Однотипные строки в цикл

Автор Тема: Однотипные строки в цикл  (Прочитано 15279 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Однотипные строки в цикл
« : 22-10-2019, 19:57:15 »
Всех приветствую.

Имеется вот такие две части кода

Код - vb.net [Выбрать]
  1. Dim lxDesign As ResultBuffer = LispExtensions.GetLispSym("lxDesign")
  2. Dim lxDesignDate As ResultBuffer = LispExtensions.GetLispSym("lxDesignDate")
  3. Dim lxChecking As ResultBuffer = LispExtensions.GetLispSym("lxChecking")
  4. Dim lxCheckingDate As ResultBuffer = LispExtensions.GetLispSym("lxCheckingDate")

Код - vb.net [Выбрать]
  1. Dim lxArray As Array
  2. Dim lxString As String
  3.  
  4. lxArray = lxDesign.AsArray
  5. lxString = lxArray(0).value
  6. TB_11.Text = lxString
  7.  
  8. lxArray = lxDesignDate.AsArray
  9. lxString = lxArray(0).value
  10. TB_21.Text = lxString
  11.  
  12. lxArray = lxChecking.AsArray
  13. lxString = lxArray(0).value
  14. TB_12.Text = lxString
  15.  
  16. lxArray = lxCheckingDate.AsArray
  17. lxString = lxArray(0).value
  18. TB_22.Text = lxString
Это части кода, который создаёт окно. Логика работы такая - при инициализации берутся переменные лиспа, есть они или нет в чертеже. Потом заполняются или редактируются поля, считываются и отправляются обратно в переменные лиспа. Мне интересно, возможно ли записать данные примеры циклом, чтобы было меньше строк. В автолиспе я делал это через (eval (read variable)). В VB.NET не могу найти информацию и не хватает опыта.

Конструкция типа:
Код - vb.net [Выбрать]
  1. Dim lxStringCollection = New String() {"lxDesign", "lxDesignDate", "lxChecking", "lxCheckingDate"}
  2. Dim lxTBCollection = New String() {"TB_11", "TB_21", "TB_12", "TB_22"}
  3.  
  4. For lxItem = 0 To lxStringCollection.GetUpperBound(0)
  5.   lxResultBuffer.Add(LispExtensions.GetLispSym(lxItem))
  6. Next
  7.  
  8. Dim lxIndex = 0
  9. For Each lxBuffer As TypedValue In lxResultBuffer
  10.   Dim lxStringBuffer As String = lxTBCollection(lxIndex) & ".text = lxBuffer.Value"
  11.   Dim lxTable = New System.Data.DataTable()
  12.   Convert.ToDouble(lxTable.Compute(lxStringBuffer, Nothing))
  13.   lxIndex += 1
  14. Next
Вылетает с критической ошибкой AutoCAD.

И второй вопрос.
Первый вариант окна я делал с помощью класса, написанного Александром Ривилисом https://forums.autodesk.com/t5/net/acedgetsym-and-acedputsym-in-net-applications/td-p/1635754 и переработанного для VB.net https://www.theswamp.org/index.php?topic=35714.0. Но изучая хелп по API .NET я наткнулся на тот факт, что в API реализованы данные методы. Нашёл пример использования этих методов на C# https://adndevblog.typepad.com/autocad/2014/08/set-or-get-lisp-symbol-in-net.html. И метод Set* работал отлично, но метод Get* не хотел работать, при отладке выдавало исключение, если в переменной находилось значение String. Изначально я неправильно переписал код с C# на VB.NET. Когда я точно повторил пример на сайте, то уже выдавало не просто исключение, а указывало на то, что объект String не может быть сконвертирован в TypedValue.

Я решил проблему двумя способами:
Код - vb.net [Выбрать]
  1. Dim lxDesign As Object = lxDocument.GetLispSymbol("lxDesignPE4")
  2. If Not String.IsNullOrEmpty(lxDesign) Then
  3.   TB_11.Text = lxDesign.ToString
  4. End If
Код - vb.net [Выбрать]
  1. Dim lxDesign = New TypedValue(CInt(LispDataType.Text), lxDocument.GetLispSymbol("lxDesignPE4"))
  2. TB_11.Text = lxDesign.Value
И если кто может объяснить чем эти способы различаются и могут повлиять на AutoCAD. Либо они равнозначны и можно делать как удобно.

PS Прошу особо не пинать за, может быть, глупые и непонятные вопросы, изучаю AutoLISP с лета этого года, а VB.NET пару недель.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #1 : 22-10-2019, 21:09:33 »
Приветствую на форуме!
изучаю AutoLISP с лета этого года, а VB.NET пару недель.
Рекомендую бросить изучать VB.NET и начать изучать C#.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #2 : 22-10-2019, 21:17:35 »
Вылетает с критической ошибкой AutoCAD.
Что говорит пошаговая отладка? И что за критическая ошибка?
Я решил проблему двумя способами:
Как по мне первый вариант предпочтительней, но особой разницы (особенно на VB.NET) я не вижу.

P.S.: Однозначно одна из ошибок здесь:
Код - vb.net [Выбрать]
  1. For lxItem = 0 To lxStringCollection.GetUpperBound(0)
  2.   lxResultBuffer.Add(LispExtensions.GetLispSym(lxItem))
  3. Next
Должно быть как-то так (на VB.NET не пишу):
Код - vb.net [Выбрать]
  1. For lxItem = 0 To lxStringCollection.GetUpperBound(0)
  2.   lxResultBuffer.Add(LispExtensions.GetLispSym(lxStringCollection(lxItem)))
  3. Next
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #3 : 22-10-2019, 21:51:20 »
Нашёл пример использования этих методов на C# https://adndevblog.typepad.com/autocad/2014/08/set-or-get-lisp-symbol-in-net.html. И метод Set* работал отлично, но метод Get* не хотел работать, при отладке выдавало исключение, если в переменной находилось значение String.
Похоже, что в статье ошибка, о чем в комментарии к ней написано. Document.GetLispSymbol возвращает Object, а не TypedValue.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #4 : 22-10-2019, 22:01:46 »
Рекомендую бросить изучать VB.NET и начать изучать C#.
Александр, а можете вкратце объяснить почему C# предпочтительнее? Я читал закреплённые темы Андрея Бушмана про книги и тему про изучение C#, но пока что не понял преимущества C# над VB.NET.

AutoCAD вылетает при операции добавления в ResultBuffer.
Код - vb.net [Выбрать]
  1. For lxItem = 0 To lxStringCollection.GetUpperBound(0)
  2.   lxResultBuffer.Add(LispExtensions.GetLispSym(lxStringCollection(lxItem)))
  3. Next

Он объявляется глобально
Код - vb.net [Выбрать]
  1. Public lxResultBuffer As ResultBuffer

Похоже, что в статье ошибка, о чем в комментарии к ней написано. Document.GetLispSymbol возвращает Object, а не TypedValue.
Вы правы, я в хелпе сразу видел, что он возвращает Object, но так как не имею своего опыта, понадеялся на опыт человека, написавшего статью.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #5 : 22-10-2019, 22:09:33 »
Александр, а можете вкратце объяснить почему C# предпочтительнее?
Вкратце - на C# значительно больше примеров, он красивее, лаконичнее, роднее для .NET
VB.NET - это искусственное образование из учебного Basic, с грехом пополам адаптированное для работы с .NET
Лично мне крайне неприятно читать код, написанный на нём.
Он объявляется глобально
Код - vb.net [Выбрать]

    Public lxResultBuffer As ResultBuffer
А где оно инициализировано? Должно быть где-то
Код - vb.net [Выбрать]
  1. lxResultBuffer = new ResultBuffer()
до вызовов lxResultBuffer.Add(...).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #6 : 22-10-2019, 22:35:11 »
А где оно инициализировано? Должно быть где-то
Я думал, что инициализация происходит во время объявления глобальной переменной. Я добавил инициализацию перед выполнением цикла, ничего не изменилось. Хочу заметить, что AutoCAD крашится независимо от того есть ли в чертеже переменная, либо она просто пустая, либо с данными String.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #7 : 22-10-2019, 22:39:17 »
Я думал, что инициализация происходит во время объявления глобальной переменной.
Нет.
Хочу заметить, что AutoCAD крашится независимо от того есть ли в чертеже переменная, либо она просто пустая, либо с данными String.
А если вместо LispExtensions.GetLispSym() используешь lxDocument.GetLispSymbol(...) ?
Какая версия и разрядность AutoCAD? Где код LispExtensions.GetLispSym?
Вообще-то после появления в AutoCAD .NET API методов Document.GetLispSymbol/Document.SetLispSymbol потребность в использовании P/Invoke для acedGetSym/acedSetSym отпала. Тем более, что использование их сопряжено с определенными сложностями (начиная с AutoCAD 2013 вместо "acad.exe" используется "accore.dll" и сигнатура функции претерпела изменения - вместо "acedGetSym" в AutoCAD 2020 x64 "?acedGetSym@@YAHPEB_WPEAPEAUresbuf@@@Z").
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #8 : 22-10-2019, 23:01:04 »
А если вместо LispExtensions.GetLispSym() используешь lxDocument.GetLispSymbol(...) ?
Это я уже завтра потестирую

Какая версия и разрядность AutoCAD?
Простой английский AutoCAD x64.

Где код LispExtensions.GetLispSym?
Код брал вот отсюда http://www.theswamp.org/index.php?topic=35714.msg460016#msg460016 , там же и упоминается о том, что произошли изменения после 2013 версии.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #9 : 22-10-2019, 23:01:51 »
Простой английский AutoCAD x64.
Версия какая???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #10 : 22-10-2019, 23:07:06 »
Простой английский AutoCAD x64.
Версия какая???
Блин, я уже сплю  :) Версия 2018

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #11 : 22-10-2019, 23:08:41 »
Блин, я уже сплю  :) Версия 2018
Теоретически замена "acad.exe" на "accore.dll" должна была помочь. Завтра проверю.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #12 : 22-10-2019, 23:20:18 »
Блин, я уже сплю  :) Версия 2018
Теоретически замена "acad.exe" на "accore.dll" должна была помочь. Завтра проверю.

