Тему закрепил, чтобы её легче было найти. Рекомендую побольше кода выкладывать здесь на форуме, так как с youtube'овского ролика переписывать его не слишком удобно.
Спасибо! Это собственно весь код, который был показан в роликеЭто было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Будем старатьсяСпасибо! Это собственно весь код, который был показан в роликеЭто было моё пожелание на будущее. Надеюсь, что это будет не единственный урок. :)
Массивы достаточно просто создаются, наример один из самых распространенных случаев - преобразование в массив чисел с плавающей точкой (variant array of doubles) для координат:
Код - Python [Выбрать]
import win32com.client
from pythoncom import VT_R8, VT_ARRAY
pythoncoord = [x, y, z]
acadcoord = win32com.client.VARIANT(VT_ARRAY | VT_R8, pythoncoord)
IronPython, к сожалению, продолжают прикручивать к различным серьёзным программных комплексам, потому что другой нормально работающей реализации Python для .NET на данный момент просто не существует. Есть несколько проектов, типа pythonnet, но без танцев с бубном они с тем же автокадом не работают. IronPython вряд ли в обозримом будущем перейдёт на поддержку Python 3x, постепенно поддержка ветки 2х будет свёрнута в первую очередь со стороны разработчиков различных модулей (а множество доступных модулей практически на все случаи жизни - одно из самых весомых преимуществ Python для инженера, когда разработка программ - возможность повысить производительность и облегчить себе жизнь). Автодеск, например, с IronPython в Revit, наступает ровно на те же грабли, что и с LISP в автокаде. Кому сейчас реально нужен лисп вне автокада? Никому. Но заменить его чем-то невозможно - у пользователей просто горы кода на лиспе накопилось за все годы.
Для инженера же Python - один из лучших языков за счёт относительной простоты и наличия огромного количества модулей.
object.SetTextHeight(rowTypes, TextHeight)
Object Table, TableStyle
The object this method applies to.rowTypes Long; the row types to change. TextHeight Double; the text height to use for the specified row types.
Electric,
Приветствую на форуме!
К примеру. у меня все работает, когда передаю "1" или "2" по отдельности , назначая моему табличному стилю newTabStyle высоту 2,5:Зачем их передавать сразу?
Код - Python [Выбрать]
newTabStyle.SetTextHeight("2", 2.5)
но как передать эти два значения сразу? При попытке передать их в виде списка или кортежа выдает ошибку, когда я передаю "1"+"2" - функция игнорирует один из них.
Вот так тебя не устроит:
example, _ = aDoc.Utility.GetEntity('Укажите объект: ')
File "<COMObject <unknown>>", line 3, in GetEntity
File "C:\ProgramData\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
TypeError: The Python instance can not be converted to a COM object
sset = AcDoc.PickfirstSelectionSet
Кроме того, допустим, пользователю нужно выделить не один, а сразу несколько объектов в Автокаде, через какую команду это реализуется?SelectionSet.SelectOnScreen: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-ActiveX/files/GUID-C4B442A3-D6A9-48FA-8C86-03D49A3B2ED7-htm.html
Но этот выдает уже ошибку:Я не специалист по Python, но может быть так:
Код - Python [Выбрать]
example, _ = aDoc.Utility.GetEntity('Укажите прямоугольник: ')
Но этот выдает уже ошибку:Я не специалист по Python, но может быть так:
Код - Python [Выбрать]
example, _ = aDoc.Utility.GetEntity('Укажите прямоугольник: ')Код - Python [Выбрать]
returnObj = aDoc.Utility.GetEntity("Укажите прямоугольник: ")
AttributeError: 'tuple' object has no attribute 'Layer'
Опции для команд через COM, конечно, доступны. При использовании методов Utility.GetInteger, Utility.GetReal, GetString и т.п. достаточно сформировать строку запроса особым образом. Для автокада наличие в запросе текста вида [Опция1/<оПция2>/опЦия3] означает, что в запросе имеются три опции, причем вторая - опция по-умолчанию.Кто сказал? В лиспе, по крайней мере, это не так. И, насколько я помню, в .NET тоже не так.
достаточно сформировать строку запроса особым образомотносится только к тому,что запрос в командной строке будет выглядеть как запрос с опциями, далее я как раз и показываю, что необходимо предусмотреть в коде, чтобы опции запроса не только выглядели, как опции, но и работали соответствующим образом.
File "C:\Program Files\Python\lib\site-packages\win32com\client\dynamic.py", line 252, in __getitem__
raise TypeError("This object does not support enumeration")
Но если я хочу выделить все объекты и по привычке нажимаю сочетание CNTRL+A - команда выделения в автокаде тут же прерывается.Всё правильно. Так и должно быть. У AutoCAD свои правила и их следует соблюдать. Вместо CTRL+A нужно жать _A и пробел/ввод (в английской версии можно просто A (латиница), а в русской В (кириллица)). CTRL+A при стандартных настройках запускает прерывание команды и команду _ai_selall.
Вместо CTRL+A нужно жать _A и пробел/ввод (в английской версии можно просто A (латиница), а в русской В (кириллица)).
Небольшое уточнение:Мой промах. A, _A не срабатывают, так как воспринимаются как _ADD, а не как _ALL. В русской локализации же эквивалент _ALL - это Все, а эквивалент _ADD - Добавить, т.е. достаточно одной буквы для того, чтобы понять какая опция выбора введена.
Autocad 2018 Eng - A или a не работают, нужно ввести al или all в любом регистре.
Autocad 2018 Rus - соответственно не работает _A и _a, необходимы _al или _all в любом регистре, при этом кириллические в, все в любом регистре работают.
File "<COMObject Add>", line 3, in SelectOnScreen
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD', 'Недопустимый аргумент FilterType в SelectOnScreen', 'C:\\Program Files\\AutoCAD\\HELP\\OLE_ERR.CHM', -2145320939, -2147024809), None)
Настоятельно советую изучать справку по VBA - там многое описано:
Тебе нужен последний пример.
В данный момент я реализовал это через указание нижней левой и верхней правой точек с помощью Utility.GetPoint(), для получения крайних координат рамки. Но как-то это не эстетичный метод, возможно ли реализовать это через выделение области прямоугольной рамкой?Можно. Посмотри в сторону Utility.GetCorner(). Первую точку через Utility.GetPoint(), вторую через Utility.GetCorner().
Пробовал уже Ответ #43
Код - Python [Выбрать]
>>> tab.GetCellValue(1, 1)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147467263), None)
Попробовал ещё раз, на всякий случай.))
Речь точно идет об автокаде? Если да, то предложенный вариант obj.GetCellValue(1, 1) у меня работает.
Я действительно пытаюсь это реализовать не в AutoCAD-е, а в ZWCAD-еУ нас на форуме категорически не обсуждаются "приложения - подобия"!!!
Хорошо, можете удалить тогда всё. :-XЯ оставлю всю эту дискуссию. Она очень поучительна.
Пытаюсь успользовать метод AutoCAD.Application.ActiveDocument.Utility.GetEntity().Обязательно с ним? А почему не подходит Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.GetEntity() ?
Ни как не могу пользоваться им в IronPython.
Я подключаюсь к Autocad следующим образом.Подключаешься изнутри AutoCAD или снаружи? Если снаружи, то предложенный мной способ недоступен.
А изнутри, это надо скомилировать код и netload делать?Нет. Компилировать ничего не нужно. Точнее создаётся C#-сборка, которая позволяет загрузить и выполнить python'овский-код.
Есть референс по классам, доступным изнутри?Это всё в документации ObjectARX SDK, а в онлайне здесь: https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-What_s_New
На этот раз речь конечно же идёт о ZWAutoCAD.))Если это шутка, то неудачная.
Такой вопрос: как можно вывести, что-нибудь в командную строку, типа: код отработан без ошибок, результат такой-то?
However, note that the MSIL in the assembly is not CLS-compliant and cannot be directly accessed from other .NET languages.Т.е. эту сборку в AutoCAD загрузить будет нельзя. Так что в компиляции теряется весь смысл.
Идея в том, чтобы загрузить в автокад сборку на c#, которая загрузит другую сборку на ironpython.Мне непонятно зачем это всё нужно. Есть традиционные способы работы с AutoCAD API. Если уж смогли сделать сборку на C#, то зачем Python нужен?
Вопрос в том, можно ли загружать из c# не скрипты на питоне с помощью скриптинджин а скомпилированные dll на питоне. Просто интересно.Я вижу как можно создать exe-файл на IronPython: https://habr.com/post/149621/
Однако в Revit при создание макроса на ironpython запускается интегрированный SharpDevelop IDE, которая компилирует макрос в dll(он это умеет делать.)Попробуй на SharpDevelop IDE скомпилировать макрос для AutoCAD и посмотри что получится.
В случае с автокадом нельзя напрямую это делать т.к. питон не поддерживает атрибуты.Атрибуты методов и классов? Т.е. стандартными методами нельзя определить команду. Тогда можно нестандартными:
Выкладываю сборкуПонятно. Ничего не получится. Результат компиляции такой, что не совпадает ни имя класса, ни имя метода, который AutoCAD должен при загрузке этой сборки найти...
Вопрос: как можно запустить комманду Акада, например "_regenall", из пайтона?Если черед COM, то AcadDocument.SendCommand("_regenall ") (обрати внимание на пробел после имени команды).
Если черед COM, то AcadDocument.SendCommand("_regenall ") (обрати внимание на пробел после имени команды).
А если через .NET, то Document.SendStringToExecute("_regenall ")
Что за метод используется при этом?В COM для этой цели есть только один метод: HitTest.
Возможно ли вызвать этот hittest текстовой командой в меню Автокада? по типу _purge или _regenall.Нет.
Нет.
if obj.HitTest(wpt, wviewVec, resultRowIndex, resultColumnIndex):
File "<COMObject <unknown>>", line 3, in HitTest
File "C:\ProgramData\Anaconda64\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_
result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)
А как в Python передаются out-параметры?
resultRowIndex = 1
resultColumnIndex = 1
py_coord = [0,0,0]
wpt = win32com.client.VARIANT(VT_ARRAY | VT_R8, py_coord)
py_vector = [0, 0, 0]
wviewVec = win32com.client.VARIANT(VT_ARRAY | VT_R8, py_vector)
print(obj.HitTest(wpt, wviewVec))
(False, -1, -1)
На dwg.ru были примеры использования HitTest (правда, на лиспе).
Т.е. у меня получилось изменить стиль ячейки (2,2) через MyTab.SetCellStyle(2, 2, '_Header'). Но тогда стиль ячейки меняется на "Заголовок", а стиль строки по-прежнему "Данные".Читаем внимательно документацию для метода Table.SetCellStyle:
NotesПеревод нужен или так понятно?
To specify cell pass a valid row and column indices; to specify row pass a valid row index and pass -1 as column index; to specify column pass a valid column index and pass -1 as row index.
Перевод нужен или так понятно?
Но в онлайн справке, что я находил через гугл в разделе SetCellStyle Method (ActiveX) этого пункта notes нет (или я его в упор не замечаю?), в моей встроенной chm справке его нет тем более.Посмотри здесь: http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_TableContent_SetCellStyle_int_int_string
Можно ли как-то таким щелчком сразу получить доступ к текстовому аттрибуту блока (например, цифре "1") без расчленения самого блока?Можно. Используй GetSubEntity.
Задавал тут вопрос, но как то все само собой решилось. Не хотел питон рисовать в пустом документе, зато без проблем нарисовал в одном из рабочих чертежей. Как удалить сообщение не нашел.1. Приветствую на форуме!
По 3 му пункту, согласенА по первому и второму? ;)
По 3 му пункту, согласен, было бы неплохо исследовать этот вопрос. По началу грешил на то что питон 32бит, а автокад64. Потом думал что может версия автокада не та. Потом попробовал с библиотекой pyautocad провести манипуляции, эффект тот же. Причем Эта библиотека возвращала название документа(Чертеж 1). Меня еще больше удивило когда она возвратила название документа при закрытом автокаде, тот же чертеж 1.
Ну тут всё просто. Приложение не закрылось корректно. При этом они уже не в состоянии отвечать на COM-запросы.По 3 му пункту, согласен, было бы неплохо исследовать этот вопрос. По началу грешил на то что питон 32бит, а автокад64. Потом думал что может версия автокада не та. Потом попробовал с библиотекой pyautocad провести манипуляции, эффект тот же. Причем Эта библиотека возвращала название документа(Чертеж 1). Меня еще больше удивило когда она возвратила название документа при закрытом автокаде, тот же чертеж 1.
У меня наблюдался наверно похожий глюк с win32com библиотекой, когда она выдавала, что автокад или ворд запущены (хотя соответствующие программы были закрыты), при этом в списке процессов в системе действительно висели невидимые процессы с именами AutoCAD Application или Word. Так и не понял, чем это вызвано.
DMuzer,
Посмотри этот код: https://gist.github.com/thengineer/7157510
А не в курсе, с чем связана ошибка? Это Автокад не стыкуется с питоном, или я что то неправльно делаю?Я же не вижу всего кода, не знаю что такое blk, не знаю есть ли у этой вставки блока атрибуты... Так что затрудняюсь сказать. Но если код, по ссылке которую я дал, работает нормально, то скорее всего это проблема твоего кода.
Может это связано что это динамический блок.Нет. Это уж точно тут не причем. Если этот же код с этим же блоком у тебя сработает в VBA, то тогда это проблема Python'а.
# XXX Manual resource management, because of the VARIANT bug:
А может быть это связано с недоработками в библиотеке comtypes?Вполне возможно.
Вариант Utility.GetPoint(None, "Сообщение") вызывает ошибку.А так: Utility.GetPoint("Сообщение") ?
Спасибо. С pythoncom.Empty все отлично работает.Отлично. Не имея возможности проверить я интуитивно догадался, что именно может помочь. Так как использование Python для AutoCAD мягко говоря не очень распространено и не поддерживается Autodesk, то поиск решений таких казалось бы простых задач очень усложнён.
Я правильно понимаю, что смогу написать модуль на С++ с использованием ObjectARX и потом им пользоваться в программе на Python?Я не понимаю к чему такие сложности. Для того, чтобы писать для AutoCAD непрофессиональному программисту оптимально использовать AutoCAD .NET API (C# или VB.NET) . Он позволяет делать большинство из того, что можно сделать при помощи ObjectARX и обладает огромным количеством примеров (большинство из них на C#).
Есть способы исправить это или это особенности работы через COM?COM между процессами приводит к таким задержкам. Особенно если эти процессы разной разрядности (32/64).
Есть способы исправить это или это особенности работы через COM?Для ускорения нужно максимально пользоваться средствами самого када, например select с фильтрами вместо select + перебор, и т.п. Но работа через COM будет всегда несколько медленной, хотя для большинства инженерных задач и достаточной.
Хочется сразу писать на том, что будет работать хорош и быстро, но вот процесс отладки кода меня, скажем прямо, пугает.Не пугайся. Все так делают. Нужно писать максимально чистый код сразу - это сократит количество запусков AutoCAD для отладки.
Есть ли подходящие примеры?Примеров нет. Во всяком случае мне они не известны. Так что пробуй делать по аналогии с Word/Excel:
Есть ли способ получить доступ к настройкам привязки и активировать их программно?Это системная переменная OSMODE: https://knowledge.autodesk.com/support/autocad/learn-explore/caas/CloudHelp/cloudhelp/2018/ENU/AutoCAD-Core/files/GUID-DD9B3216-A533-4D47-95D8-7585F738FD75-htm.html
com_error Traceback (most recent call last)
<ipython-input-365-c2e46e7e77cf> in <module>
9 arr = VARIANT(VT_ARRAY | VT_VARIANT, [ent])
10
---> 11 st.MoveToTop(arr)
d:\Prorams\Anaconda\lib\site-packages\win32com\client\dynamic.py in MoveToTop(self, Objects)
com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Неверный массив объектов', 'D:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145320837, -2145320837), None)
Traceback (most recent call last):
File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 27, in <module>
myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
, Point1, Point2, FilterType, FilterData)
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.
Здравствуйте! Подскажите пожалуйста по методу Select!
Хочу выбрать все вхождения блока, но не получается задать правильно аргументы FilterType и FilterData!Код - Python [Выбрать]
import array from win32com.client import Dispatch, CastTo, VARIANT from pythoncom import VT_DISPATCH, VT_ARRAY, VT_UI2,VT_VARIANT,VT_BSTR acad=Dispatch("Autocad.Application") doc=acad.ActiveDocument ms=doc.ModelSpace try: for i in doc.SelectionSets: i.Delete() except: pass myss=doc.SelectionSets.Add("myss") dxfcode,data=0,"Insert" FilterType=VARIANT(VT_ARRAY|VT_UI2,dxfcode) FilterData=VARIANT(VT_ARRAY|VT_VARIANT,data) SELECT_ALL=5 myss.Select(SELECT_ALL,None,None,FilterType,FilterData)Код: [Выделить]Traceback (most recent call last):
File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 27, in <module>
myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
, Point1, Point2, FilterType, FilterData)
TypeError: Objects for SAFEARRAYS must be sequences (of sequences), or a buffer object.
Научите, что я делаю не так!
Traceback (most recent call last):
File "D:\Мои документы\Работа\python exp\AutoCAD\BlocksInBlockCount\block_count2.py", line 32, in <module>
myss.Select(SELECT_ALL,pythoncom.Empty,pythoncom.Empty,FilterType,FilterData)
File "C:\Program Files\Python34\lib\site-packages\win32com\gen_py\852B2D4E-B1F4-4BD6-8672-9993177C1A40x0x1x0\IAcadSelectionSet.py", line 73, in Select
, Point1, Point2, FilterType, FilterData)
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD', 'Недопустимый аргумент FilterType в Select', 'C:\\Program Files\\Autodesk\\AutoCAD 2014\\HELP\\OLE_ERR.CHM', -2145320939, -2147024809), None)
Не нужно pythoncom.Empty, нужно None оставить,Здесь None не прокатило: https://adn-cis.org/forum/index.php?topic=7864.msg38367#msg38367Код - Python [Выбрать]
myss.Select(SELECT_ALL,None,None,FilterType,FilterData)
возможно, дело как раз в том, что нужно заменить VT_UI2 на VT_I2.Наиболее вероятно, т.к. сообщает об ошибке именно в параметре FilterType
То есть выделить один или несколько объектов в открытом документе автокада из питона.Имеется в виду выбрать и подсветить, как выбранное? Средствами только COM/ActiveX это сделать нельзя. И соответственно питоном тоже. В VBA это делалось через запуск lisp-функции (sssetfirst).
А из питона же то же можно некую лисп функцию запустить?Запустить можно. Document.SendCommand. Сложность будет только с передачей параметров.
Подскажите пожалуйста! Как выбрать вхождение блока по имени и считать значение его атрибута (например блок "РАМКА", атрибут PAGE). Пробывал через Blocks.Item, но это не то :o
Как-то можно получить к нему доступ напрямую по имени без перебора всех свойств блока?Никак. Такой возможности в API нет. Впрочем это и логично - теоретически может быть несколько свойств с одним именем.
Я надеюсь что я не сильно злоупотребляю вниманием сообщества, у меня еще один вопрос.
Есть ли возможность изменить видимость атрибута в блоке? И есть ли у кого то для этого уже готовый рецепт?
Судя по доке, параметр "Invisible" - изменяемый, нельзя ли его как то изменить тем же способом что и просматриваю?
Был настроен на питон, но сталкиваюсь со сложностью с реализацией каждой небольшой идеи. Может выбрать какой то более простой и документированный способ автоматизации автокада? Для Вижуал-бейсика хоть примеры есть, но не уверен что это оптимальный подход. В общем прошу проконсультировать.Рекомендую заняться изучением C#. И писать плагины, которые грузятся внутрь AutoCAD, т.к. AutoCAD .NET API значительно мощнее, чем AutoCAD COM/ActiveX
Рекомендую заняться изучением C#. И писать плагины, которые грузятся внутрь AutoCAD, т.к. AutoCAD .NET API значительно мощнее, чем AutoCAD COM/ActiveX
Интересно, будет ли на практике какой-то прирост в скорости по сравнению с работой с COM в AutoCAD?Да. Причем если сравнивать COM/ActiveX из внешнего приложения и .NET из плагина, загружаемого в сам AutoCAD, то прирост скорости может быть и на порядок.
И как я понимаю, программа, написанная на C# будет сильно зависеть от версии Автокада, в отличие от COM, разницу в работе которой в автокаде я не замечал с 2010 по 2020 версии.По хорошему нужно под каждую версию AutoCAD делать свою dll, но если не использовать некоторые особенности (точнее не нарваться на них случайно), то с 2013 и по 2020 должна работать одна dll. Ну и могут быть особенности с версией .NET Framework, так как каждая из версий AutoCAD требует свою (а точнее "не меньшую чем" версию .NET Framework: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2020/ENU/AutoCAD-Customization/files/GUID-A6C680F2-DE2E-418A-A182-E4884073338A-htm.html).
0, 'AutoCAD', 'Нет активного видового экрана в пространстве модели. Переключение в пространство листа'
Насколько я помню, средствами ActiveX создавать ВЭ нельзя.Вообще-то AddPViewport это делает.
сть идея написать на Пайтоне аналог скрипта AL для создания листов с видовыми экранами из рамок/блоков в пространстве модели. Предложенный там скрипт не вполне корректно работает с используемым мной динамическим блоком для рамки, а переделывать LISP пока желания не возникает Так вот, своим Python скриптом, получаю координату базовой точки рамки-блока (правый нижний угол) x, y в пространстве модели, ширину width, высоту height, поворот orientation. Далее удаляю существующие листы кроме пространства модели и пустого листа по умолчанию "Лист1". Затем создаю лист c именем pagename и пытаюсь создать видовой экран в нем (за основу взял этот код):
aDoc.ActivePViewport = newVport
Абсолютно не знаю Python, но почему бы не попробовать использовать вместоКод - Python [Выбрать] doc.SendCommand("_PSLTSCALE 0 ") doc.SendCommand("ВСЕРЕГЕН ")нечто типаКод - Python [Выбрать]doc.SetVariable("PSLTSCALE", 0)doc.Regen 1P.S. acActiveViewport = 0acAllViewports = 1
Я приведу свою функцию для формирования листа, там присутствуют ссылки на другие функции но в целом понять как работает можно.
Код - Python [Выбрать]
doc.Application.ZoomWindow(vtr(bb[0]), vtr(bb[1]))
Ошибка здесь float() argument must be a string or a number, not 'VARIANT'
-2147418111, 'Вызов был отклонен'
Это такой глюк только у меня или это в принципе нормально для взаимодействия с AutoCAD через COM?Нормально через COM из внешнего приложения.
Если я смотрю существующий аналогичный код на LISP, никаких временных пауз там не вводится.Lisp работает внутри AutoCAD.
Я так понимаю, vtr в этом фрагменте - это аналог convert_coordinates из начала темы?
Возможно ли через COM очистить командную строку и остановить выполняемую в данный момент операцию в Автокаде?Попробуй через SendCommand("\003\003"). Это единственный, но негарантированный способ.
Возможно ли через COM очистить командную строку и остановить выполняемую в данный момент операцию в Автокаде?Попробуй через SendCommand("\003\003"). Это единственный, но негарантированный способ.
Действительно, этот способ очень негарантированн, у меня он либо не работает, либо выдает ошибку.Это аналог двойного нажатия ESC в AutoCAD - так что сообщение об ошибке должно быть и должна прерываться активная команда.
Если бы я писал через C# - у меня было бы больше возможностей для этого?Если через COM/ActiveX - возможностей столько же. Если использовать AutoCAD .NET API, то необходимости прерывать команду быть не должно.
Нормально через COM из внешнего приложения.
Lisp работает внутри AutoCAD.
А если подключаться к AutoCAD не через COM, а через .NET, но не на C#, а например на Python с помощью библиотеки pythonnet - это даст какие-то преимущества?Я не пишу на Python, не знаю возможностей PythonNet. Поэтому затрудняюсь ответить на этот вопрос. В любом случае это неподдерживаемый со стороны Autodesk интерфейс.
Но как только увидел на этом форуме урок по написанию простейшей программы на C# к AutoCAD - понимаю, что ничего не понимаюДа ладно. Ничего сложного в нём нет - нужно просто разобраться в этом первом примере, а дальше будет проще...
А если подключаться к AutoCAD не через COM, а через .NET, но не на C#, а например на Python с помощью библиотеки pythonnetНе получится подключится. В Autocad что-то делать извне можно только через COM. Написать с помощью pythonnet .NET код для AutoCAD можно, только никак не скомпилировать его в dll, чтобы запустить из AutoCAD.
Возможно поможет эта статья: https://adn-cis.org/pechat-granicz-okna-pri-pomoshhi-vba.htmlМожет быть что то в этом есть, возможно где то несостыковка именно с координатами. В примере показана печать из пространства модели как я понимаю, и преобразование
После того как закрываеш чертеж и снова его открываешь, приходится все листы сносить и заново делать.Зачем?
Кроме того, после создания листов - там все в порядке, я же их могу всега видеть и распечатать, ведь печатаю я после того, как создаю все листы.Тогда я ничего не понял. После того как ты создаёшь все эти листы у тебя получается нормальный чертеж, каждый из листов которого нормально печатается? И после сохранения и повторного открытия чертежа информация с листов пропадает??? Но это может только означить, что твой код портит чертеж. Я запустил _AUDIT и что я вижу:
Command: _AUDIT
Fix any errors detected? [Yes/No] <N>: _y
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 800 objects auditedAcDbBlockReference(437)
XData String Length 312 > 255 Truncate to 255
Pass 1 15300 objects auditedAcDbSortentsTable(4B4E)
Error for Entry (4B51,4B53) eDuplicateKey fixed
Pass 1 15400 objects auditedAcDbSortentsTable(4B9A)
Error for Entry (4BA9,4BAB) eDuplicateKey fixed
Pass 1 16600 objects audited
Invalid viewport-configuration name "*Multiple" found.
Changed to "AUDIT_I_191213153339-0".
AcDbViewportTableRecord: "AUDIT_I_191213153339-0"
Tilemode Viewport Corners Not filling up whole screen Set to 0,0..1,1
Invalid viewport-configuration name "*Multiple" found.
Changed to "AUDIT_I_191213153339-1".
AcDbViewportTableRecord: "AUDIT_I_191213153339-1"
Tilemode Viewport Corners Not filling up whole screen Set to 0,0..1,1
Pass 1 26600 objects audited
Auditing Entities Pass 2
Pass 2 16700 objects auditedAcDb2dVertex(250DF) layer != owner's set to owner's
AcDb2dVertex(250E0) layer != owner's set to owner's
AcDb2dVertex(250E1) layer != owner's set to owner's
AcDb2dVertex(250E2) layer != owner's set to owner's
AcDb2dVertex(250E3) layer != owner's set to owner's
Pass 2 26600 objects audited
Auditing Blocks
349 Blocks audited
Auditing AcDsRecords
Regenerating model.
Total errors found 12 fixed 12
Erased 0 objects
И после сохранения и повторного открытия чертежа информация с листов пропадает???Именно так.
И еще такая строчка:Для начала удали все листы, выполни _AUDIT с исправлением всех ошибок. Затем сохрани чертеж, снова запусти _AUDIT и убедись, что ошибок нет. Дальше можешь запускать свою программу и посмотри что после неё скажет _AUDIT.
Обнаружено недопустимое имя конфигурации видовых экранов "*Multiple".
AcDbViewportTableRecord: "*Multiple"
Что это должно значить?
Подскажите, как решить задачу: я через ActiveX вставляю выноски функцией AddMLeader.Покажи код, которым ты это делаешь.
Пробовал добавлять и ModelSpace и Document в качестве нового собственника, пока не получилось...Попробуй в качестве нового собственника doc.Blocks
Как думаете, если мне нужно скопировать определение блока в другой чертеж, тоже не получится?Попробуй. В пределах одного чертежа скорее всего не получится из-за совпадения имён блоков. В другом чертеже если одноимённого блока нет, то возможно скопируется.
Я правильно понимаю, что это возвращаются и исходные объекты и новые?Нет. Эта функция возвращает:
RetVal = object.CopyObjects(Objects [, Owner] [, IDPairs])
RetVal - Variant (array of objects)
An array of newly created duplicate objects. Only primary objects are returned in this array.
IDPairs - Variant (array of IDPair objects); input-output; optionalТ.е. здесь пара: старый-новый объекты.
Information on what happened during the copy and translation process.
Input: an empty variant.
Output: an array of IDPair objects.
Скажите а в .net такие функции присутствуют?В .NET у BlockReference есть свойство BlockTransform, которое возвращает матрицу преобразования из координат блока в координаты МСК (WCS).
Можно ли как то заблокировать работу автокад на время работы скрипта?Заблокировать через COM/ActiveX нельзя. Можно сделать его невидимым: Application.Visible = False
То есть получается, в любом случае нужно разбивать код на участки, отлавливать исключения и если исключение возникает, код повторять заново? Ну либо вообще все сбрасывать.Именно так. Вот пример, как это делается в C++: https://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Добрый день!
Сталкиваюсь с такой проблемой, например, если программа довольно продолжительное время работает, существует проблема, что
если пользователь ткнет в чертеж или нажмет на клавишу, то при обращении к AutoCad выпадет исключение.
Можно ли как то заблокировать работу автокад на время работы скрипта?
Можно, конечно ловить исключения, но тогда придется ловить каждое обращение к автокаду, что сильно усложняет программу...
Может есть какой нибудь стандартный способ уйти от этого?
Ну и если есть такой, то сразу возникнет обратная задача, прервать работу скрипта и разблокировать автокад...
Я как-то для подобных целей использовал такой танец с бубном. Вставляю функцию в наиболее проблемные участки кода, когда нужно дождаться AutoCAD, а он занят черчением или может не ответить на запрос, пытаюсь получить доступ к пространству модели, иначе жду в цикле:
Код - Python [Выбрать]
def dynamicPause():
wait_time = 0.1
while wait_time<10:
try:
app = win32com.client.Dispatch("AutoCAD.Application")
aDoc = app.ActiveDocument
mSp = aDoc.ModelSpace
break
except:
sleep(wait_time)
wait_time *= 2
Что касается вопроса, то как-то так наверное:Получаю ошибку:
А если использовать
import win32com.client
т.е. так:
Код - Python [Выбрать]Код: [Выделить]import win32com.client
import array
app = win32com.client.Dispatch("AutoCAD.Application")
acadDoc = app.ActiveDocument
files = r"сектор-план"
insertionPnt = array.array('d', [377.7541,304.5495,0])
acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)
получаю ошибку:
acadDoc.ModelSpace.InsertBlock(insertionPnt, files, 1, 1, 1, 0)
File "<COMObject <unknown>>", line 5, in InsertBlock
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, None, None, None, 0, -2147024809), None)
правда сам не до конца понял, как оно работает, но оно работает!Функция POINT на основе переданных трёх чисел (x, y, z) формирует VARIANT, соответствующий массиву (VT_ARRAY) из чисел типа double (плавающие с двойной точностью VT_R8). Ну а дальше всё аналогично тому примеру, который я давал.
Всем здоровья!)Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме). Ну а ненужное потом удалишь.
Подскажите, как в существующий блок в пространстве модели добавить элементы из другого блока, удалив все элементы первого? Или вставить в него весь существующий блок, если так легче, опять же удалив все элементы первого.
Спасибо!
Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме).У блока нет метода CopyObjects, в примере этот метод применяется к документу и , как я понял, создается копия блока в документе, но мне нужно "перезаписать" содержимое уже существующего блока.
Ну значит ты не понял как работает этот метод. Ему нужно указать какой объект будет владельцем новых копий объектов. Вот этим владельцем и должен стать второй блок. Ну а из первого ничего удалять не нужно, так как ты собираешься удалить сам этот блок. В этом случае ты должен будешь сначала удалить все вставки (BlockReference) первого блока, а затем удалить сам блок (из таблицы Blocks)Посмотри метод CopyObjects для копирования объектов из одного блока в другой (есть пример в этой теме).У блока нет метода CopyObjects, в примере этот метод применяется к документу и , как я понял, создается копия блока в документе, но мне нужно "перезаписать" содержимое уже существующего блока.
Ну значит ты не понял как работает этот метод. Ему нужно указать какой объект будет владельцем новых копий объектов. Вот этим владельцем и должен стать второй блок. Ну а из первого ничего удалять не нужно, так как ты собираешься удалить сам этот блок. В этом случае ты должен будешь сначала удалить все вставки (BlockReference) первого блока, а затем удалить сам блок (из таблицы Blocks)
В примере выше есть строка: b_name = f"{o_blk.Name}_{i:02d}", это на JSON. Как это интерпретировать для питона?Это к теме не имеет отношения - это лишь для формата имени блока.
2. Должно быть как-то так (если копировать объекты блока 1 в блок 2):Пробовал и так. Выдает:
1. Почему pythoncom.VT_R8Честно и сам не очень понимаю этот момент. Брал из другого примера для преобразования данных в массив.
Не нужно бездумно копипастить. Объекты AutoCAD - это не плавающие числа. Поэтому вместо pythoncom.VT_R8 должно быть (скорее всего) pythoncom.VT_DISPATCH.1. Почему pythoncom.VT_R8Честно и сам не очень понимаю этот момент. Брал из другого примера для преобразования данных в массив.
это на JSONЭто он случайно выбрал не тот тип форматирования - вместо Python указал JSON.
Не нужно бездумно копипастить. Объекты AutoCAD - это не плавающие числа. Поэтому вместо pythoncom.VT_R8 должно быть (скорее всего) pythoncom.VT_DISPATCH.Благодарю за этот комментарий! Основная часть пройдена: в блок 1 вставились все элементы блока 2! Теперь нужно удалить (или это нужно было сделать сначала), все первоначальные элементы из блока 1. Как это можно сделать?
ИМХО лучше будет удалить все вхождения "Блок1", а потом уже удалить его описание.А это не приведет к удалению блока 1 из тех мест, где он находится в файле? Задача стоит в том, что бы элементы блока 1 заменились на элементы блока 2, при этом все местоположения блока 1 в модели должны сохраниться.
Задача стоит в том, что бы элементы блока 1 заменились на элементы блока 2, при этом все местоположения блока 1 в модели должны сохраниться.Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2" ???
Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2"Идея правильная, но как это сделать через питон?
Выбрать все вставки блока с именем "Блок 1" и изменить им свойство Name на "Блок 2". На питоне не пишу, поэтому код не предоставлю.Так может достаточно у вставок блока поменять свойство Name с "Блок 1" на "Блок 2"Идея правильная, но как это сделать через питон?
Пробую так:Имя нужно присваивать не Block (описание блока), а BlockReference (вставка блока), о чем я выше и писал.Код - Python [Выбрать]
block_1 = acadDoc.Blocks.Item("блок 1") block_1.Name = 'блок 2'
Выдает ошибку. Имя можно менять только на новое, например "блок 3", тогда ошибку не выдает.
Имя нужно присваивать не Block (описание блока), а BlockReference (вставка блока), о чем я выше и писал.Ох, никак не могу понять, как применить BlockReference в питоне...
Ох, никак не могу понять, как применить BlockReference в питоне...На питоне вообще практически нет примеров для работы с AutoCAD.
Как можно сделать значительно быстрее? Использование SelectionSets поможет убыстрить процес?Не думаю, что что-то может этот код ускорить. Разве что отказ от Python, который выполняется в отдельном процессе от AutoCAD, что приводит к замедлению.
Не думаю, что что-то может этот код ускорить.Может быть как-то можно сделать перебор не всех элементов в Модели, а только вставок блока?
А это как раз можно, но только через SelectionSetНе думаю, что что-то может этот код ускорить.Может быть как-то можно сделать перебор не всех элементов в Модели, а только вставок блока?
Подскажите, как можно поменять прорисовку текста, а точнее вынести на передний план?Посмотри в документации метод MoveToTop. Там и пример есть на VBA: https://knowledge.autodesk.com/ru/search-result/caas/CloudHelp/cloudhelp/2016/RUS/AutoCAD-ActiveX/files/GUID-0FA80CF9-427C-40F1-A400-BFD4AE81EE99-htm.html
Да, странное дело, у того блока, который не возвращал массива элементов установлен масштаб 110, меняю на 100, функция начинает возвращать элементы.О каком масштабе идёт речь? Есть масштабы по X,Y,Z, а есть масштаб аннотаций. Если масштабы по X,Y,Z отличаются, то Explode очень часто не срабатывает, ну и соответственно ничего не возвращает.
Почему?
Цитата: DMuzer от 10-04-2020, 15:20:18
Да, странное дело, у того блока, который не возвращал массива элементов установлен масштаб 110, меняю на 100, функция начинает возвращать элементы.
Почему?
О каком масштабе идёт речь? Есть масштабы по X,Y,Z, а есть масштаб аннотаций. Если масштабы по X,Y,Z отличаются, то Explode очень часто не срабатывает, ну и соответственно ничего не возвращает.
Ну видимо это как раз тот случай. Устанавливаю одинаковые масштабы, все начинает работать.Интересно, а что внутри этого блока? И какая версия AutoCAD?
Всем добра!Преобразовать в массив double, изменить соответствующие элементы массива и обратно преобразовать в VARIANT.
Подскажите, как к координатам в виде VARIANT задать смещение на заданную величину? Т.е. у меня есть точка в формате VARIANT, как задать ее смещение, т.е. изменить одну или несколько ее параметров x или y?
Все это в питоне.
Как преобразовать acLnWt211 для использования в питоне?Подставь просто целое число 211:
Первый аргумент должен быть целым (int)А 0 - это не целое (int)?
А 0 - это не целое (int)?В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.
В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.Первый аргумент ставлю 0, но питон ругается именно на него:
Так это же ошибка синтаксиса, а не типа данных. Может быть как-то так:В Python - не знаю. Может long, может short. Впрочем можешь попробовать short. Но главное второй и третий аргументы должны быть double.Первый аргумент ставлю 0, но питон ругается именно на него:
arrow_B.SetWidth 0, 5, 5
^
SyntaxError: invalid syntax
Так это же ошибка синтаксиса, а не типа данных.Ох, да , не отметил, что в питоне нужно добавлять скобки!
Существует ли какая-нибудь возможность через COM работать с этой новой функцией распознавания геометрии?Нет.
Единственное, что я нашел, это возможность через текстовую строку отправить команду AcadDocument.SendCommand("_-ПДФИМПОРТ ")Нужно послать такое lisp-выражение в качестве строки:
AcadDocument.SendCommand('(command "_-pdfimport" "_f" "C:/test.pdf" "1" "0,0" "1" "0") ')
А если бы, чисто теоретически, мне потребовалось бы применить больше настроек ("Данные PDF для импорта", "Слои", "Параметры импорта"), то эти настройки так же следовало бы вписывать в эту текстовую команду?Думаю, что это через системные переменные:
Есть ли документация на подобные lisp команды?На какие команды?
Есть ли документация на подобные lisp команды?На какие команды?
Эту команду нельзя запустить в режиме командной строки.Можно каким-то другим способом вставить таблицу эксел как объект автокад питоном?
Если на Python можно прочитать excel-файл, то на основе его можно создать таблицу в AutoCAD. Подозреваю, что если это даже и возможно, то очень не просто.
Я так кстати и делал недавно.Electric, прошу выслать данные наработки, если сохранились.
Electric, прошу выслать данные наработки, если сохранились.
у меня ничего не происходит. Что я делаю не так?В принципе всё так. Проверил в AutoCAD 2021 - действительно целиком колонке выравнивание задать нельзя. Возможно причина как-то связана с разными типами данных в разных колонках (Title, Header, Data). Так что задавать выравнивание придётся в цикле всем ячейкам колонки.
Всем добра!
Такая задача: после конвертации из pdf на чертеже присутствует множество прямоугольных треугольников примерно одинаковой площади. Как их можно удалить одним махом, написав прогу в pythone? Треугольники состоят из полилинии. Можно как-то их всех найти по площади?
Спасибо!
Требуется просто удалить их, к примеру, через поиск?Да, просто удалить.
Можно как-то их всех найти по площади?Нет. Да и вообще если бы это было можно, то способ был бы какой-то ненадежный. Нужно отобрать все полилинии (возможно на каком-то определенном слое), а затем уже обработать полученный набор:
Если все условия удовлетворяют, то удалить.Спасибо за ответ. Видимо проще вручную удалить.
Координаты считываются сначала внутри блока, затем с учетом точки вставки, угла поворота и общего зеркалирования перевожу их в общие для чертежа.Вот тут и вопрос. Внутри какого блока? Алексей Кулик правильно написал. Если работать с анонимным блоком, соответствующим текущему состоянию динамического блока, то никакие динамические параметры учитывать уже не нужно - они уже в этом анонимном блоке учтены. Плюс еще учтена и видимость примитивов внутри блока (см. у них свойство Visible).
hatch1 = mSp.AddHatch(PatternType = 1,
File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)
Но лично у меня при попытке назначить такую штриховку вылетает ошибка:Так и должно быть. Каждый из контуров - это один замкнутый контур. А у тебя две окружности. Т.е. одна должна быть внутренним контуром, а вторая наружным.
Цитировать
hatch1 = mSp.AddHatch(PatternType = 1,
File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)
Пока нереализовано...
Но лично у меня при попытке назначить такую штриховку вылетает ошибка:Это из-за PatternType = 1. Должно быть PatternType = 0.
Цитировать
hatch1 = mSp.AddHatch(PatternType = 1,
File "C:\Users\2E78~1\AppData\Local\Temp\gen_py\3.8\E2077CF2-3573-4E66-B1DC-01118675056Dx0x1x0\IAcadModelSpace.py", line 254, in AddHatch
ret = self._oleobj_.InvokeTypes(1579, LCID, 1, (9, 0), ((3, 1), (8, 1), (11, 1), (12, 17)),PatternType
pywintypes.com_error: (-2147352567, 'Ошибка.', (0, 'AutoCAD.Application', 'Пока не реализовано', 'C:\\Program Files\\Autodesk\\AutoCAD 2020\\HELP\\OLE_ERR.CHM', -2145386495, -2145386495), None)
Пока нереализовано...
circle1 = mSp.AddCircle(cc(0,0,0), 100)
circle2 = mSp.AddCircle(cc(20,20,0), 30)
hatch1 = mSp.AddHatch(PatternType = 0,
PatternName = "ANSI31",
Associativity = True,
HatchObjectType = 0)
hatch1.AppendOuterLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle1]))
hatch1.AppendInnerLoop(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [circle2]))
hatch1.Evaluate()
Комплект чертежей состоит из нескольких листов. Мы их обрамляем рамками, у которых есть свой штамп и другое. Эти листы мы располагаем в пространстве модели друг за другом. И на каждом из них может присутствовать какой-то элемент в определенном месте относительно глобальных координат. Можно конечно каждый раз переносить начало координат в нужную нам точку пространства, но думаю есть проектировщики, для кого это критично и недопустипо, да и выглядеть это будет не совсем удобно.
Внимание, а теперь вопрос к знатокам: "Как перед выполнением скрипта отправить запрос в Autocad об указании точки вставки результатов действий скрипта???" Другими словами - указать начало координат для скрипта не (0,0,0), а место куда укажем мышкой. Либо координаты того или иного элемента, который мы выделим мышкой. Думаю такая тема будет много кому полезна. Заранее спасибо и хорошего настроения всем...
Понимаю, что можно перед каждым вызовом функции делать проверки, но это не выход: во первых такая ерунда может произойти даже при обращении к свойствам объекта, а каждую такую строчку проверять - как бы уже бредом попахивает.Это единственный выход при использовании COM. Причем между обращениями к AutoCAD следует делать задержку как минимум в 500 миллисекунд.
Опять же, раньше то работало и меня все устраивало.Если раньше всё работало и AutoCAD не обновлял, то вероятно обновилась Windows. Но вообще-то просто тебе раньше везло. Такая проблема известна как минимум 10 лет. И именно поэтому я не рекомендую использовать COM/ActiveX, а писать приложения, которые грузятся внутрь AutoCAD.
Если только все обращения к свойствам объектов обернуть в:Не хватает задержки перед очередным обращением в случае except.
AndONE,Подскажите тогда через Python нормальный способ?
IMHO - это извращение. Для того, чтобы проделать эту процедуру, тебе придётся ко всему прочему еще и использовать Lisp, так как через COM-модель нельзя передать объекты в командную строку.
Подскажите тогда через Python нормальный способ?Через Python в принципе не может быть нормального способа - это не поддерживаемый с точки зрения AutoCAD язык программирования. И кроме того COM/ActiveX интерфейс AutoCAD уже очень сильно устарел и не позволяет то, что легко делается при помощи (например) AutoCAD .NET API. Фактически тебе потребуется переписать BURST на Python.
Какую команду в LISP гуглить, чтобы передать объекты через sendcommand?В lisp нет команд - одни функции. В данном случае тебе придётся в командную строку передать метки (Handle) всех объектов с вызовом функции (handent "метка"). Если объектов будет много, то через командную строку ты их передать не сможешь.
окей, спасибо.Какую команду в LISP гуглить, чтобы передать объекты через sendcommand?В lisp нет команд - одни функции. В данном случае тебе придётся в командную строку передать метки (Handle) всех объектов с вызовом функции (handent "метка"). Если объектов будет много, то через командную строку ты их передать не сможешь.
Я посмотрел исходники BURST (он действительно в Express Tools). Можно сильно упростить себе жизнь если воспользоваться оттуда функцией (BURST-ONE) - она выполняет BURST по одному объекту за раз. Поэтому можно выполнить в цикле строку при помощи Sendcommand:Это просто шикарно!
"(burst-one (handent \"здесь метка примитива\")) "
Надеюсь, что это даст результат.
Возможно ли через COM использовать зависимости со вкладки "Параметризация"? или это тоже недоступная для ActiveX возможность?Увы, нет. И даже в .NET с этим совсем не просто, а более-менее доступно только в ObjectARX.
Если она не грузится внутрь AutoCAD, то ты ничего не сделаешь. Все эти сборки можно использовать только в плагине, загруженном внутрь AutoCAD.
А если сравнивать .NET и ObjectARX - то по скорости работы и по своим возможностям первый вариант не сильно уступает второму?Не сильно если используется AutoCAD .NET API, а не COM/ActiveX
Мне не требуется создавать свои объекты в AutoCAD и как мне кажется, C# легче в освоении, там нет необходимости работать с ссылками и указателями. Или я снова ошибаюсь?Не ошибаешься.
DFG2020,
ObjectARX C++ даёт на порядок больше возможностей. Про быстродействие я вообще молчу...
reg = model.AddRegion(win32com.client.VARIANT(VT_ARRAY | VT_DISPATCH, [c]))reg - это не один Region, а коллекция. Так что нужно использовать элемент с нулевым индексом.
reg - это не один Region, а коллекция. Так что нужно использовать элемент с нулевым индексом.
Ну и кроме того угол в радианах, так что 2 - это 114.591559 градусов. Подозреваю, что ты хотел не это.
Нет какой нибудь установки чтоб Autocad понимал латинские буквы для дополнения команд?
Вроде бы я не прав и все объекты продолжают строится относительно глобальной системы координат. Это так?Да.
Если нет, мое решение - трансформировать все объекты матрицей 4х4?Да.
Господа, подскажите! Читал, читал тему...в голове каша. Подскажите как начертить полилинию? Можно код? Что нужно вставить в AddLightweightPolyline?
Код:Код - Python [Выбрать]
import win32com.client from pythoncom import VT_R8, VT_ARRAY, VT_DISPATCH, VT_VARIANT appAutocad = win32com.client.GetActiveObject("AutoCAD.Application") aDoc = appAutocad.ActiveDocument mSp = aDoc.ModelSpace def acadcoord(x,y,z): # преобразование координат return win32com.client.VARIANT(VT_ARRAY | VT_R8, [x, y, z]) mSp.AddLightweightPolyline(??????)
И как можно найти ID блока? ObjectID не срабатываетЧто значит не срабатывает?
Пишет, что у объекта нет ID.И как можно найти ID блока? ObjectID не срабатываетЧто значит не срабатывает?
Пишет, что у объекта нет ID.Покажи код и сообщение об ошибке.
Пишет, что у объекта нет ID.Покажи код и сообщение об ошибке.
Что в IN[0] и в IN[1]? То что у Block есть свойство ObjectID - это 100%.(https://i.postimg.cc/nj0zGxfg/12.jpg) (https://postimg.cc/nj0zGxfg)
Aleks_199513,В IN[0] имя таблицы идет, в IN[1] блок
Это мне ничего не говорит.
Aleks_199513,Очень странно, но подается же объект типа Block...буду искать дальше проблему тогда, а правильный ли я выбрал метод вставки блока в таблицу(tab.SetBlockTableRecordId(1,1,1928560679024,True))? или может есть другой вариант?
Или в IN[1] не блок (объект Block), или какая-то проблема с AutoCAD на твоей стороне.
P.S.: Кстати нужно сначала задать тип ячейки.спасибо, сейчас буду пробовать
Подскажите, пожалуйста! Как выбрать в чертеже все примитивы начерченные определенным слоем и удалить их.Вы недостаточно хорошо понимаете терминологию AutoCAD. У каждого примитива есть свойство - слой (Layer). Для выбора всех примитивов на заданном слое можно воспользоваться методом SelectionSet.Select acSelectionSetAll с фильтром по слою ( группа 8 ).
Через COM можно добавить.СпасибоКод - Visual Basic [Выбрать]
Sub testAddPointToFeatureLine() Dim obj As AcadObject ThisDrawing.Utility.GetEntity obj, pp Dim fl As AeccLandFeatureLine Set fl = obj flPoints = fl.GetPoints i = 0 Dim util As Object Set util = ThisDrawing.Utility Call util.CreateTypedArray(newPoint, vbDouble, (flPoints (i) + flPoints (i + 3)) * 0.5, flPoints ((i + 1) + flPoints (i + 4)) * 0.5, 20) 'Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointPI) 'aeccLandFeatureLinePointPI = 1 отображается на плане квадратной ручкой Call fl.InsertFeaturePoint(newPoint, aeccLandFeatureLinePointElevation) 'aeccLandFeatureLinePointElevation = 2 отображается на плане круглой ручкой End Sub
Так же есть метод InsertFeaturePoints
Если я правильно понял о чем, то это делается через MLeader.TextStringне совсем, это работает, когда стиль мультивыноски текст, а когда блок, то не работает...
А если неправильно, то через MLeader.SetBlockAttributeValueЕсли я правильно понял о чем, то это делается через MLeader.TextStringне совсем, это работает, когда стиль мультивыноски текст, а когда блок, то не работает...
А если неправильно, то через MLeader.SetBlockAttributeValueА как сделать так, чтобы центр блока не улетал в 0,0?
А если неправильно, то через MLeader.SetBlockAttributeValueА как сделать так, чтобы центр блока не улетал в 0,0?
Не видя Ваш код - никак
Интересное поведение. Даже если при создании мульти выноски я указываюКод - Visual Basic [Выбрать]Выноска создается с значением acConnectExtents.
MleaderObj.BlockConnectionType = acConnectBase
Попробуйте после создания пошевелить это свойство выноски. Может отдельной транзакцией или регеня чертеж.
В моем случае даже так не помогло. Зато ручкой у выноски меняешь расположение блока и он сразу подтягивается к выноскеКод - Visual Basic [Выбрать]
MleaderObj.BlockConnectionType = acConnectExtents MleaderObj.Update MleaderObj.BlockConnectionType = acConnectBase
Aleks_199513,Извините.
Не забывайте про правило форматирования кода на форуме (у меня в подписи)!
Код - какая-то дикая смесь AutoCAD COM/ActiveX и AutoCAD .NET API
забыл , если что значения констант:нет, к сожалению ничего не получилось. А может есть какой-то способ переместить блок?
acConnectBase=1
acConnectExtents=0
Не видя Ваш код - никакКод - Python [Выбрать]
import System import clr # Add Assemblies for AutoCAD and Civil3D #LinkDWG Core DYF by Koz Jono YEOH #kozmosovia@hotmail.com #Copyright(C) 1994-2020 KozMos Inc. #Copyright(C) 2011-2020 Neila Heaven Networks #Copyright(C) 2017-2020 Tachyon Intelligent Design Institute clr.AddReference('AcMgd') clr.AddReference('AcCoreMgd') clr.AddReference('AcDbMgd') clr.AddReference('AecBaseMgd') clr.AddReference('AecPropDataMgd') clr.AddReference('AeccDbMgd') clr.AddReference('ProtoGeometry') from Autodesk.AutoCAD.Runtime import * from Autodesk.AutoCAD.ApplicationServices import * from Autodesk.AutoCAD.EditorInput import * from Autodesk.AutoCAD.DatabaseServices import * from Autodesk.AutoCAD.Geometry import * # Import references from Civil3D from Autodesk.Civil.ApplicationServices import * from Autodesk.Civil.DatabaseServices import * marsh = System.Runtime.InteropServices.Marshal app = marsh.GetActiveObject("Autocad.Application.24.1") aDoc = app.ActiveDocument mSp = aDoc.ModelSpace adoc = Application.DocumentManager.MdiActiveDocument def ptA(p,x1,y1): return System.Array[float]([p.X,p.Y,p.Z,p.X+x1,p.Y+y1,p.Z]) x1 = 5 y1 = 5 blockItem = None # Координаты блоков listOfPoints = IN[0] numbeTable= IN[1] Coord=[] logFile = [] import Autodesk outList = [] with adoc.LockDocument(): with adoc.Database as db: with db.TransactionManager.StartTransaction() as t: # Place your code below for i in listOfPoints: bufferOut = [] locOrigin = i.Origin points = ptA(locOrigin,x1,y1) lead = mSp.AddMLeader(points, 0) bufferOut.append(lead) leaderBlocks = aDoc.Blocks(lead.ContentBlockName) [color=red] [u]Вот эта строка повторяется тремя строками ниже[/u][/color] if lead and hasattr(lead,"ObjectName") and lead.ObjectName=="AcDbMLeader": blocks=lead.Document.Blocks.Item(lead.ContentBlockName) [color=red] здесь[/color] for block in blocks: // здесь block по факту это acadEntity, то есть элементы из которых состоит определение блока if block.ObjectName == "AcDbAttributeDefinition" and block.TagString.upper() == "НОМЕРЯРЛЫКА".upper(): [color=red] block.TagString.upper() == "НОМЕРЯРЛЫКА".upper() - вот тут скорее всего спотыкается код. Так как ентити может быть линией и у нее нет такого свойства[/color] lead.SetBlockAttributeValue(block.ObjectId, str(numbeTable[listOfPoints.index(i)])) blockItem = block[color=red] ну это тоже не то пальто[/color] # Commit before end transaction t.Commit() #lead.TextString = str(numbeTable[listOfPoints.index(i)]) #ID_Name1 = (aDoc.Blocks("_TagCircle").ObjectID) #lead1= mSp.SetBlockAttributeValue(lead.ObjectID,) #lead.GetBlockAttributeValue(ID_Name1) #coord.append(points) outList = [] OUT = blockItem
Я сейчас перепроверил, все работает оказывается. Не заметил On error goto exit , код спотыкался об мою попытку настроить свойства текста выноски.а вы проверяли работу на VBA?
Так как в выноске блок вместо текста, код выходил из процедуры не доходя до настройки MleaderObj.BlockConnectionType = acConnectExtents.
Так что проверяйте код на ошибки, в цитировании помечу вероятные места
попытался выделить цветом в код блоке -не срабатывает.
строки с моими комментариям:
58, 61, 62, 63 (ошибка тут скорее всего) , 67Не видя Ваш код - никакКод - Python [Выбрать]
import System import clr # Add Assemblies for AutoCAD and Civil3D #LinkDWG Core DYF by Koz Jono YEOH #kozmosovia@hotmail.com #Copyright(C) 1994-2020 KozMos Inc. #Copyright(C) 2011-2020 Neila Heaven Networks #Copyright(C) 2017-2020 Tachyon Intelligent Design Institute clr.AddReference('AcMgd') clr.AddReference('AcCoreMgd') clr.AddReference('AcDbMgd') clr.AddReference('AecBaseMgd') clr.AddReference('AecPropDataMgd') clr.AddReference('AeccDbMgd') clr.AddReference('ProtoGeometry') from Autodesk.AutoCAD.Runtime import * from Autodesk.AutoCAD.ApplicationServices import * from Autodesk.AutoCAD.EditorInput import * from Autodesk.AutoCAD.DatabaseServices import * from Autodesk.AutoCAD.Geometry import * # Import references from Civil3D from Autodesk.Civil.ApplicationServices import * from Autodesk.Civil.DatabaseServices import * marsh = System.Runtime.InteropServices.Marshal app = marsh.GetActiveObject("Autocad.Application.24.1") aDoc = app.ActiveDocument mSp = aDoc.ModelSpace adoc = Application.DocumentManager.MdiActiveDocument def ptA(p,x1,y1): return System.Array[float]([p.X,p.Y,p.Z,p.X+x1,p.Y+y1,p.Z]) x1 = 5 y1 = 5 blockItem = None # Координаты блоков listOfPoints = IN[0] numbeTable= IN[1] Coord=[] logFile = [] import Autodesk outList = [] with adoc.LockDocument(): with adoc.Database as db: with db.TransactionManager.StartTransaction() as t: # Place your code below for i in listOfPoints: bufferOut = [] locOrigin = i.Origin points = ptA(locOrigin,x1,y1) lead = mSp.AddMLeader(points, 0) bufferOut.append(lead) leaderBlocks = aDoc.Blocks(lead.ContentBlockName) [color=red] [u]Вот эта строка повторяется тремя строками ниже[/u][/color] if lead and hasattr(lead,"ObjectName") and lead.ObjectName=="AcDbMLeader": blocks=lead.Document.Blocks.Item(lead.ContentBlockName) [color=red] здесь[/color] for block in blocks: // здесь block по факту это acadEntity, то есть элементы из которых состоит определение блока if block.ObjectName == "AcDbAttributeDefinition" and block.TagString.upper() == "НОМЕРЯРЛЫКА".upper(): [color=red] block.TagString.upper() == "НОМЕРЯРЛЫКА".upper() - вот тут скорее всего спотыкается код. Так как ентити может быть линией и у нее нет такого свойства[/color] lead.SetBlockAttributeValue(block.ObjectId, str(numbeTable[listOfPoints.index(i)])) blockItem = block[color=red] ну это тоже не то пальто[/color] # Commit before end transaction t.Commit() #lead.TextString = str(numbeTable[listOfPoints.index(i)]) #ID_Name1 = (aDoc.Blocks("_TagCircle").ObjectID) #lead1= mSp.SetBlockAttributeValue(lead.ObjectID,) #lead.GetBlockAttributeValue(ID_Name1) #coord.append(points) outList = [] OUT = blockItem
Ваш код полностью моделить не буду, но вот вам наглядно что когда вы пишите For each по block, происходит перебор составляющих определения блока. Среди них не только атрибуты поэтому обращать к свойству которое есть только у атрибута это ошибка. Я ведь уже написал.Спасибо. Решил проблему просто изменением стиля выноски.
Вообще советую тестироваться самому на ВБА так как в питоне(в данном случае из под динамо) просто нет функций по дебагу кода, отсюда такие ошибки
Добрый день. Подскажите пожалуйста, как можно получить координаты вершин полилинии в Python?Свойство Coordinates.
не выдает ошибку, но ни чего и не выводит в консоль.Ничего не выводит или выводит
Text =
как будто текст пустой?Выводит:не выдает ошибку, но ни чего и не выводит в консоль.Ничего не выводит или выводитКод: [Выделить]Text =
как будто текст пустой?
Если да, то это нормально. Значит текст не переопределён.
А как в таком случае прочитать текст из размера?Похоже, что средствами COM/ActiveX это сделать не просто. Можно расчленить размер, вытащить текст, отменить изменения.
Я тоже об этом думал, но это не то чего бы хотелосьА как в таком случае прочитать текст из размера?Похоже, что средствами COM/ActiveX это сделать не просто. Можно расчленить размер, вытащить текст, отменить изменения.
Средствами .Net подходит вроде метод DimensionText, но я понятия не имею как с этим работатьИз Python? Если он не запускается изнутри AutoCAD - то никак. Ибо AutoCAD .NET API можно использовать только изнутри AutoCAD.
И кстате я ищу не эту строчкуА в чем у тебя разница между этими значениями? Посмотри еще свойства TextPrefix и TextSuffixКод - Python [Выбрать]Она как раз находит величину размера.
print('Величина размера = ', object.Measurement)
А мне нужны данные из "Текстовая строка" в свойстве размера
Я просто не пойму раз есть метод ввода данных в Текстовую строку, почему нельзя их от туда прочитатьС размером связан блок, внутри которого МТекст, отрезки и т.д. Эту связь можно отследить (и соответственно получить содержимое МТекст) в Lisp/.NET/ObjectARX, но не в COM/ActiveX
Или где про это можно найти документацию?Это не документировано. Все доступные из COM/ActiveX свойства можно получить при помощи метода VisualLisp https://help.autodesk.com/view/OARX/2019/RUS/?guid=GUID-BCE56B30-54A6-42F9-8910-81AF2B7B9AA8
Сначала надо установить системную переменную DIMBLK, а потом уже назначать ArrowSymbol. Естественно, не забыв вернуть DIMBLK обратно.Разобрался, спасибо большое. Вот так будет выглядеть код:
Доброго времени суток, Может кто-нибудь знает как получить доступ к именам блоков которые входят в состав многовидового блока?Нашел такое в документации. Попробуй адаптировать:
Здравствуйте, кто-нибудь работал с СПДС GraphiCS от Csoft? В нем присутствует такой элемент как "Формат". Нужно как то добраться до значения всех атрибутов основной надписи или штампа по простому и прочитать значения всех ячеек из него.
Может и с "\\", только все равно ошибка. Пробовал и с "/" - тоже ошибка.
Добрый день. Подскажите, пожалуйста, как получить цвет объекта в чём-то помимо ACI? Искал по этой теме, видел только применение RGB, но получить TrueColor объекта у меня не получилось. В общем надо чтобы программа понимала в какой RAL выкрашен объектВ COM/ActiveX API, которое использует Python, таких средств нет. Тут необходимо создать массив, в котором будет соответствие ACI номера и цвета RGB. Например, как сделано здесь: https://forums.autodesk.com/t5/vba/converting-colors-to-rgb/td-p/350909
Спасибо. К сожалению через соответствие ACI не получится определять RAL, ибо первые же RAL'ы в RGB эквиваленте определяются одним и тем же ACI (близкие оттенки). Что ж, еще один "за" в сторону С#, в котором такие мелочи реализуемы?Добрый день. Подскажите, пожалуйста, как получить цвет объекта в чём-то помимо ACI? Искал по этой теме, видел только применение RGB, но получить TrueColor объекта у меня не получилось. В общем надо чтобы программа понимала в какой RAL выкрашен объектВ COM/ActiveX API, которое использует Python, таких средств нет. Тут необходимо создать массив, в котором будет соответствие ACI номера и цвета RGB. Например, как сделано здесь: https://forums.autodesk.com/t5/vba/converting-colors-to-rgb/td-p/350909
Но вообще-то соответствия ACI-номеров и RGB разные в разных версиях AutoCAD и еще зависят от цветовой схемы AutoCAD.
Что ж, еще один "за" в сторону С#, в котором такие мелочи реализуемы?Средствами ObjectARX или AutoCAD .NET API для каждого ACI можно получить RGB.
Traceback (most recent call last):
File "c:\Users\m.davydov\Dropbox\MyProg\SLD_Builder\deleting_selected_blocks.py", line 35, in <module>
if objSS.EffectiveName == "TOTAL" or objSS.EffectiveName == "KNF" or objSS.EffectiveName == "INCOMER" or objSS.EffectiveName == "AUTOMAT" or objSS.EffectiveName == "LINE":
File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\dynamic.py", line 324, in __getitem__
return self._get_good_object_(self._enum_.__getitem__(index))
File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\util.py", line 41, in __getitem__
return self.__GetIndex(index)
File "C:\Users\m.davydov\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\win32com\client\util.py", line 62, in __GetIndex
result = self._oleobj_.Next(1)
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)
Derie1,
Приветствую на форуме! Обрати внимание на правило форматирования кода, ссылка на которое у меня в подписи.
а иногда застревает на каком то шаге и вылетает с ошибкой.С какой ошибкой?
С какой ошибкой?Добавил текст ошибки в своё сообщение.
При этой ошибке можешь попробовать сделать небольшую задержку и повторить вызов.С какой ошибкой?Добавил текст ошибки в своё сообщение.
Я так понимаю, цикл надо примерно так переписать?Нет. Во-первых, выше я написал как нужно организовать цикл (от последнего элемента к первому). Во-вторых, нужен какой-то счетчик количества повторений при ошибке (например, не больше 100). Иначе возможно зацикливание.
Кстати, ни разу не видел, а возможно ли сделать дополнительный SelectionSet, отобрать в него только те элементы, которые надо удалить, и потом разом их все удалить, не перебирая циклом каждый?Если мне не изменяет память, то objSS.Erase() должно удалить все примитивы из набора.
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)Это ошибка COM в Windows, характерна не только для AutoCAD, но и для других приложений, например, Excel. Зависит от кучи разных вещей, начиная от версии Windows и её обновлений, версии AutoCAD и заканчивая быстродействием компьютера, не нашёл какой-то стабильной закономерности. Причина, насколько я понимаю в том, что COM не поддерживает очередь обработки, и, похоже, если AutoCAD занят в то время, кода ему выдается новая команда, то запрос отклоняется. Естественно, что добавление задержек в позволяет уменьшить проблему, но это лишь лечение симптомов.
pip install pyacadcom
.Думаю, каждый, кто работает с автокадом из чистого питона, сталкивались с ошибкой -2147418111 "Call was rejected bycallee/Вызов был отклонен".Вообще-то ошибок, связанных с "занятостью" AutoCAD несколько: https://adn-cis.org/kak-ispolzuya-visual-c-zapustit-autocad-i-zastavit-ego-vyipolnyat-nekotoryie-dejstviya.html
Для удобства собрал модуль pyacadcom.Спасибо за наводку. Попробовал в своём скрипте заменить:
total_blk = ms.InsertBlock(pt1, "TOTAL", 1.0, 1.0, 1.0, 0)
File "<COMObject <unknown>>", line 3, in InsertBlock
TypeError: must be real number, not acadPoint
objSS = doc.SelectionSets.Add("toErase")Как получен doc? Если это не производное от pyacadcom.AutoCAD() - ошибки перехватываться не будут. Какой код ошибки?
Как получен doc?
acad = pyacadcom.AutoCAD()Вообще должно работать. Напишите коды ошибок, которые получаются.
doc = acad.Documents.Open(dwg_file)
ms = doc.ModelSpace
Вообще должно работать. Напишите коды ошибок, которые получаются.На всякий случай, привожу весь скрипт по удалении определенных блоков из чертежа:
Traceback (most recent call last):Ошибка 2 (там же, но другая):
File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 20, in <module>
objSS = doc.SelectionSets.Add("blocks")
File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 628, in __getattr__
ret = self._oleobj_.Invoke(retEntry.dispid, 0, invoke_type, 1)
pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)
Traceback (most recent call last):Ошибка 3 (при удалении блоков. Здесь может быть ошибка на любом блоке, часть удалит, а потом где то встрянет. Так же здесь случаются ошибки как и в случае 1):
File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 20, in <module>
objSS = doc.SelectionSets.Add("blocks")
File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.Add
Traceback (most recent call last):Ошбика 4 (при добавлении всех блоков в SelSet):
File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 32, in <module>
if obj.EffectiveName == "TOTAL" or obj.EffectiveName == "KNF" or obj.EffectiveName == "INCOMER" or obj.EffectiveName == "AUTOMAT" or obj.EffectiveName == "LINE":
File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: <unknown>.EffectiveName
Traceback (most recent call last):
File "c:\Users\mdavy\Dropbox\MyProg\SLD_Builder\.test_code\deleting_selected_blocks.py", line 27, in <module>
objSS.Select(SELECT_ALL, pythoncom.Empty,
File "C:\Users\mdavy\AppData\Local\Programs\Python\Python310\lib\site-packages\win32com\client\dynamic.py", line 639, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: Add.Select
Ну и так далее. При этом у меня на домашнем компе, код намного более стабильно работает, чем на рабочем..Пока не получается повторить ошибки. Протестирую на доступных компьютерах, подумаю как сделать диагностику у вас поинформативней и отпишусь.
Derie1, а удаление выполняется только для "обычных" вхождений? А состояние слоев игнорируется специально? А описания блоков удалять не надо?Не совсем понял, что имеете в виду под "обычными" вхождениями?
Протестирую на доступных компьютерах, подумаю как сделать диагностику у вас поинформативней и отпишусь.Вот ссылка (https://github.com/Derie1/SLD_Builder.git) на мой GitHub по этому скрипту. Там в подпапке test_files есть файл SLD_full.dwg. На нем можно протестировать удаление блоков этих.
Вот ссылка на мой GitHub по этому скрипту. Там в подпапке test_files есть файл SLD_full.dwgНичто не ново под луной. Аналогичную штуку написал лет 5 назад :)
Примерно так:Ваш вариант имеет место быть. Он работает, но у него все те же проблемы. Периодически, рандомно, вылетают ошибки типа "pywintypes.com_error: (-2147418111, 'Вызов был отклонен.', None, None)"
Алексей Кулик,Модуль допилим :)
Да, я перешел на этот модуль, но все равно ошибки случаются...
Модуль допилим :)
А в питоне нет метода CopyObjects ?А какой встроенный питоновский метод вы имеете в виду?
choppylion,Пробовал так. Код успешно отрабатывает, но блок так и не появляется среди доступных в панели Insert.
ВместоКод - Python [Выбрать]должно быть
src_doc.CopyObjects(src_obj_array, new_block)Код - Python [Выбрать]
src_doc.CopyObjects(src_obj_array, dst_doc.Blocks)
result = {tuple: 6} (<COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>, <COMObject CopyObjects>)
0 = {CDispatch} <COMObject CopyObjects>
1 = {CDispatch} <COMObject CopyObjects>
2 = {CDispatch} <COMObject CopyObjects>
3 = {CDispatch} <COMObject CopyObjects>
4 = {CDispatch} <COMObject CopyObjects>
5 = {CDispatch} <COMObject CopyObjects>
new_block = dst_doc.Blocks.Add(insertion_point, name)Этого быть не должно. Иначе ты сразу создаешь блок, который неможет быть динамическим.
у него значение 0,Я правильно понимаю, что ты распечатал это значение и убедился, что оно 0?
а я до этого пробовалПытался массив подсунуть? ;)
prop[3].Value = win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, [1])
Да. Такое бывает. Обычно это связано с пустыми текстами, отрезками нулевой длины и т.д. Но судя по коду ошибки удален какой то объект, который участвует в подсчете габаритов блока. На всякий случай проверьте чертеж на ошибки (команда _AUDIT)Здорово! Помогло, теперь корректно считается. Искренне благодарю!
Помогло, теперь корректно считается.После _AUDIT?
Помогло, теперь корректно считается.После _AUDIT?