Получение исполнений детали с помощью API5/API7

Автор Валерий Изранов, 23.07.19, 16:17:44

« назад - далее »

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

Вират Лакх

Цитата: Валерий Изранов от 29.07.19, 06:19:00
# должен быть открыт Компас
print iEmbodimentsManager.SetCurrentEmbodiment(1)            # сделать текущим  исполнение 1
print iEmbodimentsManager.SetEmbodimentMarking( 1, 2, '900')         # у исполнения 1 в окончании  записать 900
Спасибо ему.
Для справки:
1) Если компас не открыт, Dispatch запускает его в невидимом режиме.
2) В SetEmbodimentMarking вы же указываете, какому исполнению задать обозначение. Следовательно, не обязательно делать его текущим с помощью SetCurrentEmbodiment.
3) Если в СДК написано ksVMEmbodimentNumber 0x2 Исполнение, то лучше так и пишите 0x2 (шестнадцатеричный формат) во избежание каких-либо непоняток.
4) И для чего в коде осталось API5 (всё остальное после SetEmbodimentMarking) - не понятно. Питон очень медленно работает с компасом, и сам по себе, говорят, медленный. Поэтому для лучшего быстродействия нужно в коде минимум обращений к интерфейсам компаса и, вообще, хлам всякий убирать. И читаемость будет лучше.
5) Для спасибо есть специальные ссылочки "Поблагодарить" у каждого сообщения и "повысить" рядом с репутацией.
+ Благодарностей: 1

Валерий Изранов

Согласен со всем вышенаписанным.
Но у меня есть маленькая беденка (от слова беда).
Я настолько привык в VB6 писАть по русски имена переменных и перейти на Python с его "исключительно английским"   не смогу.
В VB6 у меня работает все, что мне нужно. кроме IEmbodimentsManager и TransferInterface.
Думаю, как в родной VB6 вставить кусочек исполнимого кода для обработки этих команд.
Или как то по другому...

Вират Лакх

https://forum.ascon.ru/index.php/topic,31101.msg247593.html#msg247593
Я пишу на 2.7 для совместимости, а вы можете этот удалить и поставить самую новую версию 3.x для использования русских переменных. Или, если оставаться на vb, то искать генератор модулей, про что я написал выше. Или найти готовый модуль.
+ Благодарностей: 1

Vi2

Dim obj7 As KompasAPI7.IApplication
Dim doc7 As KompasAPI7.IKompasDocument

Dim embmgr As KompasAPI7.IEmbodimentsManager

    Set obj7 = GetObject(, "Kompas.Application.7")
    Set doc7 = obj7.ActiveDocument
   
    Set embmgr = doc7
    Debug.Print embmgr.EmbodimentCount

Или с использованием 5 и 7 версий

Dim obj5 As Kompas6API5.Application, obj7 As KompasAPI7.IApplication
Dim doc5 As Kompas6API5.Document3D, doc7 As KompasAPI7.IKompasDocument

Dim emb As KompasAPI7.IEmbodimentsManager

    Set obj5 = GetObject(, "Kompas.Application.5")
    Set obj7 = obj5.ksGetApplication7

    Set doc5 = obj5.ActiveDocument3D
    Set doc7 = obj7.ActiveDocument 'или так Set doc7 = obj5.TransferInterface(doc5, ksAPI7Dual, 0)

    Set emb = doc7
    Debug.Print emb.EmbodimentCount
+ Благодарностей: 1

Валерий Изранов

Vi2, спасибо за участие.

Верхние 3 строки пришлось изменить так:
Dim obj7 As Object                                            'KompasAPI7.IApplication
Dim doc7 As Object                                           'KompasAPI7.IKompasDocument

Dim embmgr As Object                                      'KompasAPI7.IEmbodimentsManager

потому что VB6 не знает типов данных, указанных выше в комментариях.

После этого при выполнении этой программы в строке вывелась ошибка
Debug.Print embmgr.EmbodimentCount            '438-объект не поддерживает это свойство или метод

Буду рад дальнейшему обсуждению.

Vi2