Так если я делаю без цикла, а просто

Код - vb.net [Выбрать]
  1. Dim lxDesign As ResultBuffer = LispExtensions.GetLispSym("lxDesign")

то всё работает.

Я ведь правильно понимаю, что метод Add аналогичен вот такому добавлению?

Код - vb.net [Выбрать]
  1. Dim input As New ResultBuffer(
  2. New TypedValue(CInt(LispDataType.ListBegin)),
  3. New TypedValue(CInt(LispDataType.Int16), 12),
  4. New TypedValue(CInt(LispDataType.Text), "toto"),
  5. New TypedValue(CInt(LispDataType.T_atom)),
  6. New TypedValue(CInt(LispDataType.ListEnd)))
Хотя, пример со списком не совсем корректен...

И ещё хочу уточнить, что мне нужно получить не список строк для лиспа, а мне нужен массив ResultBuffer. Но я пытался сделать вот так
Код - vb.net [Выбрать]
  1. Public lxDesign As ResultBuffer()
При добавлении в массив по индексу AutoCAD уже не крашился, а вылетало исключение при следующей итерации.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #13 : 23-10-2019, 09:09:20 »
Я ведь правильно понимаю, что метод Add аналогичен вот такому добавлению?
Вообще-то ResultBuffer.Add работает с TypedValue, а не с ResultBuffer. В этом может быть ошибка.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #14 : 23-10-2019, 11:00:40 »
Имеется вот такие две части кода

