Определение количества определенных вхождений

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

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

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Добрый день! Подскажите пожалуйста, есть сборка, в ней 10 одинаковых болтов (1 документ болта, 10 вхождений) Как не перебирая все вхождения сборки определить сколько раз этот болт используется в этой сборке?
P.S. При этом не учитывая, если какие-то болты погашены.

Отмечено как Решение Павел Тер-Микаэлян 13-03-2015, 15:51:04

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
Есть волшебное средство!
У коллекции всех компонентов есть хитрое свойство ComponentOccurrences.AllReferencedOccurrences( Object As Object ).

Dim oOccsEnum As ComponentOccurrencesEnumerator
Set oOccsEnum = oAsmDoc.ComponentDefinition.Occurrences.AllReferencedOccurrences(oDoc)

Оно возвращает список компонентов, которые порождены указанным в аргументе объектом. 
Варианты объектов-родителей:
•   DocumentDescriptor
•   ComponentDefinition
•   Document object

Таким образом, вы получите не только количество компонентов, но и ссылки на каждый из них.  Положение компонентов в иерархии сборки роли не играет.
Свойство видимости здесь, думаю, тоже не учитывается.
А вот считает ли эта механика подавленные (suppressed) компоненты, надо будет вам протестировать специально.

Есть тяжеловесная альтернатива – извлекать количества из BOM. 

Успехов!

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Спасибо большое))) а я совсем не обратил внимание что у AllReferencedOccurrences аж три варианта объектов родителей)) Кстати, потестировал, подавленные компоненты в  AllReferencedOccurrences(oDoc).Count не учитываются, что замечательно для формирования спецификаций)

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
Я тоже разглядел эту фичу далеко не сразу :).  Полезнейшая штука, надо признать.
Заметьте, что можно "коллекционировать" и виртуальные компоненты, если подставить в качестве аргумента объект типа VirtualComponentDefinition.

То, что игнорирует подавленные компоненты - ожидаемо.  Спасибо за тест!

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Вам спасибо за ответ)

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Заметьте, что можно "коллекционировать" и виртуальные компоненты, если подставить в качестве аргумента объект типа VirtualComponentDefinition.
Кстати, попытался получить коллекцию виртуальных компонентов, но он их не видит в таком переборе For Each occ In oCompDef.Occurrences.AllReferencedOccurrences(VirtualComponentDefinition)

Оффлайн R.I.Chernov

  • ADN Club
  • *****
  • Сообщений: 568
  • Карма: 18
Доброго времени суток. Не могли бы помочь с таким вот вопросом:
При использовании обсуждаемого нами метода, обнаружил, что если аргументом ComponentOccurrences.AllReferencedOccurrences является виртуальный компонент (вставленный в главную сборку или в любую из подсборок), то свойство возвращает все вхождения данной сборки. Да и вобще с виртуальными компонентами данный перебор работает как-то некорректно.
В программировании я новичок...но ненадолго! ;)

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
Действительно, с AllReferencedOccurrences у меня тот же результат :(
Если у вас уже есть ссылка на какой-либо виртуальный компонент в конкретной сборке (скажем, он выделен юзером), то можно получить коллекцию всех её виртуальных компонентов через свойство AllLeafOccurrences():
Set oOccsEnum = oAsmDoc.ComponentDefinition.Occurrences.AllLeafOccurrences(oVirtualDef)Здесь oVirtualDef – определение выделенного виртуального компонента.

НО
Наиболее полная информация о компонентах содержится в BOM.  В частности, у виртуальных компонентов, вполне вероятно, могут быть переопределены количества.  Если они нужны,  деваться некуда, придется открывать BOM. 

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

Приведенный ниже код демонстрирует один из вариантов поиска виртуальных компонентов на всех уровнях иерархии активной данный момент сборки.  Это слегка модифицированный пример «Traverse an Assembly API Sample» из хелпа.  Имена найденных виртуальных компонентов выводятся в отладочное окно VBA.

Код - Visual Basic [Выбрать]
  1. Public Sub VirtualComponentCount()
  2.     ' Set reference to active document.
  3.    ' This assumes the active document is an assembly
  4.    Dim oDoc As Inventor.AssemblyDocument
  5.     Set oDoc = ThisApplication.ActiveDocument
  6.    
  7.     ' Get assembly component definition
  8.    Dim oCompDef As Inventor.ComponentDefinition
  9.     Set oCompDef = oDoc.ComponentDefinition
  10.  
  11.     Dim sMsg As String
  12.     Dim iLeafNodes As Long
  13.     Dim iSubAssemblies As Long
  14.    
  15.     Debug.Print "--------------------------------"
  16.     Debug.Print "  Top Level Assembly: " & oDoc.DisplayName
  17.     Debug.Print "--------------------------------"
  18.  
  19.     ' Get all occurrences from component definition for Assembly document
  20.    Dim oCompOcc As ComponentOccurrence
  21.     For Each oCompOcc In oCompDef.Occurrences
  22.         ' Check if it's child occurrence (leaf node)
  23.        If (Not oCompOcc.IsSubstituteOccurrence) And _
  24.                     (Not oCompOcc.Suppressed) Then
  25.             If oCompOcc.SubOccurrences.Count = 0 Then
  26.                 If TypeOf oCompOcc.Definition Is VirtualComponentDefinition Then
  27.                     Debug.Print oCompOcc.Name
  28.                     iLeafNodes = iLeafNodes + 1
  29.                 End If
  30.             Else
  31.                 Debug.Print "----------"
  32.                 Debug.Print "  SubAssembly: " & oCompOcc.Name
  33.                 Debug.Print "----------"
  34.                 iSubAssemblies = iSubAssemblies + 1
  35.                 Call processAllSubOcc(oCompOcc, _
  36.                                     sMsg, _
  37.                                     iLeafNodes, _
  38.                                     iSubAssemblies) ' subassembly
  39.            End If
  40.         End If
  41.     Next
  42.     Debug.Print "--------"
  43.     Debug.Print "No of virtual components: " + CStr(iLeafNodes)
  44.     Debug.Print "No of sub assemblies:     " + CStr(iSubAssemblies)
  45. End Sub
  46.  
  47. ' This function is called for processing sub assembly.  It is called recursively
  48. ' to iterate through the entire assembly tree.
  49. Private Sub processAllSubOcc(ByVal oCompOcc As ComponentOccurrence, _
  50.                              ByRef sMsg As String, _
  51.                              ByRef iLeafNodes As Long, _
  52.                              ByRef iSubAssemblies As Long)
  53.    
  54.     Dim oSubCompOcc As ComponentOccurrence
  55.     For Each oSubCompOcc In oCompOcc.SubOccurrences
  56.         ' Check if it's child occurrence (leaf node)
  57.        If (Not oSubCompOcc.IsSubstituteOccurrence) And _
  58.                    (Not oSubCompOcc.Suppressed) Then
  59.             If oSubCompOcc.SubOccurrences.Count = 0 Then
  60.                 If TypeOf oSubCompOcc.Definition Is VirtualComponentDefinition Then
  61.                     Debug.Print oSubCompOcc.Name
  62.                     iLeafNodes = iLeafNodes + 1
  63.                 End If
  64.             Else
  65.                 sMsg = sMsg + oSubCompOcc.Name + vbCr
  66.                 iSubAssemblies = iSubAssemblies + 1
  67.    
  68.                 Call processAllSubOcc(oSubCompOcc, _
  69.                                       sMsg, _
  70.                                       iLeafNodes, _
  71.                                       iSubAssemblies)
  72.             End If
  73.         End If
  74.     Next
  75.     Beep
  76. End Sub
Такая вот история с географией …
« Последнее редактирование: 16-03-2015, 16:17:45 от Александр Ривилис »

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Спасибо за ответ! Только я уже в какой раз не понимаю, почему в справке делают перебор всех компонентов через рекурсию, определяя саб компоненты, если на это тратится огромное количество времени? На 700 вхождений 20 секунд, на 70 000, соответственно, пол часа. Имеет же смысл перебирать только документы:
Код - Visual Basic [Выбрать]
  1. Dim oCompDef As AssemblyComponentDefinition
  2. Set oCompDef = ThisApplication.ActiveDocument.ComponentDefinition
  3. Dim occ As ComponentOccurrence
  4. Dim occ2 As ComponentOccurrence
  5. Dim odoc As Document
  6.  
  7. 'поиск виртуальных вхождений
  8. 'в главной сборке
  9. For Each occ In oCompDef.Occurrences
  10.       If occ.Suppressed = False Then
  11.            If TypeOf occ.Definition Is VirtualComponentDefinition Then
  12.                  Debug.Print occ.Name
  13.            End If
  14.       End If
  15. Next
  16. 'в подсборках
  17. For Each odoc In oCompDef.Document.AllReferencedDocuments
  18.         Set occ = oCompDef.Occurrences.AllReferencedOccurrences(odoc).Item(1)
  19.         If occ.DefinitionDocumentType = kAssemblyDocumentObject Then
  20.               For Each occ2 In occ.Definition.Occurrences
  21.                     If occ2.Suppressed = False Then
  22.                           If TypeOf occ2.Definition Is VirtualComponentDefinition Then
  23.                               Debug.Print occ2.Name
  24.                           End If
  25.                      End If
  26.               Next
  27.         End If
  28. Next
  29.  
« Последнее редактирование: 17-03-2015, 16:35:38 от Pabloa »

Оффлайн Владимир Ананьев

  • ADN DevHelp
  • *
  • Сообщений: 148
  • Карма: 8
Хорошее замечение.  Ваш вариант для поиска виртуальных компонентов годится
(если только нет деталей подстановок).  Можно даже чуть упростить - в цикле по подсборкам объект осс не нужен.  Достаточно иметь сам документ odoc.

Что касается методов, то, как обычно по жизни, для разных целей - разные методы...

Оффлайн Павел Тер-МикаэлянАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 124
  • Карма: 5
Что касается методов, то, как обычно по жизни, для разных целей - разные методы...
Это точно) нет правильного, есть более оптимальное)) Спасибо за очередные консультации))