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

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

« предыдущая - следующая »

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

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

Долго выбирал раздел, в котором поместить мое сообщение.
Этот раздел оказался самым читаемым.
Задача:  с помощью API5/API7 добраться до исполнений детали.
Тема неоднократно обсуждалась на форуме:
https://forum.ascon.ru/index.php/topic,25319.0.html в сообщении от 18.11.13, 09:34:07 приведен фрагмент программы  для работы с исполнениями.
https://forum.ascon.ru/index.php/topic,27546.msg206212.html#msg206212  в сообщении от  25.02.15, 09:43:04 автор пишет что «нашла рабочий вариант!!! позже напишу, в чем была моя проблема» Прошло 4 года.
https://forum.ascon.ru/index.php/topic,31231.0.html
из сообщения от 04.06.18, 12:52:17   «но есть трудности если у детали есть исполнения»
в сообщении от  05.06.18, 22:07:14 автор  пишет «По первому, могу сделать, когда полностью до тестирую v18, т.к. у остальных были проблемы с исполнением»
Я начал программировать на VB6 с использованием API5/API7 для автоматизации работы  Компас v16 х64.
Не удается выполнить ksTransferInterface и TransferInterface, которые меня очень сильно интересуют.
Никак не удается получить интерфейс IEmbodimentsManager.

Фрагмент  моей программы на VB6 для детали с исполнениями.
Dim Kompas5 As Object
Dim Kompas7 As Object
Dim Document5 As Object
Dim Document7 As Object
Dim EmbodimentsManager As Object
Dim PathName As String
Dim Name As String
Set Kompas5 = CreateObject("Kompas.Application.5")         'работает
Set Kompas7 = Kompas5.ksGetApplication7            'работает
Set Document7 = Kompas7.ActiveDocument            'работает
Name = Document7.Name                     'работает (для проверки)
PathName = Document7.PathName               'работает (для проверки)
Set Document5 = Kompas7.ksTransferInterface(Document7, 1, 0)      '438 объект не поддерживает свойства или методы
Set Document5 = Kompas5.ksTransferInterface(Document7, 1, 0)      '438 объект не поддерживает свойства или методы
Set Document5= Kompas5.TransferInterface(Document7, 1, 0) '      '424 необходим объект
Set Document5= Kompas7.TransferInterface(Document7, 1, 0) '      '438 объект не поддерживает свойства или методы
Set EmbodimentsManager = Document7.EmbodimentsManager               '438 объект не поддерживает свойства или методы

Очень рассчитываю на помощь, в первую очередь от  Sabahs.

Вират Лакх

Я не Sabahs, но попробую помочь.
ksTransferInterface здесь, думается, вообще не при делах, и нужно использовать Automation, т.е. KompasObject.TransferInterface
Далее, зачем вы трансферинтерфейсите документ? Получайте его по-нормальному: KompasObject.ActiveDocument3D()
И зачем вы пытаетесь получить Document5, если далее вы его не используете? По крайней мере, дальнейшего кода нет.
И самое для Вас интересное по последней строке предоставленного кода:
0) В сдк русским по белому написано:
Цитировать
Интерфейс IEmbodimentsManager
Интерфейс менеджера исполнений
Иерархия:
IDispatch
IEmbodimentsManager
Описание:
Данный интерфейс можно получить у интерфейсов IPart7, IKompasDocument3D, IAssociationView с помощью метода IUnknown::QueryInterface.

1) Вы его пытаетесь получить от ActiveDocument, что невозможно, т.к. это не верхний компонент и не базовый класс документов-моделей.
2) Не знаю, как на VB выглядит QueryInterface, но у вас это похоже на метод или свойство.
Нужно от документа сначала получить 3д документ опять-таки через QueryInterface, потом от 3д получить IEmbodimentsManager
На питоне это выглядит так без API5:

from win32com.client import Dispatch, gencache
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
iApplication = Dispatch('Kompas.Application.7')
iDocument = iApplication.ActiveDocument
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)

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

Согласен с цитатой из SDK:
«Данный интерфейс можно получить у интерфейсов IPart7, IKompasDocument3D, IAssociationView с помощью метода IUnknown::QueryInterface.»
Дело в том, что  в VB, Delphi и C# метода QueryInterface нет.
Поэтому создатели SDK в разделе
Создание прикладных библиотек
    Рекомендации по созданию прикладных библиотек
         Рекомендации по использованию метода IUnknown::QueryInterface