Код - vb.net [Выбрать]
  1. Dim lxDesign As ResultBuffer = LispExtensions.GetLispSym("lxDesign")
  2. Dim lxDesignDate As ResultBuffer = LispExtensions.GetLispSym("lxDesignDate")
  3. Dim lxChecking As ResultBuffer = LispExtensions.GetLispSym("lxChecking")
  4. Dim lxCheckingDate As ResultBuffer = LispExtensions.GetLispSym("lxCheckingDate")

Код - vb.net [Выбрать]
  1. Dim lxArray As Array
  2. Dim lxString As String
  3.  
  4. lxArray = lxDesign.AsArray
  5. lxString = lxArray(0).value
  6. TB_11.Text = lxString
  7.  
  8. lxArray = lxDesignDate.AsArray
  9. lxString = lxArray(0).value
  10. TB_21.Text = lxString
  11.  
  12. lxArray = lxChecking.AsArray
  13. lxString = lxArray(0).value
  14. TB_12.Text = lxString
  15.  
  16. lxArray = lxCheckingDate.AsArray
  17. lxString = lxArray(0).value
  18. TB_22.Text = lxString
Это части кода, который создаёт окно. Логика работы такая - при инициализации берутся переменные лиспа, есть они или нет в чертеже. Потом заполняются или редактируются поля, считываются и отправляются обратно в переменные лиспа. Мне интересно, возможно ли записать данные примеры циклом, чтобы было меньше строк. В автолиспе я делал это через (eval (read variable)). В VB.NET не могу найти информацию и не хватает опыта.

Конструкция типа:
Код - vb.net [Выбрать]
  1. Dim lxStringCollection = New String() {"lxDesign", "lxDesignDate", "lxChecking", "lxCheckingDate"}
  2. Dim lxTBCollection = New String() {"TB_11", "TB_21", "TB_12", "TB_22"}
  3.  
  4. For lxItem = 0 To lxStringCollection.GetUpperBound(0)
  5.   lxResultBuffer.Add(LispExtensions.GetLispSym(lxItem))
  6. Next
  7.  
  8. Dim lxIndex = 0
  9. For Each lxBuffer As TypedValue In lxResultBuffer
  10.   Dim lxStringBuffer As String = lxTBCollection(lxIndex) & ".text = lxBuffer.Value"
  11.   Dim lxTable = New System.Data.DataTable()
  12.   Convert.ToDouble(lxTable.Compute(lxStringBuffer, Nothing))
  13.   lxIndex += 1
  14. Next
