Чтобы преодолеть трение покоя, первые страхи и осознать, что у вас буквально под рукой находится весьма любопытный инструмент, попробуем создать в среде Инвентора первую полезную программу.


Описание задачи править

Рассмотрим программу, которая выделенный пользователем компонент фиксирует в координатах сборки тремя зависимостями совмещения заподлицо одноименных базовых плоскостей XY, YZ и XZ компонента и сборки. Такая привязка компонентов характерна для каркасного проектирования, где ее автоматизация может сэкономить конструктору немало времени.

Эта маленькая программа называется Flush_XYZ, ее полный текст приведен в конце раздела.


Сначала мы попробуем Flush_XYZ в работе, а затем проведем подробный пошаговый анализ ее текста и выполняемых действий.

Ввод текста VBA программы править

Первым делом следует подготовить исходный текст программы к исполнению в среде VBA.

Интегрированная среда разработки VBA активируется нажатием клавиш ALt-F11. Слева в окне Project отображается браузер объектов. Следует найти там программный модуль с именем Module1. Раскройте его двойным кликом на имени модуля. Изначально модуль пуст, никакого текста он еще не содержит. Окно справа предназначено для программных текстов.

 


В окне для программных текстов в первой строке наберите Option Explicit. Эта инструкция задает режим явного объявления всех переменных программы. Настоятельно рекомендую работать именно в этом режиме.

Чтобы среда VBA использовала этот режим по умолчанию, в диалоге настроек 'Options' следует поставить галочку, как показано на рисунке ниже.

 


Следующим шагом методом Copy/Paste скопируйте и вставьте в модуль полный текст процедуры Flush_XYZ.

 

Сохраните измененный проект командой Ctrl-S.

Подготовка компонентов сборки править

Перейдите в окно Инвентора, создайте несколько деталей Part1, Part2, … и новую сборку. Файлы деталей следует сохранить на диске, а затем вставить в сборку в произвольных местах. Первая деталь автоматически ориентируется в сборке (Grounded) совмещением координатных систем детали и сборки.

Вот теперь все готово, чтобы опробовать Flush_XYZ в деле.

Запуск макроса править

Сначала выделите в сборке любую деталь кроме первой, а потом запустите на выполнение макрос Flush_XYZ.

Для запуска VBA макросов в среде Инвентора предназначен диалог 'Macros’, открываемый нажатием клавиш Alt-F8. Диалог выглядит следующим образом:

 

Примечание: Если окно ‘Macro name’ окажется пустым, то выберите нужный модуль из списка в строке ‘Macros in:’.


Итак, деталь выделена, курсор стоит на имени макроса. Нажимаем кнопку Run, макрос выполняеь свою работу, и деталь встает на положенное ей место


Взаимная ориентация компонентов до запуска макроса:

 


Взаимная ориентация компонентов после запуска макроса:

 


Отмените операцию и попробуйте наложить те же зависимости вручную, сравнив затраченное время. А теперь представьте что таких вставок требуется сделать сотни… Да и вообще, приятно, когда Инвентор делает полезную работу сам.



Разбор полетов править

Рассмотрим теперь, что происходило за сценой и чему мы обязаны этим праздником жизни.

Первые несколько строк являются комментариями. Ими считаются любой текст после знака ' . Они игнорируются при исполнении команд, предназначены для читателей текста, т.е. для программистов, и чрезвычайно полезны, когда нужно понять логику алгоритма и внести в программу какие-либо изменения.

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'                 Flush_XYZ
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Выделенный пользователем компонент фиксируется
'в координатах сборки наложением трех зависимостей
'совмещения заподлицо одноименных базовых
'плоскостей XY, YZ и XZ сборки и компонента
'
'Процедура работает в контексте сборки.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Следующие строки начинают и завершают процедуру (Sub) с именем Flush_XYZ без аргументов, о чем свидетельствуют пустые скобки. Весь текст между этими строками является собственно текстом макроса. Макросом в VBA называется глобальная процедура (Public Sub) без аргументов (с пустыми скобками).

Public Sub Flush_XYZ()
    ………………
    ………………
    ………………
End Sub   ' Flush_XYZ


Первая группа команд, начинающихся с Dim (от англ. dimension — размерность), объявляет все нужные программе переменные и их типы.

Dim oApp        As Inventor.Application        'приложение Inventor
Dim oAsmCompDef As AssemblyComponentDefinition 'сборка
Dim oCompOcc    As ComponentOccurrence         'компонент
Dim oSelectSet  As SelectSet

Переменная oApp будет хранить указатель (ссылку) на активное приложение Inventor, объект типа Application. После инициализации oApp обеспечит нам доступ к такому важному объекту как документ активной сборки и его компонентам.

