Перебор вхождений.

Автор Тема: Перебор вхождений.  (Прочитано 6812 раз)

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

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Перебор вхождений.
« : 22-05-2019, 14:57:01 »
Доброго времени суток, уважаемые форумчане, вновь ищу вашей помощи! Обычно стараюсь писать кратко, но сейчас, я даже толком не знаю, как сформулировать, что хочу.
Суть стоящей передо мной задачи такая: необходимо осуществить максимально быстрый перебор вхождений сборки, для получения спецификации.  Тонкость в том, что наиболее эффективный - перебор документов, мне не подходит, так как  мне необходимо игнорировать элементы, являющиеся частью сборочного узла. Ну то есть: я осуществляю перебор, дошел до сборки, дальше идет проверка, сборочный ли это узел (на него оформляется отдельный чертеж) и его массу берется целиком, или же сборку надо "расчленить" и посчитать отдельно. В общем понятно, что цели можно достичь обычным перебором вхождений с рекурсией, но мне хотелось бы сделать это более эффективно, так как у нас бывают огромные сборки.
Основная проблема в том, что у меня может быть 100 одинаковых вхождений внутри сборки, очень хотелось бы не перебирать их все, магическим образом сразу узнать их количество и игнорировать их в дальнейшем, то бишь вычеркнуть из перебираемой коллекции.
То есть вроде как суть задачи сводится к :
1. создать коллекцию вхождений
2. узнать как подсчитать количество конкретного вхождения
3. вычеркнуть все его копии, чтобы не перебирать в дальнейшем.
Буду благодарен за любую идею по поводу каждого из вопросов, либо альтернативного решения.

П.С. На форуме в нескольких топиках обсуждалась данная тема косвенно, но помочь мне найти они не смогли. Решил создать отдельный, надеюсь совместными усилиями, как всегда, решение будет найдено, и каждый им сможет воспользоваться в дальнейшем.
В программировании я новичок...но ненадолго! ;)

Оффлайн mikazakov

  • ADN
  • *
  • Сообщений: 751
  • Карма: 195
  • Skype: mikazakov@mail.ru
Re: Перебор вхождений.
« Ответ #1 : 22-05-2019, 16:06:47 »
так как у нас бывают огромные сборки.
На сколько большие?
Для работы используется AddIn или внешний exe-файл?

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #2 : 22-05-2019, 16:40:02 »
Для работы используется AddIn или внешний exe-файл?

Работать будет с помощью внешнего exe. До AddIn я еще не эволюционировал.

На сколько большие?

По-разному, ну всяких болтов с гайками тьма в рамках одной сборки, не библиотечных элементов ну штук по 100-200 может быть одинаковых. У нас мощное железо и справится с текущей задачей в приемлемое время. Просто я люблю думать, а потом делать. Сейчас 100 одинаковых деталей, а через пару лет может быть 1000, и все их перебирать нет смысла, если можно сделать иначе.
В программировании я новичок...но ненадолго! ;)

Оффлайн mikazakov

  • ADN
  • *
  • Сообщений: 751
  • Карма: 195
  • Skype: mikazakov@mail.ru
Re: Перебор вхождений.
« Ответ #3 : 22-05-2019, 16:56:23 »
Работать будет с помощью внешнего exe.
Вот потому и медленно работает рекурсия, и параллельные потоки нельзя запустить, потому как инвентор однопоточный

До AddIn я еще не эволюционировал.
Надо всё таки как то эволюционировать. Большие объёмы данных обязывают.

Может обратиться к ComponentDefinition.BOM чтоб как то по оптимальнее выудить данные

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #4 : 22-05-2019, 17:00:09 »
Перебор через AddIn раз в 30 быстрее. Несколько тысяч вхождений перебирает секунд за 20. Если хотите скорости, то прямая дорога к AddIn.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #5 : 22-05-2019, 17:25:44 »
Может обратиться к ComponentDefinition.BOM чтоб как то по оптимальнее выудить данные
Внутренним подсчетом материалов, предусмотренным инвентором пользоваться не планируется. Наша концепция построения спецификации изначально это исключает.
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #6 : 22-05-2019, 17:26:54 »
А если вернуться к моим вопросам, есть какие-то советы? Например можно ли определить количество вхождений элемента в данный уровень сборки (исключая подсборки)?
В программировании я новичок...но ненадолго! ;)

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #7 : 22-05-2019, 17:28:59 »
Количество вхождений компонента в сборке можно подсчитать данным правилом (iLogic):