Вылетает с критической ошибкой AutoCAD.
Это потому, что, несмотря на использование .NET, Вы продолжаете думать на LISP. То есть, Вы совершенно игнорируете новые возможности и пытаетесь адаптировать .NET под логику LISP. Разумеется, что ничего хорошего из этого не выйдет.
Как вариант, что можно сделать.
1. Вместо двух несвязанных между собой коллекций из названий переменных и имён текстбоксов можно создать словарь Dictionary<string, TextBox> с ключом-строкой с именем переменной и соответствующим ему значением типа TextBox (в .NET можно создавать коллекции из объектов) вида: ["lxDesign" - TB_11], ["lxDesignDate" - TB_21], ["lxChecking", TB_12]
2. Пройтись foreach по этому словарю, беря по очереди ключ и значение и выполняя операцию по занесению значения переменной в текстбокс.
На VB.NET не пишу, поэтому, примера не будет.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #15 : 23-10-2019, 11:37:15 »
Вообще-то ResultBuffer.Add работает с TypedValue, а не с ResultBuffer. В этом может быть ошибка.
Александр, я пробовал добавлять с помощью Typedvalue, но всё равно AutoCAD крашится.

Это потому, что, несмотря на использование .NET, Вы продолжаете думать на LISP. То есть, Вы совершенно игнорируете новые возможности и пытаетесь адаптировать .NET под логику LISP. Разумеется, что ничего хорошего из этого не выйдет.
Дмитрий, я знаю про словари, но у меня стринговые переменные, например "lxDesign", не только читаются из чертежа, но и потом присваиваются обратно, о чём я писал в начале. Я может не понимаю Вашей мысли, Вы не могли написать пример на C#. Да и вряд ли краш AutoCAD связан с тем, что я пишу так как в начальном примере, а не с помощью словаря.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #16 : 23-10-2019, 11:44:51 »
Lemieux,
Цитата: Александр Ривилис от 22-10-2019, 22:39:17

    А если вместо LispExtensions.GetLispSym() используешь lxDocument.GetLispSymbol(...) ?

Это я уже завтра потестирую
И? Какой результат?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #17 : 23-10-2019, 11:48:22 »
Александр, я пробовал добавлять с помощью Typedvalue, но всё равно AutoCAD крашится.
Каким образом? Я не вижу кода, которым вы это делаете и поэтому не могу проверить. Создайте специальный тестовый проект, в котором будете только читать и писать lisp-переменные. Я его протестирую.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #18 : 23-10-2019, 11:58:05 »
И? Какой результат?
Я пока что на работе, когда дома буду, то выложу все результаты.

Каким образом? Я не вижу кода, которым вы это делаете и поэтому не могу проверить. Создайте специальный тестовый проект, в котором будете только читать и писать lisp-переменные. Я его протестирую.
Делал примерно так
Код - vb.net [Выбрать]
  1. lxResultBuffer.Add(New TypedValue(CInt(LispDataType.Text), (LispExtensions.GetLispSym(lxStringCollection(lxItem))))

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #19 : 23-10-2019, 12:27:02 »
Делал примерно так
Код - vb.net [Выбрать]

    lxResultBuffer.Add(New TypedValue(CInt(LispDataType.Text), (LispExtensions.GetLispSym(lxStringCollection(lxItem))))
Очевидно, что это ерунда. TypedValue - это один из элементов в ResultBuffer
Соответственно, должно было быть что-то типа:
Код - vb.net [Выбрать]
  1. For Each tv As TypedValue In LispExtensions.GetLispSym(lxStringCollection(lxItem)))
  2.  lxResultBuffer.Add(tv)
  3. Next

P.S.: Настоятельно рекомендую заняться изучением C# и забросить VB.NET
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #20 : 23-10-2019, 12:34:25 »
Я может не понимаю Вашей мысли, Вы не могли написать пример на C#.
Код - C# [Выбрать]
  1. Dictionary<string, TextBox> varAndBoxesDict
  2.     = new Dictionary<string, TextBox>
  3.     {
  4.         { "lxDesign", TB_11 },
  5.         { "lxDesignDate", TB_21 },
  6.         { "lxChecking", TB_12 },
  7.         { "lxCheckingDate", TB_22 },
  8.     };
  9.  
  10.  
  11. // Переносим значения из переменных в текстбоксы
  12. foreach (KeyValuePair<string, TextBox> pair in varAndBoxesDict)
  13. {                
  14.     string text =
  15.         // Вспомогательный метод, который вытаскивает строку, сохранённую в LISP-переменной
  16.         LispExtensions.GetTextFromLispVariable(pair.Key);
  17.     pair.Value.Text = text ?? string.Empty;
  18. }
  19.  
  20. // Переносим значения из текстбоксов в переменные
  21. foreach (KeyValuePair<string, TextBox> pair in varAndBoxesDict)
  22. {
  23.     string text = pair.Value.Text?.Trim() ?? string.Empty;
  24.     // Вспомогательный метод, который записывает строку в LISP-переменную
  25.     LispExtensions.SetLispSym(pair.Key, text);
  26. }
  27.  
Да и вряд ли краш AutoCAD связан с тем, что я пишу так как в начальном примере, а не с помощью словаря.
Возможно. Я неправильно выразился. Я имел в виду, что такие сложные действия в коде являются следствием попытки реализовать операции через одно место через логику LISPа :)

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #21 : 23-10-2019, 12:50:39 »
P.S.: Настоятельно рекомендую заняться изучением C# и забросить VB.NET
Я последую Вашему совету и следующую работу выполню на C#