Переменная oAsmCompDef предназначена для хранения ссылки на определение компонентов активной сборки.

Переменная oCompOcc предназначена для получения доступа к определениям компонентов ориентируемой детали, ее базовых рабочих плоскостей, в частности.

Переменная oSelectSet предназначена для получения доступа к элементам коллекции SelectSet активной сборки, т.к. к выделенному компоненту.

Следующие три декларации объявляют переменные, посредством которых мы будем оперировать рабочими плоскостями сборки и детали.

Dim oAsmPlane       As WorkPlane      'рабочие плоскости сборки
Dim oPartPlane      As WorkPlane      'рабочие плоскости детали
Dim oPartPlaneProxy As WorkPlaneProxy 'proxy-плоскости детали

Последним объявляется счетчик циклов i:

Dim i As Long  'счетчик плоскостей 1,2,3


Далее идут исполняемые команды.

Первым делом получим ссылку на активное приложение INVENTOR и сохраним его в переменной oApp:

Set oApp = ThisApplication


Далее важный элемент работы программы — следует провериться, а в контексте ли сборки запускает пользователь наш макрос? Если нет, то выводится соответствующее уведомление и работа макроса завершается.

   'Проверка: а в сборке ли мы?
   If oApp.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then
       MsgBox "Процедура предназначена для работы в контексте сборки."
       Exit Sub
   End If

Если исполнение программы продвинулось дальше, значит активным документом действительно является сборка, и мы можем создать объект oAsmCompDef, в котором сохраняем определение компонентов активной сборки.

   Set oAsmCompDef = oApp.ActiveDocument.ComponentDefinition

Теперь самое время узнать, что же выделил (если выделил) в сборке пользователь. Для этого требуется получить доступ к коллекции выделенных объектов SelectSet активной сборки. В программе это делается с помощью переменной oSelectSet:

   'Ссылка на коллекцию SelectSet активного документа
   Set oSelectSet = oApp.ActiveDocument.SelectSet


Далее в программе следуют две обязательных проверки. Первая проверяет, что выделен только один компонент, а вторая — что выделен именно компонент, а не что-либо иное (например, рабочая плоскость). Если хотя бы одно условие не выполнено, то выполнение макроса завершается с выводом пользователю соответствующего сообщения.

   'Проверка: должен быть выделен один и только один элемент
   If oSelectSet.Count <> 1 Then
       MsgBox "Следует выделить один компонент."
       Exit Sub
   End If
   
   'Проверка: должен быть выделен именно компонент
   If Not (TypeOf oSelectSet.Item(1) Is ComponentOccurrence) Then
       MsgBox "Следует выделить один компонент."
       Exit Sub
   End If


Следующий фрагмент кода получает ссылку на выделенный пользователем компонент сборки.

   'ссылка на выделенный компонент (деталь)
   Set oCompOcc = oSelectSet.Item(1)


Далее в программе мы встречаем интересную конструкцию — пример работы с транзакциями. Здесь формируется транзакция с именем "Привязка_XYZ". Все действия, выполненные программой внутри блока между командами StartTransaction и End могут быть отменены за один шаг Undo.

   'Инициализация транзакции для возможной отмены за один шаг
   Dim oConstrTransaction As Transaction
   Set oConstrTransaction = oApp.TransactionManager. _
            StartTransaction(oApp.ActiveDocument, "Привязка_XYZ")
      …………………………
      …………………………
      …………………………
      …………………………
      …………………………
   oConstrTransaction.End 'завершение транзакции


И наконец, мы подошли к самому главному, тому, ради чего программа и была создана — к привязке выделенного компонента oCompOcc к системе координат сборки наложением трех зависимостей совмещения заподлицо одноименных базовых плоскостей XY, YZ и XZ сборки и компонента.

   'Совмещаем в цикле базовые плоскости сборки и компонента.
   
   ' i=1:   плоскость YZ,   нормаль - ось X
   ' i=2:   плоскость ZX,   нормаль - ось Y
   ' i=3:   плоскость XY,   нормаль - ось Z
   
   For i = 1 To 3
   
      'ссылка на базовую плоскость i сборки
      Set oAsmPlane = oAsmCompDef.WorkPlanes.Item(i)
         
      'ссылка на базовую плоскость i выделенного компонента
      Set oPartPlane = oCompOcc.Definition.WorkPlanes.Item(i)
         
      'создаем прокси-объект рабочей плоскости компонента
      Call oCompOcc.CreateGeometryProxy(oPartPlane, oPartPlaneProxy)
         
      'создаем зависимость совмещения рабочих плоскостей типа "Заподлицо"
      'плоскости сборки и прокси-объекта плоскости компонента
      Call oAsmCompDef.Constraints.AddFlushConstraint( _
                          oAsmPlane, oPartPlaneProxy, 0)
   
   Next i