Код - vb.net [Выбрать]
  1. Dim oAsmDoc As AssemblyDocument
  2. oAsmDoc = ThisApplication.ActiveDocument
  3.  
  4. Dim oAsmDef As AssemblyComponentDefinition
  5. oAsmDef = oAsmDoc.ComponentDefinition
  6.  
  7. Dim oDoc As Document
  8. oDoc = ThisApplication.Documents.ItemByName("D:\1.ipt")
  9.  
  10. Dim oOccs As ComponentOccurrencesEnumerator
  11. oOccs = oAsmDef.Occurrences.AllReferencedOccurrences(oDoc)
  12.  
  13. MessageBox.Show(oOccs.Count)

Конечно, всегда есть нюансы. Такой подсчет не учитывает состояний компонента, например, тип спецификации.

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #8 : 22-05-2019, 17:33:46 »
Если хотите исключать подсборки, то нужно обходить рекурсивно.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #9 : 22-05-2019, 18:05:44 »
Dim oOccs As ComponentOccurrencesEnumerator
oOccs = oAsmDef.Occurrences.AllReferencedOccurrences(oDoc)
MessageBox.Show(oOccs.Count)

Свойство Occurrences.AllReferencedOccurrences возвращает количество деталей на всех подуровнях, а мне необходимо узнать, сколько их конкретно в коллекции "Occurrences", т.е. на верхнем уровне сборки. В этом и есть основная сложность задачи. Ну то есть у меня есть деталь дважды вставленная в сборку, и дважды используемая в подсборке, которая является сборочным узлом и "потрошить" ее мне не надо. Мне надо каким-то образом получить цифру 2, вместо 4.
Спасибо.
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #10 : 22-05-2019, 18:33:28 »
Нашел свойство ComponentOccurrence.Joints не могу разобраться, что оно значит, не то ли это, что я искал? Быть может кто в курсе, как им пользоваться?
В программировании я новичок...но ненадолго! ;)

Оффлайн mikazakov

  • ADN
  • *
  • Сообщений: 751
  • Карма: 195
  • Skype: mikazakov@mail.ru
Re: Перебор вхождений.
« Ответ #11 : 22-05-2019, 18:58:45 »
ComponentOccurrence.Joints не могу разобраться, что оно значит
Это точно не то что надо, это привязки


Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #12 : 22-05-2019, 19:02:47 »
Это точно не то что надо, это привязки
Понял, спасибо, Михаил. Полезно однако бывает иметь английскую версию продукта ))

Подумал, может Occurrences.AllLeafOccurrences поможет, оказалось тоже не тем - возвращает коллекцию всех деталей сборки (включая детали из подсборок), но не возвращает сами сборки. Завис: не могу придумать, для какой задачи это вобще нужно?
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #13 : 22-05-2019, 19:20:34 »
Откопал неплохую статью по обсуждаемому нами вопросу, решил тоже бросить в топик, дабы в будущем кому-то пригодилось. Правда она на английском, ну а кто не владеет - гугл в помощь )))
https://modthemachine.typepad.com/my_weblog/2009/03/accessing-assembly-components.html
В программировании я новичок...но ненадолго! ;)

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #14 : 24-05-2019, 13:17:03 »
Продолжаю пытаться решить вопрос с перебором, но пока получается так себе. Вот, допустим, у меня в сборке всего три детали, все три одинаковые. Я осуществляю перебор по вхождениям. Дошел до первой, считал ее массу, сохранил где-то, записал количество "1". Не могу въехать, как, дойдя в переборе до второй (третьей детали) осуществить проверку, что данный элемент уже представлен, что не надо выделять ему новую позицию, а необходимо увеличить количество на один. Все варианты, которые возникают в моей голове, не кажутся мне работоспособными при наличии хотя бы 1000 вхождений в сборке. А если их 10 тыс, или 50? Буду рад любому совету.
В программировании я новичок...но ненадолго! ;)

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #15 : 24-05-2019, 13:47:54 »
Лично я это делаю так: сначала считаю элементы, потом произвожу обработку.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #16 : 24-05-2019, 13:49:25 »
Лично я это делаю так: сначала считаю элементы, потом произвожу обработку.
Каким образом вы их считаете?
В программировании я новичок...но ненадолго! ;)

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #17 : 24-05-2019, 14:08:38 »
В одном случае я использую рекурсивную функцию для получения состава изделия, а в другом считаю количество компонентов кодом, который представил в ответе №7. Все зависит от целей.

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #18 : 24-05-2019, 14:13:41 »
В одном случае я использую рекурсивную функцию для получения состава изделия...
Не могли бы пояснить, как вы осуществляете это?
... а в другом считаю количество компонентов кодом, который представил в ответе №7. Все зависит от целей.
Ответ №7 не подходит для нашей задачи, так как нам надо подсчитать вхождения данного уровня модели, а AllReferencedOccurrences считает на всех уровнях подсборок.
В программировании я новичок...но ненадолго! ;)

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #19 : 24-05-2019, 14:36:11 »
Если не надо заходить в подсборки, то данное правило (iLogic) поможет перебрать все компоненты на данном уровне. Если нужно зайти в подсборки, то нужно использовать рекурсию. Подсчитать элементы можно, например, просуммировав однотипные элементы.

Код - vb.net [Выбрать]
  1. Dim oAsmDoc As AssemblyDocument
  2. oAsmDoc = ThisApplication.ActiveDocument
  3.  
  4. Dim Occurrences As ComponentOccurrences
  5. Occurrences=oAsmDoc.ComponentDefinition.Occurrences
  6.  
  7. Dim oOcc As ComponentOccurrence
  8. For Each oOcc In Occurrences
  9. MessageBox.Show(oOcc.ReferencedDocumentDescriptor.ReferencedFileDescriptor.FullFileName)
  10. Next

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #20 : 24-05-2019, 15:14:32 »
Спасибо за ваш ответ. Но смотрите, например у меня 100 вхождение в сборке, все уникальные (то есть разные детали). Я перебрал уже 99, проверил, куда-то сохранил. Дошел до 100. Мне ведь необходимо 99 раз сравнить путь к файлу (ссылку на документ или имя - вариантов много), чтобы понять, что 100-ая деталь уникальна. Ну то есть для 100 деталей это не то чтобы большая проблема, а если их будет десятки тысяч? Ну я имею ввиду, что хочу найти какой-то более элегантный и быстрый способ. Мне почему-то казалось, что внутри программы уже должны была быть информация, сколько раз элемент представлен в коллекции Occurrences текущего уровня модели, чтобы не считать его количество, а сразу взять итоговое число. 
В программировании я новичок...но ненадолго! ;)

Оффлайн xzenter

  • ADN OPEN
  • Сообщений: 29
  • Карма: 1
    • xzenter.com
  • Skype: xzenter
Re: Перебор вхождений.
« Ответ #21 : 24-05-2019, 15:38:57 »
Возможно, эту информацию можно вытянуть из представления BOM сборки. В свое время от этого варианта отказался, так как работаю с разными уровнями детализации, а в этом случае в BOM отображается некорректное количество.

Оффлайн mikazakov

  • ADN
  • *
  • Сообщений: 751
  • Карма: 195
  • Skype: mikazakov@mail.ru
Re: Перебор вхождений.
« Ответ #22 : 24-05-2019, 16:21:48 »
Ну я имею ввиду, что хочу найти какой-то более элегантный и быстрый способ.
Может при событии сохранения сборок просто вписывать нужные данные в атрибуты о самой сборке. А потом не шерстить эту сборку, а просто считать уже готовые данные.
Ну и всё таки AddIn в помощь

Оффлайн R.I.ChernovАвтор темы

  • ADN Club
  • *****
  • Сообщений: 565
  • Карма: 18
Re: Перебор вхождений.
« Ответ #23 : 24-05-2019, 16:37:03 »
Может при событии сохранения сборок просто вписывать нужные данные в атрибуты о самой сборке. А потом не шерстить эту сборку, а просто считать уже готовые данные.
Идея интересная, только у нас сборки обычно являются сборочными узлами: то есть на них делается чертеж. Соответственно при оформлении узла из нескольких сборок, программа будет распознавать, что внутрь подсборок лезть не надо, и будет определять их как 1 позицию с общей массой и ссылкой на номер чертежа. А вот для оформления "сборочных чертежей" нужна будет информация по вхождениям в них. Конечно, при построении изделия можно научить программу записывать данные внутрь атрибутов, сборки, как вы и посоветовали, но это может повлечь ошибки. Всегда ведь есть вероятность, что программа не сможет сделать узел необходимой итоговой конфигурации, и придется что-то добавить руками, тогда информация внутри атрибутов станет некорректной.

у и всё таки AddIn в помощь.
Храню это вариант как джокер )
В программировании я новичок...но ненадолго! ;)