Я имел в виду, что такие сложные действия в коде являются следствием попытки реализовать операции через одно место через логику LISPа
Согласен, что через логику лиспа, но мне интересны различные варианты реализации, для этого я и создал эту тему. Но, к сожалению, я обычно сначала выполняю практические занятия и провожу разные эксперименты, а уже потом читаю книги. У меня была задача написать скрипты для автоматической формирований связей между элементами схемы, автоматического формирования остальных документов из схемы Э4. Я сделал, времени читать книги не было, разбираюсь на ходу.
Спасибо за пример.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #22 : 23-10-2019, 13:01:12 »
Но, к сожалению, я обычно сначала выполняю практические занятия и провожу разные эксперименты, а уже потом читаю книги. У меня была задача написать скрипты для автоматической формирований связей между элементами схемы, автоматического формирования остальных документов из схемы Э4. Я сделал, времени читать книги не было, разбираюсь на ходу.
Да это, в общем-то, вполне нормальный подход: практика + теория. Главное - не пренебрегать чем-то одним. Читать книги обязательно надо, применять полученные знания на практике тоже очень важно. То, что задаёте вопросы - вообще отлично! Многие почему-то стесняются. Ну и готовьтесь к тому, что всё что вы сейчас напишете через год-два либо выкинете, либо будете переписывать заново ;)

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #23 : 23-10-2019, 13:07:51 »
Ну и готовьтесь к тому, что всё что вы сейчас напишете через год-два либо выкинете, либо будете переписывать заново
Так я к этому давно привык, ещё во времена, когда писал на Python и Mel интерфейсы и конвертеры шейдеров в Maya. Даже сейчас, за эти месяцы изучения и практики я нахожу более практичные реализации задач и, просматривая старый код, думаю - "Неправильно я написал, надо было делать по другому." Вообще у меня был такой план. Я пишу дополнение на лисп для создания КД шкафов РЗА, потом изучаю .NET и пишу дополнение для создания КД шкафов НКУ. Но плохое поведение DCL меня поставило в такие условия, что раньше пришлось начать изучение .NET. VB.NET я выбрал только из-за того, что у меня были видео уроки по созданию плагинов для AutoCAD на VB.NET.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #24 : 23-10-2019, 13:08:16 »
Но, к сожалению, я обычно сначала выполняю практические занятия и провожу разные эксперименты, а уже потом читаю книги.
Эти эксперименты могут отнять много времени, которое можно было потратить на что-то другое более полезное. Впрочем ваше дело...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #25 : 23-10-2019, 13:09:40 »
VB.NET я выбрал только из-за того, что у меня были видео уроки по созданию плагинов для AutoCAD на VB.NET.
Там же были уроки по созданию плагинов на C# для AutoCAD. На каком-то из C-подобных языков вы уже что-то писали?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #26 : 23-10-2019, 13:26:11 »
Но плохое поведение DCL меня поставило в такие условия, что раньше пришлось начать изучение .NET.
Так-так-так... Теперь понятны попытки скрестить лисп с нетом. То есть, нужен диалог для изменения каких-то лисповых данных? А есть уверенность, что подход выбран правильный? Я про то, что данные можно передавать по другому - не через считывание-запись лисповых переменных, а с помощью передачи аргументов в самописную лисп-функцию, которая после завершения диалога будет возвращать полученные в нём значения.
Типа такого:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.         res (run-my-dialog lxDesign lxDesignDate lxChecking lxCheckingDate)
  3.         lxDesign (nth 0 res)
  4.         lxDesignDate (nth 1 res)
  5.         lxChecking (nth 2 res)
  6.         lxCheckingDate (nth 3 res)
  7. )
Функцию run-my-dialog написать на .NET. Она будет принимать строковые значения, запускать диалог по их изменению и возвращать список новых значений после закрытия диалога.
P.S.: Настоятельно рекомендую заняться изучением C# и забросить VB.NET
+1

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #27 : 23-10-2019, 13:28:52 »
Функцию run-my-dialog написать на .NET. Она будет принимать строковые значения, запускать диалог по их изменению и возвращать список новых значений после закрытия диалога.
Именно так. Или всё полностью пишется на .NET (C#/VB.NET) или на .NET пишется функции, к которым обращаются из lisp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #28 : 23-10-2019, 13:45:48 »
На каком-то из C-подобных языков вы уже что-то писали?
Нет

Но плохое поведение DCL меня поставило в такие условия, что раньше пришлось начать изучение .NET.
Так-так-так... Теперь понятны попытки скрестить лисп с нетом. То есть, нужен диалог для изменения каких-то лисповых данных? А есть уверенность, что подход выбран правильный? Я про то, что данные можно передавать по другому - не через считывание-запись лисповых переменных, а с помощью передачи аргументов в самописную лисп-функцию, которая после завершения диалога будет возвращать полученные в нём значения.
Типа такого:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.         res (run-my-dialog lxDesign lxDesignDate lxChecking lxCheckingDate)
  3.         lxDesign (nth 0 res)
  4.         lxDesignDate (nth 1 res)
  5.         lxChecking (nth 2 res)
  6.         lxCheckingDate (nth 3 res)
  7. )