предложили какой то очень экстравагантный способ получения этого метода.
Я не понимаю смысла написанного там. Уже больше месяца не понимаю...

Вират Лакх

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

kompasDoc = KomApp.ActiveDocument
doc2D = kompasDoc._oleobj_.QueryInterface(KAPI7.NamesToIIDMap['IDrawingDocument'], pythoncom.IID_IDispatch)
doc2D = API7.IDrawingDocument(doc2D)

Но можно сделать проще, без этой мутной строки с QueryInterface типа как в примере выше.
В примере для C# тоже явно слова QueryInterface нет и похоже на пример для питона.
В примере для C++ про какие-то "умные указатели" рассказывают, но тоже явно слова QueryInterface нет.
В примере для Delphi тоже это выглядит просто без QueryInterface.
В примере для Visual Basic вроде понятно расписали (похоже на смесь Delphi и Python):

Dim kompasDoc As KompasAPI7.KompasDocument
Dim doc2D As KompasAPI7.DrawingDocument
Set kompasDoc = KomApp.ActiveDocument
Set doc2D = kompasDoc // Здесь выполнится QueryInterface.

Вам здесь, видимо, нужен визуалобэйсиковый KompasAPI7.
В питоне мы его можем сами сгенерировать:
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
Или можем импортировать из библиотеки Компас-Макро готовый KompasAPI7.py, полученный этим же путем:
import KompasAPI7
В папке SDK\Include лежат файлы kapi7.h и kapi7.cpp, которые Machine generated IDispatch wrapper class(es) created with ClassWizard
Вот и вам надо инструмент типа EnsureModule или ClassWizard, чтобы из kApi7.tlb создать KompasAPI7 для Visual Basic.
Или как-то по-другому.

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

При запуске Компас от v? до v18 в реестре появляются две записи:
«Kompas.Application.5» и «Kompas.Application.7». Их можно увидеть с помощью редактора реестра.
Что бы запустить редактор реестра нужно нажать одновременно клавишу Windows (4 квадрата) и R.
В открывшемся оконце ввести «regedit» и ВК. Далее с помощью поиска найти «Kompas.Application.5»
и «Kompas.Application.7».
Сами программы находятся внутри Kompas.exe а в реестре их «точки соприкосновения».
Эти программы запускаются одновременно с Компасом и не знают ни о VB, ни о Delphi, ни о Питоне и ни о чем другом.
Подключение к ним в VB выглядит так: Set Имя = CreateObject("Kompas.Application.5"). Имя может быть любым.
Подключение к ним в Delphi выглядит так: Имя = CreateOleObject("Kompas.Application.5"). Имя может быть любым.
Подключение к ним в Питоне выглядит так:
Имя = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0) "). Имя может быть любым.
Моя программа умеет подключаться и к "Kompas.Application.5" и к "Kompas.Application.7"
Она никак не научится получать интерфейс EmbodimentsManager.
Вот в чем мой вопрос.

Вират Лакх

Цитата: Валерий Изранов от 24.07.19, 07:15:14
Подключение к ним в Питоне выглядит так:
Имя = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0) "). Имя может быть любым.

Про питон не так. Подключение к компасу в Питоне выглядит так:
Имя = Dispatch('Kompas.Application.5', None, KompasAPI5.KompasObject.CLSID). Имя может быть любым.
    или
Имя = Dispatch('Kompas.Application.7'). Имя может быть любым.
Вот я вам и рассказываю, что подключиться к компасу - это одно, а подключить модуль, из которого компилятор узнает, что такое IEmbodimentsManager - это другое. Делайте, как в примере СДК написано, но там используется KompasAPI7, про который не написали как его получить.

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

  По ссылке "https://forum.ascon.ru/index.php/topic,25319.0.html в сообщении от 18.11.13, 09:34:07 из моего первого письма" приведен фрагмент программы  для для получения интерфейса EmbodimentsManager.
  По ссылке "https://forum.ascon.ru/index.php/topic,27546.msg206212.html#msg206212  в сообщении от  25.02.15, 09:43:04 из моего первого письма " автор сообщает, что ей не удалось повторить ЭТО на своем компьютере.
  Я не владею Delphi и не могу попробовать ЭТО сам.
  Можно ли по образу и подобию повторить ЭТО на Питоне?

Вират Лакх

Пролистал обе темы. Они там какие-то детские проблемы решают...
99% вероятности, что ЭТО легко можно повторить на питоне.
Получение IEmbodimentsManager на питоне я вам написал.
Вот тут https://forum.ascon.ru/index.php/topic,30640.msg264438.html#msg264438 программа, в которой чего только нет: и оба API, и трансферинтерфейсы, и исполнения по всякому получаем, переключаем и читаем.
Можете скачать, почитать. Там много комментариев написано.

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