Цитата: Валерий Изранов от 31.07.19, 08:37:04
потому что VB6 не знает типов данных, указанных выше в комментариях.

Буду рад дальнейшему обсуждению.
Так добавь в References или в Object Browser (F2). Иначе ты доступ к интерфейсу IEmbodimentsManager не получишь, т.к. он и документ, у которого его нужно получать по QueryInterface, оба имеют IDispatch интерфейс.

IEmbodimentsManager : IDispatch
IAssemblyDocument : IKompasDocument3D : IKompasDocument : IKompasAPIObject : IDispatch

Так что это бага в проектировании. По-хорошему, либо интерфейсы нужно разделять, либо IDispatch (это VBшный Object) должен отрабатывать все методы объекта.

PS
Можно было бы использовать TransferInterface, но я не видел соответствующего параметра для IEmbodimentsManager.

Валерий Изранов


Валерий Изранов

Vi2, сознаюсь: я не знаю как в VB6 добавить в References или в Object Browser (F2) новый тип данных.
И для чего это нужно.

Vi2

Цитата: Валерий Изранов от 31.07.19, 21:26:13
Vi2, сознаюсь: я не знаю как в VB6 добавить в References или в Object Browser (F2) новый тип данных.
И для чего это нужно.
Таким образом добавляются новые библиотеки типа. Находишь в меню «Project» пункт «Reference...» или нажимаешь F2, появляется окно Object Browser, в котором по правой кнопке мышки вызывается меню, в котором тоже есть пункт «Reference...». Жмакаешь на него. Появится окно добавления этих самых Reference. Находишь относящиеся к Компас, в которых определены те или иные данные ,которые тебе нужны в работе. У меня, например, Kompas6API5, KompasAPI7, Kompas6Constants и Kompas6Constants3D. Отмечаешь галочкой выбора и нажимаешь ОК. Теперь у тебя доступны интерфейсы в явном виде, т.е. вместо Object можно (или нужно) использовать реальный тип.

Это в дальнейшем поможет цепляться и к событиям Компаса.
+ Благодарностей: 2

Валерий Изранов

Vi2, это была шикарная подсказка.
Сегодня кратко скомпоную нашу переписку и завтра выложу "для идущих сзади".
ОК?
Глупенький вопрос - приходилось ли видеть отключение запросов с помощью
Kompas7.HideMessage = 0 при работе с деталями и сборками? У меня не отключает.

SDK почитайте.
ksShowMessage - 0 - Показывать все сообщения и диалоги;
ksHideMessageYes - 1- Скрывать сообщения и диалоги с выбором ОК или Да, если сообщение или диалог предусма­тривают такой выбор, с перестроением доку­мента;
ksHideMessageNo - 2 - Скрывать сообщения с ОК, если имеется толь­ко кнопка ОК, сообщения и диалоги с выбором Нет, если сообщение или диалог предусматри­вают такой выбор, без перестроения документа.


Валерий Изранов

Не 0 не1 не 2 и даже 3 у меня не  отключают при работе с деталями и сборками

У меня, четко работает, не на VB, но и числовые значения, я, не применяю, всегда оригинальное имя значения, значение может поменяться, а имя нет.

Валерий Изранов

Вот так можно получить исполнения детали при работе на VB6.

1.Запуститите  VB6.
2. В меню выберите «Проект», пункт «Информация...» в русифицированном VB6.
3. С левой стороны у строк
Kompas6API5,
KompasAPI7,
Kompas6Constants,
Kompas6Constants3D
поставьте галочки и нажмите ОК.

'должен быть открыт Компас
'должна быть открыта деталь с исполнениями
'проверка проводилась на VB6

Запустите эту программу в режиме пошагового выполнения.

Dim Kompas7 As KompasAPI7.IApplication
Dim Document7 As KompasAPI7.IKompasDocument
Dim embmgr As KompasAPI7.IEmbodimentsManager

Dim Kompas5 As Kompas6API5.Application
Dim Document5 As Kompas6API5.Document3D

Dim КоличествоИсполнений as Integer
Dim ТекущееИсполнение as Integer
Dim  Обозначение as String
Dim r as Boolean

Set Kompas5 = GetObject(, "Kompas.Application.5")            'попытаться подключиться к открытому Компасу через API5
'  Set Kompas5 = CreateObject("Kompas.Application.5")           'открыть если открытого не было
Set Kompas7 = Kompas5.ksGetApplication7               'одновременно подключиться и через API7
Set Document5 = Kompas5.ActiveDocument3D
Set Document7 = Kompas5.TransferInterface(Document5, 2, 0)      'преобразовать в версию 7
Set embmgr = Document7
КоличествоИсполнений =  embmgr.EmbodimentCount         '
ТекущееИсполнение = embmgr.CurrentEmbodimentIndex         '            
Обозначение =  embmgr.GetCurrentEmbodimentMarking(-1,False)      '
r = embmgr.SetCurrentEmbodiment(1)                     'сделать текущим  исполнение 1    (выдает False, но работает)
r = embmgr.SetEmbodimentMarking( 1, 2,"900")            'у исполнения 1 в окончании  записать 900

Это составлено благодаря помощи Vi2, спасибо ему. Обязательно нажму заветную кнопку.
.

Валерий Изранов

08.08.19, 08:46:58 #34 Последнее редактирование: 08.08.19, 09:24:04 от Валерий Изранов
Окрыленный знаниями от Vi2 написал программку для копирования Сборки
из Старой Папки в Новую папку. Сборка содержит одну деталь. У детали три
исполнения -00, -01 и -02.
Вот текст программки. Для лучшего понимания сути текст здесь немного изменен.

Dim Document7(2) As KompasAPI7.IKompasDocument                'две переменные такого типа
Dim embmgr As KompasAPI7.IEmbodimentsManager      

Set Document7(0) = Open(СтараяПапка\Сборка, True, False)       '
Document7(0).SaveAs(НоваяПапка\Сборка)              '   

For i =0 to КоличествоДеталейВСборке -1                      ' деталей три: с исполнениями -00, -01, -02
     Set Document7(1) = Open(СтараяПапка\Деталь, True, False)             '
     Set Komponent = Document7(1).TopPart
     Обозначение = Komponent.marking                         'это и есть исполнение
     Set embmgr = Document7(1)                             'так нужно, чтобы к исполнениям добраться
     embmgr.SetCurrentEmbodiment(Обозначение)          'у детали установить нужное исполнение
     Komponent.Update
     Document7(0).RebuildDocument
     Document7(1).SaveAs(НоваяПапка\Деталь)        'для исполнения -00 Компас выдает запрос на изменение ссылок, для исполнений -01 и -02 нет.
     Document7(1).Close(0)
Next i
Document7(0).RebuildDocument                    '   
Document7(0).Save

Когда все ЭТО срабатывает, в Компасе остается открытая Сборка.
Все хорошо.
Все три исполнения детали берутся из файла детали в Новой Папке.
Дальше очень плохо.
"Вручную" закрываю Сборку и открываю ее из Новой Папки.
Исполнения детали -01 и -02 берутся из файла детали в СТАРОЙ папке.

Я в растерянности, как это так.

Валерий Изранов

За последние дни так и не удалось скопировать деталь с исполнениями в Новую папку. Увы.

Оплошность Компаса v16 х64 можно исправить вручную:
Открыть Сборку в Новой папке,
выбрать в дереве построения Деталь,
правой кнопкой мыши выбрать Свойства компонента,
файл источник -> выбрать файл в Новой папке-> установить исполнение,
ввести ВК.

Кто то знает, как эти действия повторить программно?

Валерий Изранов

"Когда все ЭТО срабатывает, в Компасе остается открытая Сборка.
Все хорошо.
Все три исполнения детали берутся из файла детали в Новой Папке.
Дальше очень плохо.
"Вручную" закрываю Сборку и открываю ее из Новой Папки.
Исполнения детали -01 и -02 берутся из файла детали в СТАРОЙ папке.
Я в растерянности, как это так."

Проблема, озвученная пару сообщений раньше до сих пор не решилась.

В сообщении от 02.02.18, 10:56:29 #7 по ссылке https://forum.ascon.ru/index.php/topic,31007.msg246609.html#msg246609 было написано:

"IKompasDocument3D - он один для файла, исполнения имеют свой интерфейс и уже от них нужно получать IPart7:=IEmbodiment.Part - компонент исполнения."

Sabahs,Вират Лакх,Vi2 как бы это "приземлить"?

Вират Лакх

Макрос на питоне сохраняет текущую сборку по новому пути, перебирает все исполнения новой сборки и пересохраняет все компоненты рядом с собой без какого-либо анализа. 'd:\\sborka.a3d' - этот путь заменить на свой. Подсборки не анализируются. Ссылки в переменных не обрабатываются.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

title = 'Копия текущей сборки'

from os import path
try:
from win32com.client import Dispatch, gencache
try:
KompasAPI5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
except:
import KompasAPI5, KompasAPI7
except:
import sys
if sys.version_info[0] < 3:
import Tkinter as tk, tkMessageBox
def decodestr(txt): return txt.decode('cp1251')
else:
import tkinter as tk, tkinter.messagebox as tkMessageBox
def decodestr(txt): return txt
from traceback import format_exc
tk.Tk().withdraw()
tkMessageBox.showerror(title, decodestr(format_exc()))
sys.exit()
KompasObject = Dispatch('Kompas.Application.5', None, KompasAPI5.KompasObject.CLSID)
iApplication = KompasObject.ksGetApplication7() # Dispatch('Kompas.Application.7')
if not iApplication.Visible: iApplication.Visible = True # KompasObject.Visible
k14 = True if KompasObject.ksGetSystemVersion(0, 0, 0, 0)[1] >= 14 else False

def saveparts():
iTopPart = iKompasDocument3D.TopPart
firstparts = iTopPart.PartsEx(1)
allparts = iTopPart.PartsEx(0)
for firstpart in firstparts:
f1 = firstpart.FileName
f2 = iDocPath + path.basename(f1)
iDocPart = iApplication.Documents.Item(f1)
if iDocPart and iDocPart.Changed:
iDocPart.SaveAs(f2)
else:
if k14:
iEMpart = KompasAPI7.IEmbodimentsManager(firstpart)
ceipart = iEMpart.CurrentEmbodimentIndex
firstpart.SaveAs(f2)
if k14:
iEMpart.SetCurrentEmbodiment(ceipart)
firstpart.Update()
for part in allparts:
if part.FileName == f1:
part.FileName = f2
part.Update()
iDocument = iApplication.ActiveDocument
iDocument.SaveAs('d:\\sborka.a3d')
iDocPath = iDocument.Path
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
if k14:
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)
cei = iEmbodimentsManager.CurrentEmbodimentIndex
ecount = iEmbodimentsManager.EmbodimentCount
else:
ecount = 0
if ecount:
for e in range(ecount):
iEmbodimentsManager.SetCurrentEmbodiment(e)
saveparts()
iEmbodimentsManager.SetCurrentEmbodiment(cei)
else:
saveparts()
iKompasDocument3D.RebuildDocument()

Валерий Изранов

Вират Лакх, каюсь: синтаксис Питон_а очень труден для понимания простому человеку.

1"def saveparts():" из текста - это начало определения подпрограммы? А где, на какой строке это определение заканчивается.

2 Я не смог найти место в тексте, где Сборка копируется из Старой папки в Новую папку.

3 В тексте 3 раза используется SaveAS и ни разу не используется Open.

До мелких мелочей я просто не дошел.

Вират Лакх

Наоборот, питон сделан для легкого понимания. Его может читать любой неподготовленный человек, если сказать ему, что да как :)
1) saveparts() - это процедура сохранения всех компонентов активного исполнения сборки, которая применяется в двух местах в коде. Если бы было одно применение, то я бы это в def не делал. В питоне нет end'ов. Блоки определяются отступами. Так гораздо нагляднее и заставляет человека писать красиво.
Соответственно, код процедуры заканчивается перед iDocument = iApplication.ActiveDocument
2) iDocument.SaveAs('d:\\sborka.a3d')
3) Значит Open не нужен. Он понадобится для открытия и обработки подсборок.