Функцию run-my-dialog написать на .NET. Она будет принимать строковые значения, запускать диалог по их изменению и возвращать список новых значений после закрытия диалога.
P.S.: Настоятельно рекомендую заняться изучением C# и забросить VB.NET
+1
Я думал о таком подходе, чтобы написать функцию лиспа на .net. Но когда вызываешь модальное окно с помощью функции лиспа, то AutoACD крашится.
То есть я делал конструкцию типа:
Код - vb.net [Выбрать]
  1. <LispFunction("Window")>
  2. //тут инициализовал окно
и AutoCAD вылетал.

Работает всё это только из команды:
Код - vb.net [Выбрать]
  1. <CommandMethod("Window")>
  2. //тут инициализовал окно

Или всё полностью пишется на .NET (C#/VB.NET) или на .NET пишется функции, к которым обращаются из lisp.
Согласен, но пришлось прибегнуть к такому способу, так как чтобы переписать весь код на .net уйдёт слишком много времени.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #29 : 23-10-2019, 13:54:59 »
Я думал о таком подходе, чтобы написать функцию лиспа на .net. Но когда вызываешь модальное окно с помощью функции лиспа, то AutoACD крашится.
То есть я делал конструкцию типа:
Код - vb.net [Выбрать]
  1. <LispFunction("Window")>
  2. //тут инициализовал окно
и AutoCAD вылетал.
Причина, видимо, была где-то внутри того, что скрывается под "//тут инициализовал окно". Из лисп-функции нормально запускаются модальные диалоги.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #30 : 23-10-2019, 13:58:44 »
Причина, видимо, была где-то внутри того, что скрывается под "//тут инициализовал окно". Из лисп-функции нормально запускаются модальные диалоги.
Может быть. Тогда попробую реализовать окно через функции лиспа, когда буду переписывать окно для создания клемного ряда.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #31 : 23-10-2019, 14:35:28 »
Я думал о таком подходе, чтобы написать функцию лиспа на .net. Но когда вызываешь модальное окно с помощью функции лиспа, то AutoACD крашится.
То есть я делал конструкцию типа:
Код - vb.net [Выбрать]
  1. <LispFunction("Window")>
  2. //тут инициализовал окно
и AutoCAD вылетал.
Причина, видимо, была где-то внутри того, что скрывается под "//тут инициализовал окно". Из лисп-функции нормально запускаются модальные диалоги.
100% проблема в самой форме (создание, запуск, события кнопок...)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #32 : 23-10-2019, 14:38:05 »
Небольшая демонстрация того, как это работает.

Лисп:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.   data "Привет, .NET!"
  3.   res (run-custom-dialog data))
  4. (if res (setq data res))
  5. (alert data)
.NET:
Код - C# [Выбрать]
  1. [LispFunction("run-custom-dialog")]
  2. public string RunDia(ResultBuffer rb)
  3. {
  4.     string data = rb?
  5.         .AsArray()
  6.         .FirstOrDefault()
  7.         .Value.ToString()
  8.         ?? "*error*";
  9.  
  10.     CustomDialog customDialog = new CustomDialog();
  11.     customDialog.Data = data;
  12.     var res = Application.ShowModalDialog(customDialog);
  13.     if (res != System.Windows.Forms.DialogResult.Cancel)
  14.     {
  15.         return customDialog.Data;
  16.     }
  17.     else
  18.     {
  19.         return null;
  20.     }
  21. }
  22.  
Весь проект для VS2019 - в приложенном архиве.

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #33 : 23-10-2019, 14:40:21 »
Дмитрий, спасибо

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #34 : 23-10-2019, 21:55:12 »
Небольшая демонстрация того, как это работает.

Лисп:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq
  2.   data "Привет, .NET!"
  3.   res (run-custom-dialog data))
  4. (if res (setq data res))
  5. (alert data)
.NET:
Код - C# [Выбрать]
  1. [LispFunction("run-custom-dialog")]
  2. public string RunDia(ResultBuffer rb)
  3. {
  4.     string data = rb?
  5.         .AsArray()
  6.         .FirstOrDefault()
  7.         .Value.ToString()
  8.         ?? "*error*";
  9.  
  10.     CustomDialog customDialog = new CustomDialog();
  11.     customDialog.Data = data;
  12.     var res = Application.ShowModalDialog(customDialog);
  13.     if (res != System.Windows.Forms.DialogResult.Cancel)
  14.     {
  15.         return customDialog.Data;
  16.     }
  17.     else
  18.     {
  19.         return null;
  20.     }
  21. }
  22.  