К сожалению в указанной ссылке поиск "исполнение", "EmbodimentsManager", "TransferInterface" ничего не дал.

Вират Лакх

Не в сообщении, а в скрипте программы Обозначение компонентов и тел v3.14, которая лежит в архиве OKTv314.zip. Искать ActiveDocument, IKompasDocument3D, IEmbodimentsManager, TransferInterface и т.д.

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

К сожалению, искать что либо в исполняемом файле у меня нет возможности.

Вират Лакх

Повторюсь, это скрипт программы, т.е. файл .pyw - это текстовый файл, который можно открыть в любом просмотрщике или редакторе. Только желательно в таком редакторе, который бы корректно отформатировал табуляции, иначе всё будет нечитаемо криво. Должно быть типа как на картинке.

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

Вират Лакх, я всю голову сломал КАК текст программы на Питоне по ссылке из предыдущего письма ЗАРАБОТАЛ на моем компьютере.
Сегодня вдруг обнаружил,что у меня есть установленный Python.
В VB у меня не получается выполнить TransferInterface и получить интерфейс EmbodimentsManager.
В  программе на Питоне есть такие строки:
ModelObject5 = KompasObject.TransferInterface(ModelObject7, 1, 0)
iEMpart = KompasAPI7.IEmbodimentsManager(partsFile[index])
Вират Лакх, в силу моей полной неосведомленности программирования на Питоне, можно ли маленькую подсказку как мне запустить этот текст на выполнение в пошаговом режиме (есть ли такой?).
Хотелось бы перенести эти строки ближе к началу программы  и проверить выполнение только их.


Вират Лакх

Питон приходит вместе с компасом (библиотекой компас-макро).
На счет пошагового режима не знаю. Мы используем вывод на экран того, что нам нужно:
print abc   # для питон 2.x
print(abc) # для любого питона
где abc - переменная, которая вас интересует.
Давайте начнем с простого. Возьмем код, который я написал выше, и натолкаем туда принты:

from win32com.client import Dispatch, gencache
print Dispatch
print gencache
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
print KompasAPI7
iApplication = Dispatch('Kompas.Application.7')
print iApplication
iDocument = iApplication.ActiveDocument
print iDocument
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
print iKompasDocument3D
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)
print iEmbodimentsManager
print iEmbodimentsManager.EmbodimentCount

В окне вывода вашего редактора оно выдаст такое:

<function Dispatch at 0x0000000002815F28>
<module 'win32com.client.gencache' from 'C:\Python27\lib\site-packages\win32com\client\gencache.pyc'>
<module 'win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0' from 'C:\Python27\lib\site-packages\win32com\gen_py\69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.pyc'>
<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IApplication instance at 0x44289416>
<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IKompasDocument instance at 0x44289544>
<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IKompasDocument3D instance at 0x44289608>
<win32com.gen_py.69AC2981-37C0-4379-84FD-5DD2F3C0A520x0x1x0.IEmbodimentsManager instance at 0x44289672>
2

Если инструкция ничего не получила, то он так и пишет None. Но бывает со всякими коллекциями тоже None, но на самом деле не None, просто он не знает, как такое отображать, наверное. Но это уже тонкости. И еще нюанс. Если мы делаем тот самый QueryInterface, то он в любом случае выдаст интерфейс в принте, но он может быть гонимый, если его получать не от того, чего надо. Проверить его можем только использованием, например, получить свойство EmbodimentCount, ответ 2.
Так вот, лучше не перемещать, а написать под переменной её принт, соблюдая отступы. Иначе вы испортите логику программы и получите не то, что надо. При этом "пробельные" и "табуляционные" отступы к коде лучше не перемешивать - может быть ошибка при компиляции. В обозначении компонентов и тел стоят табуляции.

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

Скопировал верхний код из предыдущего сообщения, вставил его в новое окно Питона,запустил на выполнение.
"Первенец" - так его зовут
подключился к Kompas.Application.7 открытого ранее Компаса,
нашел открытый ActiveDocument
получил у него IEmbodimentsManager
получил количество исполнений EmbodimentCount
Обалдеть. Это в VB6 я пытался получить в течение последнего месяца...
Мне нужно сколько то времени все это обдумать.

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


Вират Лакх, можно ли к фрагменту программы из сообщения от  26.07.19, 10:51:28 