Для каждой из трех базовых плоскостей сборки выполняется однотипная последовательность операций, завершающихся созданием зависимости типа FlushConstraint (заподлицо). Сборка oAsmCompDef имеет свойство Constraints — ссылку на коллекцию всех сборочных зависимостей. Метод AddFlushConstraint(oAsmPlane, oPartPlaneProxy, 0) дополняет эту коллекцию новой зависимостью совмещения заподлицо для двух плоскостей oAsmPlane сборки и oPartPlaneProxy компонента. Третий аргумент означает отсутствие смещения — нулевое расстояние между указанными плоскостями.

Самым любопытным в данном фрагменте является то, что совмещение плоскости сборки производится не с «родной» плоскостью детали, а с ее прокси-объектом, т.к. именно

прокси-объекты описывают положение компонента в сборке.

Полный текст процедуры Flush_XYZ править

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'                 Flush_XYZ
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Выделенный пользователем компонент фиксируется
'в координатах сборки наложением трех зависимостей
'совмещения заподлицо одноименных базовых
'плоскостей XY, YZ и XZ сборки и компонента
'
'Процедура работает в контексте сборки.
'Автор: Владимир Ананьев, 2007                 
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
Public Sub Flush_XYZ()
 
   Dim oApp        As Inventor.Application        'приложение Inventor
   Dim oAsmCompDef As AssemblyComponentDefinition 'сборка
   Dim oCompOcc    As ComponentOccurrence         'компонент
   Dim oSelectSet  As SelectSet
 
   Dim oAsmPlane       As WorkPlane      'рабочие плоскости сборки
   Dim oPartPlane      As WorkPlane      'рабочие плоскости детали
   Dim oPartPlaneProxy As WorkPlaneProxy 'proxy-плоскости детали
 
   Dim i As Long  'счетчик плоскостей 1,2,3
 
   ' Получим ссылку на активное приложение INVENTOR
   Set oApp = ThisApplication
 
   'Проверка: а в сборке ли мы?
   If oApp.ActiveDocument.DocumentType <> kAssemblyDocumentObject Then
       MsgBox "Процедура предназначена для работы в контексте сборки."
       Exit Sub
   End If
   
   'Получим ссылку на определение компонентов активной сборки
   Set oAsmCompDef = oApp.ActiveDocument.ComponentDefinition
 
   'Ссылка на коллекцию SelectSet активного документа
   Set oSelectSet = oApp.ActiveDocument.SelectSet
 
   'Проверка: должен быть выделен один и только один элемент
   If oSelectSet.Count <> 1 Then
       MsgBox "Следует выделить один компонент."
       Exit Sub
   End If
 
   'Проверка: должен быть выделен именно компонент
   If Not (TypeOf oSelectSet.Item(1) Is ComponentOccurrence) Then
       MsgBox "Следует выделить один компонент."
       Exit Sub
   End If
 
   'ссылка на выделенный компонент (деталь)
   Set oCompOcc = oSelectSet.Item(1)
 
   'Инициализация транзакции для возможной отмены за один шаг
   Dim oConstrTransaction As Transaction
   Set oConstrTransaction = oApp.TransactionManager. _
            StartTransaction(oApp.ActiveDocument, "Привязка_XYZ")
 
 
   'Совмещаем в цикле базовые плоскости сборки и компонента.
 
   ' i=1:   плоскость YZ,   нормаль - ось X
   ' i=2:   плоскость ZX,   нормаль - ось Y
   ' i=3:   плоскость XY,   нормаль - ось Z
 
   For i = 1 To 3
 
      'ссылка на базовую плоскость i сборки
      Set oAsmPlane = oAsmCompDef.WorkPlanes.Item(i)
 
      'ссылка на базовую плоскость i выделенного компонента
      Set oPartPlane = oCompOcc.Definition.WorkPlanes.Item(i)
 
      'создаем прокси-объект рабочей плоскости компонента
      Call oCompOcc.CreateGeometryProxy(oPartPlane, oPartPlaneProxy)
 
      'создаем зависимость совмещения рабочих плоскостей типа "Заподлицо"
      'плоскости сборки и прокси-объекта плоскости компонента
      Call oAsmCompDef.Constraints.AddFlushConstraint(oAsmPlane, oPartPlaneProxy, 0)
 
   Next i
 
   oConstrTransaction.End 'завершение транзакции
 
End Sub   ' Flush_XYZ