Весь проект для VS2019 - в приложенном архиве.

Дмитрий, изучил Ваш пример. Вы делаете на WinForm,а я делаю окна на WPF. Сейчас как не пытался, так и не вызывает окно. Исключения при отладке не возникает, AutoCAD не крашится, просто в логе AutoCAD выводится вот такое
Код - Auto/Visual Lisp [Выбрать]
  1. System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
  2.    at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
  3.    at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
  4.    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  5.    at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
  6.    at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
  7.    at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.InvokeLisp(); error: ADS request error

Сам код имеет вот такой вид

Код - vb.net [Выбрать]
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.ApplicationServices
  3. Imports Autodesk.AutoCAD.DatabaseServices
  4.  
  5. Public Class Initialization
  6.     <LispFunction("lmxWindowTest")>
  7.     Public Sub lmxDisplayFullName()
  8.         Dim WinTest As tWindow = New tWindow()
  9.         Application.ShowModalWindow(WinTest)
  10.     End Sub
  11. End Class

Отмечено как Решение Lemieux 23-10-2019, 22:49:43

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #35 : 23-10-2019, 22:20:49 »
Метод лисп-функции должен иметь входной параметр типа ResultBuffer, даже если лисп-функция не будет иметь аргументов. А у Вас пустые скобки, то есть, входных параметров нет.
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-3B2760FE-A0DC-4229-AEBE-5CC83290BA95-htm.html

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #36 : 23-10-2019, 22:54:34 »
Метод лисп-функции должен иметь входной параметр типа ResultBuffer, даже если лисп-функция не будет иметь аргументов. А у Вас пустые скобки, то есть, входных параметров нет.
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-3B2760FE-A0DC-4229-AEBE-5CC83290BA95-htm.html
ёмоё. Я изначально делал по примеру из хелпа по API и не работало, сюда я скопировал последний вариант пробы. Моя невнимательность.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #37 : 24-10-2019, 09:03:16 »
Ну зато теперь на всю жизнь запомните  8)

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #38 : 30-10-2019, 19:38:24 »
А кто-то может подсказать как тип Object преобразовать в TypedValue?

Я делаю вот так
Код - C# [Выбрать]
  1. object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2. TypedValue[] lxType = (TypedValue[])lxCollectionTB;

В лисп переменной у меня хранится список из строк. И при выполнении кода переменная "lxCollectionTB" хранит в себе "TypeValue[]".

Но что-то мне подсказывает, что можно и по другому.

Сразу напрашивается вопрос - зачем мне это?
По советам выше я пробовал сделать через "LispFunction", но пришёл к выводу, что мне удобнее хранить в переменной и вызывать окно через "CommandMethod".

PS Хочу поблагодарить за советы выше. Я попробовал все варианты и сократил код, с помощью словарей примерно в 2 раза.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #39 : 30-10-2019, 19:44:26 »
Lemieux,
Как я понимаю lxDocument.GetLispSymbol("lmxNameTerminals") возвращает ResultBuffer
Соответственно:
Код - C# [Выбрать]
  1.     object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2.     TypedValue[] lxType = lxCollectionTB.AsArray();
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #40 : 30-10-2019, 19:47:14 »
Lemieux,
Как я понимаю lxDocument.GetLispSymbol("lmxNameTerminals") возвращает ResultBuffer
Соответственно:
Код - C# [Выбрать]
  1.     object lxCollectionTB = lxDocument.GetLispSymbol("lmxNameTerminals");
  2.     TypedValue[] lxType = lxCollectionTB.AsArray();
Александр, в том-то и дело, что по хелпу он возвращает Object. С ResultBuffer было бы просто.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #41 : 30-10-2019, 19:48:32 »
Lemieux,
Сечас перепроверю.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #42 : 30-10-2019, 20:21:40 »
Да именно так и следует делать:
Код - C# [Выбрать]
  1. TypedValue[] lxType = (TypedValue[])lxCollectionTB;
Только желательно сначала проверить не равен ли случайно lxCollectionTB null (если такой переменной нет или она nil)


Впрочем возможен вариант, что в этой переменной не список и тогда преобразовывать в TypedValue[] нельзя.
Правильнее вот так:

Код - C# [Выбрать]
  1. [CommandMethod("GetLispVar")]
  2. public void GetLispVar()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.  
  7.   Editor ed = doc.Editor;
  8.   PromptResult rs =  ed.GetString("\nУкажите имя переменной: ");
  9.   if (rs.Status == PromptStatus.OK)
  10.   {
  11.     var o = doc.GetLispSymbol(rs.StringResult);
  12.     if (o != null && o is TypedValue[])
  13.     {
  14.       TypedValue[] tvs = o as TypedValue[];
  15.       foreach (TypedValue tv in tvs)
  16.       {
  17.         ed.WriteMessage($"\n{tv.TypeCode} - {tv.Value}");
  18.       }
  19.     } else
  20.     {
  21.       ed.WriteMessage($"\n{o}");
  22.     }
  23.   }
  24. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #43 : 30-10-2019, 20:37:55 »
