Сообщество программистов Autodesk в СНГ

ADN Club => VBA => Тема начата: Дамир от 11-08-2014, 23:46:52

Название: Вставка блока из другого файла
Отправлено: Дамир от 11-08-2014, 23:46:52
Друзья, приветствую!
Наша PDM система позволяет выполнять VBS скрипты. Необходима команда для постановки подписи в  файл AutoCAD. В имеющийся файл “Наш чертеж” поместить блок из файла “Подпись”.
 
Руководствовался интернетом, в частности форумами. Примеры кода моих попыток:
 
Начало одинаковое:

Код - Visual Basic [Выбрать]
  1. Dim FileDialog, FName, AcadApp, AcadDocs, Doc, DocNew
  2. Set AcadApp = CreateObject("AutoCAD.Application")
  3.  
  4. Set doc1 = AcadDocs.Open("C:\Users\damir\Downloads\Sign\Наш чертеж.dwg")
  5. Set doc2 = AcadDocs.Open("C:\Users\damir\Downloads\Sign\Подпись.dwg")

ВАРИНАТ 1
 
Код - Visual Basic [Выбрать]
  1. set blocks1 = doc1.Blocks
  2. set blocks2 = doc2.Blocks
  3.  
  4. set oldBlock = blocks2.Item("sss") ‘ естественно блок с именем  “sss” существует.
  5. insp = oldBlock.Origin
  6.  
  7. redim objs(oldBlock.count)
  8. i=0
  9.  
  10. For Each obj In oldBlock
  11.    set objects(i) = obj
  12.    i = i + 1
  13. Next
  14.  
  15. set newBlock = blocks1.add(insp, "sss")
  16. ‘Далее варианты команды CopyObjects
  17. set res = doc1.CopyObjects(obs)
  18. set res = doc1.CopyObjects(obs, newBlock)
  19. doc1.CopyObjects(obs, newBlock)

‘ в результате получаю ошибку:
"Неверный массив объектов" - ошибка AutoCAD.Applocation

хотя при обращении msgbox obs(0).ObjectName получаю имя объекта (полилиния)
_______________________________________
ВАРИАНТ 2

Код - Visual Basic [Выбрать]
  1. ‘Начало то же
  2.  
  3. Dim dblX, dblY, dblZ, dblRotation
  4. dim varInsertionPoint(3)
  5.  
  6. varInsertionPoint(0) = Cdbl(0)
  7. varInsertionPoint(1) = Cdbl(0)
  8. varInsertionPoint(2) = Cdbl(0)
  9.  
  10.  
  11. dblX = Cdbl(0)
  12. dblY = Cdbl(0)
  13. dblZ = Cdbl(0)
  14. dblRotation = Cdbl(0)
  15.  
  16. Set objBlockRef = doc1.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\damir\Downloads\Sign\Подпись.dwg", dblX, dblY, dblZ, dblRotation)
  17.  
Ничего не происходит. То есть вставку не наблюдаю. Прошелся по всему чертежу...

Возможно я использую не те методы AutoCAD. Либо допускаю ошибки. Прошу Вашей помощи в разрешении этого вопроса.
Заранее премного благодарен.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 02:04:58
На VBA я не пишу совсем, но это как понимать:
Код - Visual Basic [Выбрать]
  1. redim objs(oldBlock.count)
  2. i=0
  3.  
  4. For Each obj In oldBlock
  5.    set objects(i) = obj
  6.    i = i + 1
  7. Next
  8.  
Т.е. определяешь objs, а заполняешь objects. Это как?
Второе. При таком копировании ты копируешь описание блока, а не вставку блока. Т.е в самом чертеже ты так ничего и не увидишь.

Во втором случае ты вставляешь Пространство Модели из внешнего чертежа в Пространство модели своего чертежа, а совсем не блок "sss"
Ну и если в том чертеже в Пространстве модели ничего нет, то ты ничего и не видишь.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 12-08-2014, 09:03:53
Александр Ривилис, благодарю за скорый ответ!
Пройду по замечаниям. Многое осмотрел в примерах на ресурсах, посвященных этой теме.
1. По поводу obs и objects. Код был перелопачен изрядно. Видимо на форум поместил измененный фрагмент. Т.е. в рабочем коде везде obs.

Цитировать
При таком копировании ты копируешь описание блока, а не вставку блока. Т.е в самом чертеже ты так ничего и не увидишь.
Вы имеете ввиду эти методы:
Код - Visual Basic [Выбрать]
  1. set newBlock = blocks1.add(insp, "sss")
  2. ‘Далее варианты команды CopyObjects
  3. set res = doc1.CopyObjects(obs)
  4. set res = doc1.CopyObjects(obs, newBlock)
  5. doc1.CopyObjects(obs, newBlock)

Получается таким способом нельзя скопировать объект из одного чертежа в другой? Наверное я что то не понимаю. В справке к AutoCAD нашел о методе CopyObjects:

Цитировать
Duplicates multiple objects (deep cloning).
RetVal = object.CopyObjects(Objects [, Owner] [, IDPairs])

2.
Цитировать
Во втором случае ты вставляешь Пространство Модели из внешнего чертежа в Пространство модели своего чертежа, а совсем не блок "sss"
Данный способ посмотрел в примере:
Код - Visual Basic [Выбрать]
  1. Set objBlockRef = doc1.ModelSpace.InsertBlock(varInsertionPoint, "C:\Users\damir\Downloads\Sign\Подпись.dwg", dblX, dblY, dblZ, dblRotation)
По поводу копирования пространств модели спорить не буду, но во втором чертеже есть объект - сплайн. Его при копировании не наблюдаю.

3. Ну и самый главный вопрос: если перечисленные методы не подходят, то каким же пользоваться для простого копирования блока из  одного чертежа в другой? Прошу Вашей  помощи, ибо уж все перепробовал...
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 11:49:58
По поводу копирования пространств модели спорить не буду, но во втором чертеже есть объект - сплайн. Его при копировании не наблюдаю.
А ты не обратил внимание, что у тебя в коде нулевые масштабные коэффициенты по X,Y,Z??? Я так понимаю, что они должны быть единичными.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 12-08-2014, 11:59:12
Александр Ривилис, да обратил кончено.
Следующий код возвращает ошибку: "Недопустимое число элементов в Safearray" - AutoCAD.Appplication
Код - Visual Basic [Выбрать]
  1. redim startPoint(3)
  2.  
  3. startPoint(0) = cdbl(1.0)
  4. startPoint(1) = cdbl(1.0)
  5. startPoint(2) = cdbl(1.0)
  6.  
  7. Dim convArr1
  8. convArr1 = ThisApplication.Utility.VariantToArray(startPoint)
  9.  
  10. dblX = cdbl(1.0)
  11. dblY = cdbl(1.0)
  12. dblZ = cdbl(1.0)
  13. dblRotation = cdbl(0.0)
  14.  
  15. Set objBlockRef = doc1.ModelSpace.InsertBlock(convArr1, "C:\Users\damir\Downloads\Sign\Подпись.dwg", dblX, dblY, dblZ, dblRotation)

Вопрос остается открытым: какой метод исползовать для копирования объектов, блоков из чертежа в чертеж, либо вставки блока в чертеж?????????
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 12:01:46
Ты должен сначала скопировать описание блока при помощи CopyObjects, а потом вставить его при помощи InsertBlock

P.S.: Не забывай на форум вставлять теги кода [code=vb]... здесь сам код...[/code]
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 13:28:24
У меня получилось что-то такое:
Код - Visual Basic [Выбрать]
  1. Option Explicit
  2.  
  3. Sub TestDwg2DwgBlkTrans()
  4.     Dim strPath As String
  5.     Dim strPathTo As String
  6.     Dim strBlockName As String
  7.     Dim objBlock As AcadBlock
  8.     Dim entRef As AcadBlockReference
  9.     Dim dblPkPt() As Double
  10.     strBlockName = "shtamp" ' Имя блока штампа
  11.    strPath = "C:\shab_shtamp.dwg" ' Имя файла с блоком штампа
  12.    strPathTo = "C:\Тестовый чертеж.dwg" ' Имя файла в который вставляем штамп
  13.    On Error Resume Next
  14.     DbxCopyBlock strBlockName, strPath, strPathTo ' Копируем описание блока и выполняем вставку его
  15. End Sub
  16.  
  17. Sub DbxCopyBlock(strBlockName As String, strPathFrom As String, strPathTo As String)
  18.     Dim strFullDef As String
  19.     Dim objBlock As AcadBlock
  20.     Dim colBlocks As AcadBlocks
  21.     Dim objArray(0) As Object
  22.     Dim ACDbxFrom As Object
  23.     Dim entRef As AcadBlockReference
  24.     Dim ACDbxTo As Object
  25.     Set ACDbxFrom = GetAcDbxDoc()
  26.     ACDbxFrom.Open strPathFrom
  27.     Set ACDbxTo = GetAcDbxDoc()
  28.     ACDbxTo.Open strPathTo
  29.     Set colBlocks = ACDbxFrom.Blocks
  30.     Set objBlock = colBlocks.Item(strBlockName)
  31.     Set objArray(0) = objBlock
  32.     ACDbxFrom.CopyObjects objArray, ACDbxTo.Blocks
  33.     Dim insertionPnt(0 To 2) As Double
  34.     insertionPnt(0) = 0#: insertionPnt(1) = 0#: insertionPnt(2) = 0#
  35.     Set entRef = ACDbxTo.ModelSpace.InsertBlock(insertionPnt, strBlockName, 1#, 1#, 1#, 0#)
  36.     ACDbxTo.SaveAs strPathTo
  37.     Set ACDbxFrom = Nothing
  38.     Set ACDbxTo = Nothing
  39. End Sub
  40.  
  41. Function GetAcDbxDoc() As Object
  42.     Dim strAcadVersion As String
  43.     With ThisDrawing.Application
  44.        strAcadVersion = Mid(.Version, 1, 2)
  45.        If CInt(strAcadVersion) < 16 Then
  46.            Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument")
  47.        Else
  48.            Set GetAcDbxDoc = .GetInterfaceObject("ObjectDBX.AxDbDocument." & strAcadVersion)
  49.        End If
  50.     End With
  51. End Function
  52.  

1. Учти, что на VBA я не пишу и не уверен, что синтаксис VBA и VBS абсолютно одинаков.
2. Проверки ошибок в моём коде нет вообще. Например, подразумевается, что в файле, в который мы копируем нет блока с таким именем, который есть в файле шаблона.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 12-08-2014, 17:47:33
Александр Ривилис, огромное Вам спасибо.

Конечно проблему пока решить так и не удалось. Грешу в большей степени на работу VBS с типами данных. К примеру, чтобы поместить графический объект мы используем точку с координатами x, y, z. Причем в VBA пишем эти координаты в виде массива (пример из Вашего кода)
Код - Visual Basic [Выбрать]
  1.  Dim insertionPnt(0 To 2) As Double
  2.     insertionPnt(0) = 0#: insertionPnt(1) = 0#: insertionPnt(2) = 0#
В VBS этот номер не проходит, поэтому создаем альтернативную запись:
Код - Visual Basic [Выбрать]
  1. redim insertionPnt(3)
  2.   insertionPnt(0) = Cdbl(0.0)
  3.   insertionPnt(1) = Cdbl(0.0)
  4.   insertionPnt(2) = Cdbl(0.0)
  5.  
На выходе имеем массив с координатами. Тип данных массива - Variant? что AutoCAD'y не нравится и он жалуется ошибкой: "Неверный массив объектов" .

В системе, где я пишу свой код есть метод, позволяющий конвертировать в массивы формата VBScript в типизированные VBA массивы. Что мне собственно и нужно. Однако, переконвертировав массив получаю пустую ошибку используемой мною системы.

Аналогичная ситуация при работе с массивами, содержащими объекты:
Код - Visual Basic [Выбрать]
  1. Set objArray(0) = objBlock

 Все это указывает на проблему с типами данных.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 17:53:36
Ну с этим я вряд ли смогу помочь. Придется тебе самостоятельно с этим разбираться. Не исключаю, что каких-то возможностей VBS может просто не хватить.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 12-08-2014, 18:31:16
P.S.: Метод CopyObjects не допускает позднего связывания.
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 13-08-2014, 00:33:15
Дамир, а конструкция типа
Код - Visual Basic [Выбрать]
  1. Dim insPoint
  2. insPoint = (0.0, 0.0, 0.0)
не сработает?
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 13-08-2014, 13:20:32
Друзья, благодарю вас!

Решил проблему. Причина была действительно в типах массивов, которые при создании в VBS были непонятны AutoCAD.
Рабочий вариант:
Так я заполняю массив координат для точки вставки:
Код - Visual Basic [Выбрать]
  1. Dim insertionPnt, insertionPnt2                                                             ' ПЕРВАЯ РАЗНИЦА В СРАВНЕНИИ С ПРЕДЫДУЩИМ КОДОМ
  2.  insertionPnt = array(Cdbl(0.0), Cdbl(0.0), Cdbl(0.0))
  3.   insertionPnt2 = array(Cdbl(100.0), Cdbl(100.0), Cdbl(0.0))
  4.  

Далее как и ранее преобразую его в понятный AutoCAD'y тип данных (объект состоящий из Double элементов)
Код - Visual Basic [Выбрать]
  1. set doc1 = AcadDocs.Open(strPath)                            
  2.   conv1 = ThisApplication.Utility.VariantToArray(insertionPnt)
  3.   conv2 = ThisApplication.Utility.VariantToArray(insertionPnt2)
  4.  


Код - Visual Basic [Выбрать]
  1. set doc2 = AcadDocs.Open(strPathTo)                    
  2.  
  3.   Set colBlocks = doc1.Blocks                                                 ' определяю блоки чертежа, из которого буду забирать нужный мне блок  
  4.  Set objBlock = colBlocks.Item(strBlockName)                      ' нужный мне блок
  5.    
  6.   Dim  objArray
  7.   objArray = array(objBlock)                                                   ' ЕЩЕ ОДНА РАЗНИЦА! ПРИСВАИВАЮ ЗНАЧЕНИЕ МАССИВА ПО ДРУГОМУ
  8. '  Set objArray(0) = objBlock                              
  9.  convArr = ThisApplication.Utility.VariantToArray(objArray)   '  преобразую его в понятный AutoCAD'y тип данных массива    
  10.  doc1.CopyObjects convArr, doc2.Blocks                               '  помещаю объекты искомого блока в состав блоков второго чертежа
  11.        
  12.   Set entRef = doc2.ModelSpace.InsertBlock(conv1, strBlockName, 1, 1, 1, 0) ' помещаю сам блок
  13.  

Друзья проблему со вставкой решили. Однако, теперь стоит более глобальная задача - вставка блока на все листы чертежа.
Сейчас вставка осуществляется в пространство модели ModelSpace, для вставки в пространство листа строку меняю так:
Код - Visual Basic [Выбрать]
  1. Set entRef = doc2.ModelSpace.InsertBlock(conv1, strBlockName, 1, 1, 1, 0)

При этом блок вставляется в активный лист. А мне нужно во все листы. Возникают вопросы:
1. Какой командой активировать лист? Чтобы потом поместить блок командой Set entRef = doc2.PaperSpace.InsertBlock(conv1, strBlockName, 1, 1, 1, 0)
либо
2. Как вставить блок в конкретный лист? На Layuot не нашел команды InsertBlock

Заранее премного благодарен!
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 13-08-2014, 14:05:21
Если обращаться с CAD'ом через СОМ, то по свойству Layouts текущего документа можно получить перечень всех листов. А у каждого листа есть свойство Block. Думаю, что надо искать в этом направлении.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 13-08-2014, 14:25:10
Сначала немного теории (хотя вариант Алексея тоже вполне рабочий). Каждому листу соотвествует блок с именем вида *Paper_SpaceN:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F6829%2F7842324.1%2F0_e32dd_e88a3a63_orig.png&hash=79ae9a1a325c91a371a26dbf4a8d3862)
Т.е. можно пройтись по всем блокам, отобрать только те, имена которых соответствуют *Paper_SpaceN и выполнить blk.InsertBlock для них.
Если нужно только в конкретный лист, то тогда лучше идти по схеме Алексея, т.к. у каждого Layout есть свойство Name, по которому можно идентифицировать лист, ну а дальше по свойству Block находим блок в который и вставляем.
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 13-08-2014, 14:30:28
Одно "но": для пространства модели тоже есть свой Block. Так что это придется учитывать.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 13-08-2014, 14:35:54
На всякий случай создал тему:
Документация по ActiveX/COM модели AutoCAD (http://adn-cis.org/forum/index.php?topic=909.msg3891#msg3891)
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 13-08-2014, 16:22:39
Алексей Кулик и Александр Ривилис,  спасибо за подсказку.

Сделал так:
Код - Visual Basic [Выбрать]
  1. for each lay in doc2.Layouts
  2.     if lay.name <> "Модель" and lay.name <> "Model" then
  3.           Set entRef = lay.block.InsertBlock(conv1, strBlockName, 1, 1, 1, 0)
  4.      end if
  5.    next

Сработало.

Далее буду привязываться к форматам. Отпишу по результатам и вопросам. Спасибо!
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 13-08-2014, 18:18:43
Универсальнее (чтобы не зависеть от языка локализации AutoCAD) будет так:
Код - Visual Basic [Выбрать]
  1. for each lay in doc2.Layouts
  2.    if lay.Block.Name <> doc2.ModelSpace.Name then
  3.        Set entRef = lay.Block.InsertBlock(conv1, strBlockName, 1, 1, 1, 0)
  4.    end if
  5. next
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 13-08-2014, 21:16:08
Александр Ривилис, спасибо. Согласен.
Появились новые вопросы. Как разберусь - отпишу
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 14-08-2014, 10:42:08
Продолжение битвы.
Теперь занимаюсь поиском координат для вставки блока-подписи. Сразу скажу, что блок-подпись будет помещаться относительно блока-штампа (стандартный проектный штамп с должностями и фамилиями). Есть две идеи:


1. К примеру в блоке-штампе есть примитив "ГИП", если узнать его точку вставки (относительно начала координат всего чертежа, а не блока), то блок-подпись я помещу напротив примитива "ГИП" с небольшим шагом.
Вопрос: точку вставки примитива я определяю так:


Код - Visual Basic [Выбрать]
  1. coor = objBlock.item(1).InsertionPoint

Однако, выясняется, что это точка вставки относительно блока, а не начала координат чертежа.
Как определить точку вставки примитива в блоке относительно начала координат чертежа?

2. Если первая идея не реализуема, тогда:
Определить точку вставки блока, однако, и тут проблема: в методах AcadBlock я не нашел ничего похожего на InsertionPoint, зато есть Origin. Но Origin  дает всегда 0,0,0 (точка вставки блока-штампа не равна 0,0,0).  В справке AutocAD написано"Specifies the origin of the UCS, block, layout, or raster image in WCS coordinates" - я понимаю это как координаты точки вставки блока-штампа относительно начала координат чертежа, но Origin дает 0,0,0 в любом случае.

Как определить координаты точки вставки блока-штамп относительно начала координат чертежа? Только блок является AcadBlock, а не AcadBlockReference.


Заранее премного благодарен!
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 14-08-2014, 10:54:07
Примитива "ГИП" не существует в принципе. Скорее всего, это атрибут (точнее, AttrbuteReference). Соответственно надо смотреть его свойства.
Далее. Разберись с описанием блока и вхождением блока - разница принципиальная.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 14-08-2014, 11:16:01
Только блок является AcadBlock, а не AcadBlockReference.
AcadBlock - это описание блока, а AcadBlockReference - это вставка блока. В общем случае может быть несколько вставок блока для одного описания блока. Например, блоки-штампы на разных листах могут быть вставками одного и того-же блока. Между вставкой блока и его описанием есть взаимосвязь - имена совпадают. Если блок динамический, то все несколько сложнее.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 14-08-2014, 11:27:20
Примитива "ГИП" не существует в принципе. Скорее всего, это атрибут (точнее, AttrbuteReference).
А мне кажется, что это скорее или Text или MText -  так как это постоянный текст, то его делать атрибутом нелогично.
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 14-08-2014, 11:28:33
Может быть :) Вариантов масса.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 14-08-2014, 11:35:31
1. В моем случае это "ГИП" текст-примитив, а не атрибут. Он действительно постоянный и менять не нужно


2. Я понимаю что блок-штамп определяется один раз для всего чертежа (AcadBlock), а вставляться может несколько раз на разные листы - это AcadBlockReference.
В моем случае, проектировщик руками вставляет блок стандартным способом Вставка/Блок на листы, которые пожелает, при этом при обращении к блоку следующим образом:

Код - Visual Basic [Выбрать]
  1. Set objBlock = colBlocks.Item("Штамп")

у него не наблюдаю метода InsertionPoint.

Как обратиться к блоку-штампу на каждом листе? т.е. обратиться к блоку-штампу как к AcadBlockReference, к вставке блока, а не к его определению (говоря вашими словами).
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 14-08-2014, 13:09:22
2. Я понимаю что блок-штамп определяется один раз для всего чертежа (AcadBlock), а вставляться может несколько раз на разные листы - это AcadBlockReference.
Правильно.
В моем случае, проектировщик руками вставляет блок стандартным способом Вставка/Блок на листы, которые пожелает, при этом при обращении к блоку следующим образом:

Код - Visual Basic: [Выделить]

    Set objBlock = colBlocks.Item("Штамп")


у него не наблюдаю метода InsertionPoint.

Потому что ты обращаешься к описанию блока, а не к его вставке. Тебе уже не в первый раз об этом говорят.
Как обратиться к блоку-штампу на каждом листе? т.е. обратиться к блоку-штампу как к AcadBlockReference, к вставке блока, а не к его определению (говоря вашими словами).
Ты должен:
1) пройтись по всем листам (Layout), получить блоки для этих Loyout
2) пройтись по этим блокам и найти все AcadBlockReference, имена которых соотвествуют имени твоего блока-штампа и получить их InsertionPoint
3) А вот тут начинается самое интересное. Тебе нужно пересчитать координаты текста "ГИП" внутри твоего AcadBlock в координаты WCS с точкой вставки InsertionPoint для AcadBlockReference. В простейшем случае ничего пересчитывать не придется, если AcadBlock.Origin = (0,0,0) и AcadBlockReference не повернут и неотмасшабирован.

Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 14-08-2014, 13:34:23
Цитировать
1) пройтись по всем листам (Layout), получить блоки для этих Loyout

2) пройтись по этим блокам и найти все AcadBlockReference, имена которых соотвествуют имени твоего блока-штампа и получить их InsertionPoint
Как у конкретного листа Layout получить блоки? Через:


Код - Visual Basic [Выбрать]
  1. Layout.block

? Или как то еще?


Т.е. в этом то и вопрос как найти все блоки (вставки) листа ( AcadBlockReference )
Название: Re: Вставка блока из другого файла
Отправлено: Алексей Кулик от 14-08-2014, 13:49:16
Пройтись по всем элементам Layout.Block и выбрать блоки, имена которых соответствуют определенному критерию.
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 14-08-2014, 13:51:54
Как у конкретного листа Layout получить блоки? Через:


Код - Visual Basic: [Выделить]

    Layout.block


? Или как то еще?

Именно так.
Т.е. в этом то и вопрос как найти все блоки (вставки) листа и найти их AcadBlockReference
Внутри Layout.Block делаешь:
Код - Visual Basic [Выбрать]
  1. for each en in blk
  2.   if (en.ObjectName = "AcadBlockReference") then
  3.      ' здесь проверяем имя блока
  4.     Dim blkRef as BlockReference
  5.      set blkRef = en
  6.      if (blkRef.Name = "имя нашего блока") then
  7.        ' Тут уже можно получать точку вставки и искать "ГИП"'а
  8.     end if
  9.   end if
  10. end for
Код очень условный.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 14-08-2014, 14:14:00
Спасибо Вам! Я никак не мог догадаться обратиться к Block как к коллекции блоков AcDbBlockReference через for each.


Теперь буду прорабатывать этот момент:
Цитировать
3) А вот тут начинается самое интересное. Тебе нужно пересчитать координаты текста "ГИП" внутри твоего AcadBlock в координаты WCS с точкой вставки InsertionPoint для AcadBlockReference. В простейшем случае ничего пересчитывать не придется, если AcadBlock.Origin = (0,0,0) и AcadBlockReference не повернут и неотмасшабирован.
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 15-08-2014, 14:38:23
Результаты экспериментов с подключением к COM-объекту AutoCAD 2013 LT.
Дано: установлены AutoCAD 2014, AutoCAD 2014 VBA Enabler, AutoCAD 2013 LT
Ассоциация с файлами dwg привязана на
AutoCAD 2013 LT

Мои попытки:
Код - Visual Basic [Выбрать]
  1. Set AcadApp = CreateObject("C:\Program Files\Autodesk\AutoCAD LT 2013\acadlt.exe")
  2. Set AcadApp = CreateObject("C:\Program Files\Autodesk\AutoCAD LT 2013\acadlt.exe","AutoCAD.Application")
  3. Set AcadApp = CreateObject(,"AutoCAD.Application")
  4. Set AcadApp = CreateObject(,"AutoCAD.Application.**") '** - пробежал по вариантам: 17, 18, LT18, 18LT
  5. Set AcadApp = GetObject(,"AutoCAD.Application") ' при открытом AutoCAD 2013 LT
  6. Set AcadApp = GetObject(,"AutoCAD.Application.**") '** - пробежал по вариантам: 17, 18, LT18, 18LT


все варианты приводили к различным ошибкам: "Невозможно создание контейнером объекта ActiveX..."
На сторонних сайтах нашел следующую информацию:

http://www.cadtutor.net/forum/showthread.php?30446-vb-code-to-open-drawings-in-autocad-lt (http://www.cadtutor.net/forum/showthread.php?30446-vb-code-to-open-drawings-in-autocad-lt)
Цитировать
I do not believe the LT version can be accessed with VB in it's present state.
Цитировать
That's right. You have no COM interface in LT, so you have nothing like
Set acadLTApp = CreateObject("AutoCADLT.Application")


http://www.vbaexpress.com/forum/showthread.php?24269-Solved-How-to-control-AutoCad-LT-with-Visual-Basic-6 (http://www.vbaexpress.com/forum/showthread.php?24269-Solved-How-to-control-AutoCad-LT-with-Visual-Basic-6)
Цитировать
autocad LT do not support vb in its present version..this is the response i got from the autodesk customer support...
Цитировать
This is correct, you cannot control Autocad LT with the createobject/getobject methods. You can however write a script that will open Autocad LT and insert the drawing(s) that you want and close it.


Все это наводит на мысль, что я никак не смогу обратиться к COM-объекту AutoCAD 2013 LT версии.
Может есть какие идеи на этот счет?
Название: Re: Вставка блока из другого файла
Отправлено: Александр Ривилис от 16-08-2014, 16:06:15
Все это наводит на мысль, что я никак не смогу обратиться к COM-объекту AutoCAD 2013 LT версии.
Может есть какие идеи на этот счет?
Мысль абсолютно правильная. Всё что можно делать с LT я указал здесь: http://adn-cis.org/forum/index.php?topic=917.0


Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 16-08-2014, 17:24:26
Александр Ривилис, благодарю. Я как новичок не знал об этом. Поэтому и привел лишь результаты своих поисков по этой теме. Благодарю. Значит будем работать на полноценных версиях AutoCAD. Пока эксперименты провел на 14 версии. Планирую проверить на 12, и 15. По результатам отпишу!
Название: Re: Вставка блока из другого файла
Отправлено: art_rrc от 18-09-2014, 20:26:25
Я в своих программах использую следующий код собственного сочинения. Гуру СНГ программирования он покажется смешным, но для моих потребностей вполне хватает  :)
В программе:
Код - Visual Basic [Выбрать]
  1. On Error Resume Next
  2. Set NewBlock = .ModelSpace.InsertBlock(nPnt, nameBlock, 1, 1, 1, 0)
  3. If Err Then
  4.     Err.Clear
  5.     Call art_InsertBaseBlocks(nameBlock)
  6.     Set NewBlock = .ModelSpace.InsertBlock(nPnt, nameBlock, 1, 1, 1, 0)
  7. End If
  8.  
Сама процедура:
Код - Visual Basic [Выбрать]
  1. Public Sub art_InsertBaseBlocks(strName As String)
  2. Dim XRef As AcadExternalReference
  3. Dim insPnt(0 To 2) As Double
  4. Dim FileWay As String
  5. Dim objDel As AcadBlock
  6. Dim strDel As String
  7. With ThisDrawing
  8. insPnt(0) = 1#: insPnt(1) = 1#: insPnt(2) = 0#
  9. FileWay = "D:\All_For_Acad_2015\Acad_Blocks\Blocks.dwg"
  10. Set XRef = .ModelSpace.AttachExternalReference(FileWay,  "БазаДанныхБлоков", insPnt, 1, 1, 1, 0, False)
  11. .Blocks.Item(XRef.Name).Bind True
  12. XRef.Delete
  13. FileWay = "ВаляКоля"
  14. 'On Error Resume Next
  15. Set XRef = .ModelSpace.AttachExternalReference(FileWay, "Шило", insPnt, 1, 1, 1, 0, False)
  16. .Blocks.Item("БазаДанныхБлоков").Delete
  17. For Each objDel In .Blocks
  18.     strDel = objDel.Name
  19.     If strDel <> strName Then
  20.         .Blocks.Item(strDel).Delete
  21.     End If
  22. Next
  23. End With
  24. End Sub
Название: Re: Вставка блока из другого файла
Отправлено: Дамир от 18-09-2014, 20:34:31
Здорово! Спасибо. Моя проблема заключалась в том, что я пишу на VBS, а не на VBA. На основании чего столкнулся с массой проблем связанной с восприятием типов данных VBS'ом.