from win32com.client import Dispatch, gencache
print Dispatch
print gencache
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
iApplication = Dispatch('Kompas.Application.7')
iDocument = iApplication.ActiveDocument
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)
print iEmbodimentsManager.EmbodimentCount

добавить подключение к 'Kompas.Application.5' и показать как выполняются TransferInterface и ksTransferInterface?

Вират Лакх

Цитата: Валерий Изранов от 28.07.19, 04:41:03
... из сообщения от  26.07.19, 10:51:28 
добавить подключение к 'Kompas.Application.5' и показать как выполняются TransferInterface и ksTransferInterface?

Время у предыдущих сообщений указывать нет большого смысла, т.к. из-за часовых поясов оно у всех разное. Лучше ссылку, которая расположена сразу над « Ответ #13 : ... », скопировать в буфер обмена и вставить в текущее сообщение.
Про ksTransferInterface я писал в Ответ #1. Вот по TransferInterface:

# -*- coding: utf-8 -*-
from win32com.client import Dispatch, gencache
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
iApplication = Dispatch('Kompas.Application.7')
iDocument = iApplication.ActiveDocument
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)
print iEmbodimentsManager.EmbodimentCount

KompasAPI5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasObject = Dispatch('Kompas.Application.5', None, KompasAPI5.KompasObject.CLSID)

print iDocument
ksDocument3D = KompasObject.TransferInterface(iDocument, 1, 0) # API7 -> API5
print ksDocument3D, ksDocument3D.reference # reference - Указатель документа-модели
print ksDocument3D.fileName # Еще проверка интерфейса более понятным свойством

iDoc3D = KompasObject.ActiveDocument3D() # Аналогичные результаты
print iDoc3D, iDoc3D.reference
print KompasObject.TransferInterface(iKompasDocument3D, 1, 0).reference
print KompasObject.TransferInterface(iEmbodimentsManager, 1, 0).reference

iPartDocument = KompasObject.TransferInterface(iDoc3D, 2, 0) # API5 -> API7
print iPartDocument
print KompasAPI7.IEmbodimentsManager(iPartDocument).EmbodimentCount

Количество исполнений можно было вообще в одну строчку написать после получения интерфейса компаса:
print KompasAPI7.IEmbodimentsManager(iApplication.ActiveDocument).EmbodimentCount

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

Вират Лакх, я узнал как получать исполнения детали через API5/API7 используя Python.
Чтобы другим было проще искать, я скомпоновал строчки текста из разных сообщений в один фрагмент
и хотел разместить фрагмент в  моем первом сообщении. И указать, что автор всего этого Вират Лакх.
Не удается сделать... Свои сообщения на форуме можно редактировать?

Вират Лакх

"всего этого" :)
Свои сообщения можно редактировать, если не прошло определенное время.
Не знаю, сколько точно этот период составляет.

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

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

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

from win32com.client import Dispatch, gencache
KompasAPI7 = gencache.EnsureModule('{69AC2981-37C0-4379-84FD-5DD2F3C0A520}', 0, 1, 0)
iApplication = Dispatch('Kompas.Application.7')
iDocument = iApplication.ActiveDocument
print iDocument.PathName                         # проверка интерфейса c понятным свойством
iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument)
iEmbodimentsManager = KompasAPI7.IEmbodimentsManager(iKompasDocument3D)
print iEmbodimentsManager.EmbodimentCount               # количество исполнений
print iEmbodimentsManager.CurrentEmbodimentIndex            # индекс текущего исполнения
print iEmbodimentsManager.GetCurrentEmbodimentMarking(-1,False)      # полное обозначение текущего исполнения
print iEmbodimentsManager.SetCurrentEmbodiment(1)            # сделать текущим  исполнение 1
print iEmbodimentsManager.SetEmbodimentMarking( 1, 2, '900')         # у исполнения 1 в окончании  записать 900

KompasAPI5 = gencache.EnsureModule('{0422828C-F174-495E-AC5D-D31014DBBE87}', 0, 1, 0)
KompasObject = Dispatch('Kompas.Application.5', None, KompasAPI5.KompasObject.CLSID)
ksDocument3D = KompasObject.TransferInterface(iDocument, 1, 0)      # API7 -> API5
print ksDocument3D.fileName                         # проверка интерфейса c понятным свойством
iDocument = KompasObject.TransferInterface(ksDocument3D, 2, 0)       # API5 -> API7

Составлено под руководством Вират Лакх. Спасибо ему.