Да именно так и следует делать:
Код - C# [Выбрать]
  1. TypedValue[] lxType = (TypedValue[])lxCollectionTB;
Только желательно сначала проверить не равен ли случайно lxCollectionTB null (если такой переменной нет или она nil)


Впрочем возможен вариант, что в этой переменной не список и тогда преобразовывать в TypedValue[] нельзя.
Правильнее вот так:

Код - C# [Выбрать]
  1. [CommandMethod("GetLispVar")]
  2. public void GetLispVar()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.  
  7.   Editor ed = doc.Editor;
  8.   PromptResult rs =  ed.GetString("\nУкажите имя переменной: ");
  9.   if (rs.Status == PromptStatus.OK)
  10.   {
  11.     var o = doc.GetLispSymbol(rs.StringResult);
  12.     if (o != null && o is TypedValue[])
  13.     {
  14.       TypedValue[] tvs = o as TypedValue[];
  15.       foreach (TypedValue tv in tvs)
  16.       {
  17.         ed.WriteMessage($"\n{tv.TypeCode} - {tv.Value}");
  18.       }
  19.     } else
  20.     {
  21.       ed.WriteMessage($"\n{o}");
  22.     }
  23.   }
  24. }

Меню смутило то, что я так, можно сказать в наглую, преобразовываю типы. А проверку я делаю следующим этапом, перед циклом для организации string массива. И там всегда будет список, так как никто к этой переменной не имеет доступа, а формируется она функцией написанной мной.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #44 : 30-10-2019, 20:43:39 »
Lemieux,
Кстати, ты обратил внимание что в этом списке есть не только строки, но и Autodesk.AutoCAD.Runtime.LispDataType.ListBegin и Autodesk.AutoCAD.Runtime.LispDataType.ListEnd (это как скобки в lisp)? У них TypeCode 5016 и 5017
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн LemieuxАвтор темы

  • ADN OPEN
  • ****
  • Сообщений: 384
  • Карма: 21
Re: Однотипные строки в цикл
« Ответ #45 : 30-10-2019, 20:51:52 »
Lemieux,
Кстати, ты обратил внимание что в этом списке есть не только строки, но и Autodesk.AutoCAD.Runtime.LispDataType.ListBegin и Autodesk.AutoCAD.Runtime.LispDataType.ListEnd (это как скобки в lisp)? У них TypeCode 5016 и 5017
Да, я знаю об этом, поэтому у меня перебор массива начинается не с "0" элемента, а с "1" и заканчивается на "*.length-1". А есть какое решение как более изящно избавиться от обозначения границ списка?
PS Я с .ListStart и .ListEnd сталкивался, когда изучал ResultBuffer. Да и при отладке видно, что при передаче списка, размером 3, пишет "TypedValue[5]". Кстати, благодаря тому, что в Visual Studio, при отладке, удобно сделано, что показывает значение переменной и можно посмотреть, что там внутри, я решил вот так преобразовать тип.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #46 : 30-10-2019, 20:55:06 »
А есть какое решение как более изящно избавиться от обозначения границ списка?
Вполне изящное решение если ты уверен, что у тебя в переменной обычный линейный список строк.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Однотипные строки в цикл
« Ответ #47 : 30-10-2019, 21:03:02 »
Впрочем возможен вариант, что в этой переменной не список и тогда преобразовывать в TypedValue[] нельзя.
Правильнее вот так:

Код - C# [Выбрать]
  1. [CommandMethod("GetLispVar")]
  2. public void GetLispVar()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.  
  7.   Editor ed = doc.Editor;
  8.   PromptResult rs =  ed.GetString("\nУкажите имя переменной: ");
  9.   if (rs.Status == PromptStatus.OK)
  10.   {
  11.     var o = doc.GetLispSymbol(rs.StringResult);
  12.     if (o != null && o is TypedValue[])
  13.     {
  14.       TypedValue[] tvs = o as TypedValue[];
  15.       foreach (TypedValue tv in tvs)
  16.       {
  17.         ed.WriteMessage($"\n{tv.TypeCode} - {tv.Value}");
  18.       }
  19.     } else
  20.     {
  21.       ed.WriteMessage($"\n{o}");
  22.     }
  23.   }
  24. }
В C# не-помню-какой-версии добавили удобную проверку типа с одновременным преобразованием.
Поэтому, вместо строк 12-14 можно написать:
Код - C# [Выбрать]
  1. if (o is TypedValue[] tvs)
  2. {

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Однотипные строки в цикл
« Ответ #48 : 30-10-2019, 21:08:21 »
В C# не-помню-какой-версии
Добавили в C# 7.0. Но я консервативен и использую старый синтаксис :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение