Долго выбирал раздел, в котором поместить мое сообщение.
Этот раздел оказался самым читаемым.
Задача: с помощью 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
Составлено под руководством Вират Лакх. Спасибо ему.
Цитата: Валерий Изранов от 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) Для спасибо есть специальные ссылочки "Поблагодарить" у каждого сообщения и "повысить" рядом с репутацией.
Согласен со всем вышенаписанным.
Но у меня есть маленькая беденка (от слова беда).
Я настолько привык в VB6 писАть по русски имена переменных и перейти на Python с его "исключительно английским" не смогу.
В VB6 у меня работает все, что мне нужно. кроме IEmbodimentsManager и TransferInterface.
Думаю, как в родной VB6 вставить кусочек исполнимого кода для обработки этих команд.
Или как то по другому...
https://forum.ascon.ru/index.php/topic,31101.msg247593.html#msg247593
Я пишу на 2.7 для совместимости, а вы можете этот удалить и поставить самую новую версию 3.x для использования русских переменных. Или, если оставаться на vb, то искать генератор модулей, про что я написал выше. Или найти готовый модуль.
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
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-объект не поддерживает это свойство или метод
Буду рад дальнейшему обсуждению.
Цитата: Валерий Изранов от 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) новый тип данных.
И для чего это нужно.
Цитата: Валерий Изранов от 31.07.19, 21:26:13
Vi2, сознаюсь: я не знаю как в VB6 добавить в References или в Object Browser (F2) новый тип данных.
И для чего это нужно.
Таким образом добавляются новые библиотеки типа. Находишь в меню «Project» пункт «Reference...» или нажимаешь F2, появляется окно Object Browser, в котором по правой кнопке мышки вызывается меню, в котором тоже есть пункт «Reference...». Жмакаешь на него. Появится окно добавления этих самых Reference. Находишь относящиеся к Компас, в которых определены те или иные данные ,которые тебе нужны в работе. У меня, например, Kompas6API5, KompasAPI7, Kompas6Constants и Kompas6Constants3D. Отмечаешь галочкой выбора и нажимаешь ОК. Теперь у тебя доступны интерфейсы в явном виде, т.е. вместо Object можно (или нужно) использовать реальный тип.
Это в дальнейшем поможет цепляться и к событиям Компаса.
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, спасибо ему. Обязательно нажму заветную кнопку.
.
Окрыленный знаниями от 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 не нужен. Он понадобится для открытия и обработки подсборок.
Цитата: Вират Лакх от 19.12.19, 09:28:092) iDocument.SaveAs('d:\\sborka.a3d')
Но она вначале должна открыться из Старой папки...
Я в описании сказал, что "Макрос на питоне сохраняет текущую сборку", т.е. ранее открытый и активный документ.
Но можно и открыть самому, смотря что должна выполнять программа.
Тогда iDocument = iApplication.ActiveDocument заменить на iApplication.Documents.Open(FilePart, False, True) # указать видимость документа и права доступа.
FilePart - путь к файлу.
Это странная штука "длина сессии в мин" при регистрации. Был я, и вдруг меня нет на форуме.
Может быть Sabahs -автор текста
В сообщении от 02.02.18, 10:56:29 #7 по ссылке https://forum.ascon.ru/index.php/topic,31007.msg246609.html#msg246609 :
"IKompasDocument3D - он один для файла, исполнения имеют свой интерфейс и уже от них нужно получать IPart7:=IEmbodiment.Part - компонент исполнения."
откликнется?
Цитата: Валерий Изранов от 19.12.19, 10:08:12Может быть Sabahs -автор текста
...
В сообщении от 02.02.18, 10:56:29 #7 по ссылке https://forum.ascon.ru/index.php/topic,31007.msg246609.html#msg246609 :
...
А, где, я,
тут (https://forum.ascon.ru/index.php/topic,31007.msg246609.html#msg246609)?
Вам нужно перебрать исполнения сборки и сохранить содержимое каждого? Тогда чем Вам моё не устраивает? Не понятно ничего? Я почти так же, как сказал Sabahs, делаю.
"IKompasDocument3D - он один для файла" -> iKompasDocument3D = KompasAPI7.IKompasDocument3D(iDocument) - получаю интерфейс документа-модели.
"исполнения имеют свой интерфейс" -> for e in range(ecount): iEmbodimentsManager.SetCurrentEmbodiment(e) - последовательно переключаю текущее исполнение.
"от них нужно получать IPart7:=IEmbodiment.Part - компонент исполнения" -> iTopPart = iKompasDocument3D.TopPart - верхний компонент текущего исполнения.
Скорее всего, можно было не переключать исполнения сборки, а сделать типа как написал Sabahs: iEmbodimentsManager.Embodiment(e).Part
Но этот способ работает с версии компаса 16.0 и выше, а переключения должны работать с 14.0 и выше.
Sabahs, ссылка верная, 02.02.18, 10:56:29
Вират Лакх, задача с первого взгляда простая:
Сборку в которую входит 1 деталь, у детали 3 исполнения нужно скопировать из Старой папки в Новую папку.
Здраствуйте, к теме с API. Возможно ли к созданной детали, создать и добавить новое свойство(не из стандартных т.е библиотеке), для программирования исползую C#
проблемам в том, что после обьявления
IAplication newAplication = (IAplication)kompas.ksGetApplication7();
IKompasDocument kompasDoc = newAplication.ActivDocument;
IpropertyMng newProperty = (IpropertyMng)kompasDoc;
не добавить метод .addProperty, пишет что queryInterface не потдерживаеться. подскажите что делать ?
Цитата: Gefakra от 04.06.20, 09:42:42не добавить метод .addProperty, пишет что queryInterface не потдерживаеться. подскажите что делать ?
Можно так:
IPropertyMng newProperty = (IPropertyMng) newAplication;
newProperty.AddProperty(...);
Или так:
IPropertyMng newProperty = (IPropertyMng)kompasDoc.Application;
newProperty.AddProperty(...);
Цитата: p3452 от 04.06.20, 10:04:27Можно так:
IPropertyMng newProperty = (IPropertyMng) newAplication;
newProperty.AddProperty(...);
Или так:
IPropertyMng newProperty = (IPropertyMng)kompasDoc.Application;
newProperty.AddProperty(...);
Сработало, но к детали свойство не добавляется, пытаюсь вызвать метод IProperty.Update; но не выходит.
подозреваю что здесь нужен IPropertyKeeper, подскажите пожалуйста, что делать?
code
IApplication newAplikation = (IApplication)kompas.ksGetApplication7();
IKompasDocument kompasDoc = newAplikation.ActiveDocument;
IPropertyMng newProprty = (IPropertyMng)newAplikation;
newProprty.AddProperty("12","12");
Цитата: Gefakra от 04.06.20, 10:50:32Сработало, но к детали свойство не добавляется, пытаюсь вызвать метод IProperty.Update; но не выходит.
Вы вдумайтесь в то, что написано в справке SDK!
Что означают два параметра у AddProperty()?
Где и как их взять?!
Проделайте ручками в КОМПАС-е то, что хотите сделать программно, может быть тогда наступит понимание...
Цитата: p3452 от 04.06.20, 14:10:34Вы вдумайтесь в то, что написано в справке SDK!
Что означают два параметра у AddProperty()?
Где и как их взять?!
Проделайте ручками в КОМПАС-е то, что хотите сделать программно, может быть тогда наступит понимание...
получаеться: открыть менеджер свойст, создать свойство, добавить свойство
создать свойство есть, добавить это IpropertyKeeper.SetPropertyValue
значет остаеться установить сами значени, как то нет понимания как это сделать, и как подключить интерфей IpropertyKeeper через
IChooseBodies7::Bodies.
я не очень понимаю эти два параметра:( VARIANT libname, VARIANT val );
Libname ( VARIANT)
- полный путь к библиотеке на диске VT_BSTR, либо указатель на документ VT_DISPATCH. Текущий документ - VT_EMPTY,
val( VARIANT)
- новое свойство VT_EMPY, создать по прототипу другого свойства - VT_DISPATCH.
из этого вытекает вопрос как должен выглядеть параметр, и как его добавить к объекту через IpropertyKeepr.SetPropertyValue?, не удаёться подключить интерфейс через IBody7
Цитата: Gefakra от 04.06.20, 09:42:42Возможно ли к созданной детали, создать и добавить новое свойство(не из стандартных т.е библиотеке)...
Сработало, но к детали свойство не добавляется...
Устал читать :)
Свойство создается не для детали/компонента, а добавляется в документ-модель. Все тела и компоненты, включая верхний компонент, имеют свойства, присутствующие в документе.
Неполный пример на питоне. Создание нового свойства в текущем документе, в котором надо выбирать значение из списка. При этом идентификатор созданного свойства будет всегда разный.
from pythoncom import VT_EMPTY, VT_ARRAY, VT_BSTR
from win32com.client import VARIANT
empty = VARIANT(VT_EMPTY, None)
listv = VARIANT(VT_ARRAY|VT_BSTR, ['aaa', 'bbb', 'ccc'])
iPropertyMng = KompasAPI7.IPropertyMng(iApplication)
iProperty = iPropertyMng.AddProperty(empty, empty)
iProperty.Name = 'Bukvi'
iProperty.Comment = 'Comment'
iProperty.UseListVal = True
iProperty.ListVal = listv
iProperty.Update()
Цитироватья не очень понимаю эти два параметра:( VARIANT libname, VARIANT val )
Первый - где создать свойство: в библиотеке свойств, в указанном документе или текущем документе.
Второй - само свойство: новое (с новым идентификатором и параметрами) или копию/прототип уже существующего свойства из другого или текущего документа или из библиотеки.
Когда свойство будет в документе, вы телу сможете в это свойство присвоить значение.
iPropertyKeeper = KompasAPI7.IPropertyKeeper(iBody7)
iPropertyKeeper.SetPropertyValue(iProperty, 'bbb', True)
Цитата: Вират Лакх от 05.06.20, 10:48:10Устал читать :)
Свойство создается не для детали/компонента, а добавляется в документ-модель. Все тела и компоненты, включая верхний компонент, имеют свойства, присутствующие в документе.
Неполный пример на питоне. Создание нового свойства в текущем документе, в котором надо выбирать значение из списка. При этом идентификатор созданного свойства будет всегда разный.
from pythoncom import VT_EMPTY, VT_ARRAY, VT_BSTR
from win32com.client import VARIANT
empty = VARIANT(VT_EMPTY, None)
listv = VARIANT(VT_ARRAY|VT_BSTR, ['aaa', 'bbb', 'ccc'])
iPropertyMng = KompasAPI7.IPropertyMng(iApplication)
iProperty = iPropertyMng.AddProperty(empty, empty)
iProperty.Name = 'Bukvi'
iProperty.Comment = 'Comment'
iProperty.UseListVal = True
iProperty.ListVal = listv
iProperty.Update()Первый - где создать свойство: в библиотеке свойств, в указанном документе или текущем документе.
Второй - само свойство: новое (с новым идентификатором и параметрами) или копию/прототип уже существующего свойства из другого или текущего документа или из библиотеки.
Когда свойство будет в документе, вы телу сможете в это свойство присвоить значение.
iPropertyKeeper = KompasAPI7.IPropertyKeeper(iBody7)
iPropertyKeeper.SetPropertyValue(iProperty, 'bbb', True)
на создании самого свойства всё и стопориться, непонятно как это сделать на C#
IApplication newAplikation = (IApplication)kompas.ksGetApplication7();
IKompasDocument kompasDoc = newAplikation.ActiveDocument;
//IPropertyMng newProprty = (IPropertyMng)newAplikation;
IPropertyMng newProprty = (IPropertyMng)kompasDoc.Application;
IProperty prop = newProprty.AddProperty(kompasDoc, b);
prop.Name = "qwerty";
prop.ReadOnly = true;
prop.ListVal = "123";
prop.Update();
prop возрашает null
Цитата: Вират Лакх от 05.06.20, 10:48:10Устал читать :)
Свойство создается не для детали/компонента, а добавляется в документ-модель. Все тела и компоненты, включая верхний компонент, имеют свойства, присутствующие в документе.
Неполный пример на питоне. Создание нового свойства в текущем документе, в котором надо выбирать значение из списка. При этом идентификатор созданного свойства будет всегда разный.
from pythoncom import VT_EMPTY, VT_ARRAY, VT_BSTR
from win32com.client import VARIANT
empty = VARIANT(VT_EMPTY, None)
listv = VARIANT(VT_ARRAY|VT_BSTR, ['aaa', 'bbb', 'ccc'])
iPropertyMng = KompasAPI7.IPropertyMng(iApplication)
iProperty = iPropertyMng.AddProperty(empty, empty)
iProperty.Name = 'Bukvi'
iProperty.Comment = 'Comment'
iProperty.UseListVal = True
iProperty.ListVal = listv
iProperty.Update()Первый - где создать свойство: в библиотеке свойств, в указанном документе или текущем документе.
Второй - само свойство: новое (с новым идентификатором и параметрами) или копию/прототип уже существующего свойства из другого или текущего документа или из библиотеки.
Когда свойство будет в документе, вы телу сможете в это свойство присвоить значение.
iPropertyKeeper = KompasAPI7.IPropertyKeeper(iBody7)
iPropertyKeeper.SetPropertyValue(iProperty, 'bbb', True)
А что если у модели есть ненесколько тел, и для каждого тела нужно задать уникальное свойство?!
Уникальное свойство или уникальное значение свойства?
Ещё раз. Свойства одни для документа. При добавлении свойства в документ оно появляется у всех тел и компонентов. И можно каждому объекту задать свои значения этого свойства.
..
Цитата: Вират Лакх от 23.09.20, 14:12:35Уникальное свойство или уникальное значение свойства?
Ещё раз. Свойства одни для документа. При добавлении свойства в документ оно появляется у всех тел и компонентов. И можно каждому объекту задать свои значения этого свойства.
Уникальное значение, или атрибуты
Задача, поставленная в названии темы уже давно была решена.
29.07.19, 06:19:00 в теме была размещена программа на Python.
02.08.19, 07:13:27 в теме была размещена программа на VB6
Появилась новая задача: программно получить свойства модели вообще
и Раздел спецификации в частности.
Программка на VB6 с этим не справилась.
Set Kompas5 = CreateObject("Kompas.Application.5")
Set Kompas7 = Kompas5.ksGetApplication7
Dim СвойстваMng As kompasAPI7.IPropertyMng
Dim СвойстваKeeper As kompasAPI7.IPropertyKeeper
Dim Компонент As kompasAPI7.Part7
Dim Документ3D As kompasAPI7.KompasDocument3D
Dim Документы As Kompas7.Documents
Dim ОдноСвойство As kompasAPI7.IProperty
Dim r as Boolean
Dim КолСвойств as Integer
Dim ЗначениеСвойства as String
Set Документ3D = Документы.Open("......")
'Set СвойстваMng = Документ3D ' queryInterface
КолСвойств = СвойстваMng.PropertyCount(Документ3D)
Set Компонент = Документ3D.TopPart
Set СвойстваKeeper = Компонент 'queryInterface
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, "Автор")
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойства, True, Retval) 'читаем свойство неудачно
'после выполнения r= True , ЗначениеСвойства = ""
r = СвойстваKeeper.SetPropertyValue(ОдноСвойство, "Василий", True) записываем свойство
' после выполнения r=True , Василий стал Автором
Компонент.Update
Документ3D.RebuildDocument
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, "Раздел спецификации") 'читаем свойство неудачно
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойства, True, Retval)
'после выполнения r=False , ЗначениеСвойства = ""
r = СвойстваKeeper.SetPropertyValue(ОдноСвойство, "Детали", True) записываем свойство неудачно
' поле выполнения r=False , раздел спецификации не изменился
Компонент.Update
Документ3D.RebuildDocument
Не читается ни одно свойство. Записываются некоторые.
Программы на Python, найденные на форуме тоже оказались бессильны.
В чем подвох?
# -*- coding: utf-8 -*-
import pythoncom
from win32com.client import gencache, Dispatch
# Подключим описание интерфейсов API7
kompas_api7_module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
application = kompas_api7_module.IApplication(
Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IApplication.CLSID,
pythoncom.IID_IDispatch))
kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iPart7 = kompas_document_3d.TopPart
property_mng = kompas_api7_module.IPropertyMng(application)
property_keeper = kompas_api7_module.IPropertyKeeper(iPart7)
dict_xml = {'Детали': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Детали" type="string" />'
'<property id="sectionNumb" value="20" type="int" />',
'Стандартные изделия': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Стандартные изделия" type="string" />'
'<property id="sectionNumb" value="25" type="int" />',
'Прочие изделия': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Прочие изделия" type="string" />'
'<property id="sectionNumb" value="30" type="int" />',
'Материалы': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Материалы" type="string" />'
'<property id="sectionNumb" value="35" type="int" />',
'Комплекты': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Комплекты" type="string" />'
'<property id="sectionNumb" value="40" type="int" />',
}
# Читаем обозначение (4.0 - Обозначение)
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 4.0), '', True, True)[1])
# Читаем наименование (5.0 - Наименование)
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 5.0), '', True, True)[1])
# Установить значение свойства (5.0 - Наименование)
print(property_keeper.SetPropertyValue(property_mng.GetProperty(kompas_document, 5.0), 'Кронштейн', True))
# Читаем свойство автор
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 11.0), '', True, True)[1])
# Читаем свойство раздел спецификации
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 20.0), '', True, True)[1])
# Определяем признак комплексного значения свойства - True - составное свойство, False - нет
print(property_keeper.IsComplexPropertyValue(property_mng.GetProperty(kompas_document, 20.0)))
# Установить значение составного свойства
iProperty = property_mng.GetProperty(kompas_document, 20.0)
print(property_keeper.SetComplexPropertyValue(iProperty, dict_xml['Прочие изделия']))
iProperty.Update()
# Читаем свойство раздел спецификации после изменения
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 20.0), '', True, True)[1])
input('Для выхода нажмите любую клавишу')
Запускать на текущей детали
Цитата: Валерий Изранов от 02.10.21, 06:30:15r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойства, True, Retval) 'читаем свойство неудачно
Это и не будет работать, т.к. ты описал переменную как "Dim ЗначениеСвойства as String", а методу требуется нечто иное. Retval там тоже не к месту.
Сам VB показывает этот метод так:
Function GetPropertyValue(Property As _Property, Value, BaseUnit As Boolean, FromSource As Boolean) As Boolean
Member of KompasAPI7.IPropertyKeeper
Получить значение свойства.
В описании SDK так:
[id(0x00003e80), helpstring("Получить значение свойства."), helpcontext(0x003bd081)]
HRESULT GetPropertyValue(
[in] IProperty* Property,
[out] VARIANT* Value,
[in] VARIANT_BOOL BaseUnit,
[out] VARIANT_BOOL* FromSource,
[out, retval] VARIANT_BOOL* Result);
Стоит переопределить переменную для получения значения или объявить другую, например, так:
Dim ЗначениеСвойства As String
Dim ЗначениеСвойстваV As Variant
...
Dim FromSource As Boolean
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойстваV, True, FromSource)
ЗначениеСвойства = ЗначениеСвойстваV
С разделом спецификации не помогу, потому что у меня не возвращается ничего оттуда (Empty), а как задать этот раздел, я не в курсе.
В личной переписке Михаил88 очень обстоятельно объяснил мне,
что value должен быть массивом из 3-х элементов. Спасибо ему за это.
Подсказка Vi2 что это должен быть тип Variant тоже попала в точку.
Вот такая получилась РАБОТАЮЩАЯ программка на VB6
Set Kompas5 = CreateObject("Kompas.Application.5")
Set Kompas7 = Kompas5.ksGetApplication7
Dim СвойстваMng As kompasAPI7.IPropertyMng
Dim СвойстваKeeper As kompasAPI7.IPropertyKeeper
Dim Компонент As kompasAPI7.Part7
Dim Документ3D As kompasAPI7.KompasDocument3D
Dim Документы As Kompas7.Documents
Dim ОдноСвойство As kompasAPI7.IProperty
Dim r as Boolean
Dim КолСвойств as Integer
Dim ЗначениеСвойства as String
'новые переменные
Dim ОтветНаЗапрос(2) As Variant '0,1,2 – массив из трех ячеек
Dim FromSource As Boolean
Dim Временная as String
Set Документ3D = Документы.Open("......")
'Set СвойстваMng = Документ3D ' queryInterface
КолСвойств = СвойстваMng.PropertyCount(Документ3D)
Set Компонент = Документ3D.TopPart
Set СвойстваKeeper = Компонент 'queryInterface
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, 20#) '# - тип Double, 20 - раздел спецификации
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ОтветНаЗапрос(0), True, FromSource) 'после выполнения r= True
ЗначениеСвойства = ОтветНаЗапрос(0)
r= СвойстваKeeper.IsComplexPropertyValue(ОдноСвойство) ) 'после выполнения r= True
Временная = СвойстваKeeper.GetComplexPropertyValue(ОдноСвойство, r)
'после выполнения Временная = "<? xml version="1.0"?><document/>"
Задача ЧТЕНИЯ свойств в VB6 решена.
Раздел спецификации оказывается (единственное ?) IsComplexProperty "составное свойство".
Запись составных свойств отличается от записи НЕсоставных. Для составных свойств используется
некий xml. Михаил88 в своем примере указал dict_xml =...... Что это такое практически и как его использовать в VB6?
Приписка для Vi2:
'а как задать этот раздел, я не в курсе.'
В верхней строке открытого Компаса V18: Настройка > Параметры > Настройка списка свойств > поставить галочку Раздел спецификации
В любом месте экрана нажать правую кнопку мыши > выбрать Свойства модели.
В появившемся окошке свойств два раза щелкнуть по строке раздел спецификации.
В появившемся оконце выбрать нужный и ОБЯЗАТЕЛЬНО нажать зеленую галочку.
Цитата: Валерий Изранов от 05.10.21, 09:36:21Вот такая получилась РАБОТАЮЩАЯ программка на VB6
Она не может быть работающей, потому что "Dim Документы As Kompas7.Documents" приводит к ошибке компиляции, а не заданный СвойстваMng - к ошибке выполнения.
Dim ЗначениеСвойстваV As Variant
...
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, "Раздел спецификации")
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойстваV, True, FromSource)
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, 20#) '# - тип Double, 20 - раздел спецификации
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойстваV, True, FromSource)
Начнём с того, что эти два кода идентичны. Что из них использовать - видно из области вкуса.
У меня этот код
r = СвойстваKeeper.IsComplexPropertyValue(ОдноСвойство) 'после выполнения r= True
ЗначениеСвойства = СвойстваKeeper.GetComplexPropertyValue(ОдноСвойство, FromSource)
даёт такую строку, если я выбираю "Документация" при выборе разделов спецификации:
<?xml version="1.0"?>
<document expression="" format="{$sectionName}" fromSource="false">
<property id="sectionName" value="Документация" type="string" />
<property id="sectionNumb" value="5" type="int" />
</document>
или такую, если я выбираю "Детали":
<?xml version="1.0"?>
<document expression="" fromSource="false" format="{$sectionName}">
<property id="sectionName" value="Детали" type="string" />
<property id="sectionNumb" value="20" type="int" />
</document>
Посмотри на свойство СвойстваKeeper.Properties. У меня оно возвращает такую строку:
<?xml version="1.0"?>
<infObject>
<property id="name" value="Receptacle" type="string" />
<property id="marking">
<property id="base" value="ABC.000.000.011" type="string" />
<property id="embodimentDelimiter" value="-" type="string" />
<property id="embodimentNumber" value="" type="string" />
<property id="additionalDelimiter" value="." type="string" />
<property id="additionalNumber" value="" type="string" />
<property id="documentDelimiter" value=" " type="string" />
<property id="documentNumber" value="" type="string" />
</property>
<property id="comment" value="" type="string" />
<property id="mass" value="0.176406" type="double" />
<property id="material" format="{$name}">
<property id="name" value="40Х" type="string" />
<property id="density" value="7825" type="double" />
<property id="location" value="" type="string" />
</property>
<property id="accuracyClass" value="c" type="string" />
<property id="specRoughSign" value="0" type="int" />
<property id="specRoughValue" value="" type="string" />
<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">
<property id="sectionName" value="Детали" type="string" />
<property id="sectionNumb" value="20" type="int" />
</property>
<property id="spcObjNumber" value="318873682338.000000" type="string" />
</infObject>
Я так понимаю, что они пересекаются в области SPCSection. Это показывает, какие бывают свойства и их типы.
Наверное, есть XML парсеры, такие как DOMDocument. Подключаешь в Refereneces что-то типа "Microsoft XML, v6.0"
Class DOMDocument60
Member of MSXML2
W3C-DOM XML Document 6.0 (Apartment)
И работаешь с этим переданным XML текстом как с объектами.
Dim aplication As KompasAPI7.IApplication
Dim kompas_document As KompasAPI7.IKompasDocument
Dim kompas_document_3d As KompasAPI7.KompasDocument3D
Dim iPart7 As KompasAPI7.Part7
Dim property_mng As KompasAPI7.IPropertyMng
Dim property_keeper As KompasAPI7.IPropertyKeeper
Dim property As KompasAPI7.IProperty
Dim value_property As Variant
Dim res As Boolean
Dim razdel As String
Dim complex_property As Boolean
Set aplication = GetObject(, "Kompas.Application.7")
Set kompas_document = aplication.ActiveDocument
Set kompas_document_3d = kompas_document
Set iPart7 = kompas_document_3d.TopPart
Set property_mng = aplication
Set property_keeper = iPart7
Set property = property_mng.GetProperty(kompas_document, 20#)
res = property_keeper.GetPropertyValue(property, value_proprty, True, True)
razdel = value_proprty
strXml = "<property id=""SPCSection"" expression="""" fromSource=""false"" format=""{$sectionName}""><property id=""sectionName"" value=""Прочие изделия"" type=""string"" /><property id=""sectionNumb"" value=""30"" type=""int"" />"
complex_property = property_keeper.SetComplexPropertyValue(property, strXml)
Подведем итоги.
Вот программа для чтения и записи свойств файлов на Питоне:
# -*- coding: utf-8 -*-
import pythoncom
from win32com.client import gencache, Dispatch
# Подключим описание интерфейсов API7
kompas_api7_module = gencache.EnsureModule("{69AC2981-37C0-4379-84FD-5DD2F3C0A520}", 0, 1, 0)
application = kompas_api7_module.IApplication(
Dispatch("Kompas.Application.7")._oleobj_.QueryInterface(kompas_api7_module.IApplication.CLSID,
pythoncom.IID_IDispatch))
kompas_document = application.ActiveDocument
kompas_document_3d = kompas_api7_module.IKompasDocument3D(kompas_document)
iPart7 = kompas_document_3d.TopPart
property_mng = kompas_api7_module.IPropertyMng(application)
property_keeper = kompas_api7_module.IPropertyKeeper(iPart7)
dict_xml = {'Детали': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Детали" type="string" />'
'<property id="sectionNumb" value="20" type="int" />',
'Стандартные изделия': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Стандартные изделия" type="string" />'
'<property id="sectionNumb" value="25" type="int" />',
'Прочие изделия': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Прочие изделия" type="string" />'
'<property id="sectionNumb" value="30" type="int" />',
'Материалы': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Материалы" type="string" />'
'<property id="sectionNumb" value="35" type="int" />',
'Комплекты': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Комплекты" type="string" />'
'<property id="sectionNumb" value="40" type="int" />',
}
# Читаем обозначение (4.0 - Обозначение)
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 4.0), '', True, True)[1])
# Читаем наименование (5.0 - Наименование)
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 5.0), '', True, True)[1])
# Установить значение свойства (5.0 - Наименование)
print(property_keeper.SetPropertyValue(property_mng.GetProperty(kompas_document, 5.0), 'Кронштейн', True))
# Читаем свойство автор
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 11.0), '', True, True)[1])
# Читаем свойство раздел спецификации
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 20.0), '', True, True)[1])
# Определяем признак комплексного значения свойства - True - составное свойство, False - нет
print(property_keeper.IsComplexPropertyValue(property_mng.GetProperty(kompas_document, 20.0)))
# Установить значение составного свойства
iProperty = property_mng.GetProperty(kompas_document, 20.0)
print(property_keeper.SetComplexPropertyValue(iProperty, dict_xml['Прочие изделия']))
iProperty.Update()
# Читаем свойство раздел спецификации после изменения
print(property_keeper.GetPropertyValue(property_mng.GetProperty(kompas_document, 20.0), '', True, True)[1])
input('Для выхода нажмите любую клавишу')
А вот программа на VB6:
Dim Kompas7 As KompasAPI7.IApplication
Dim Документ As KompasAPI7.IKompasDocument
Dim Документ3D As KompasAPI7.KompasDocument3D
Dim Компонент As KompasAPI7.Part7
Dim СвойстваMng As KompasAPI7.IPropertyMng
Dim СвойстваKeeper As KompasAPI7.IPropertyKeeper
Dim ОдноСвойство As KompasAPI7.IProperty
Dim ЗначениеСвойства As Variant
Dim r As Boolean
Dim strXml As String
Set Kompas7 = GetObject(, "Kompas.Application.7")
Set Документ = Kompas7.ActiveDocument
Set Документ3D = Документ
Set Компонент = Документ3D.TopPart
Set СвойстваMng = Kompas7
Set СвойстваKeeper = Компонент 'QueryInterface
Set ОдноСвойство = СвойстваMng.GetProperty(Документ3D, 20#) '# -тип Double, 20 - раздел спецификации
r = СвойстваKeeper.GetPropertyValue(ОдноСвойство, ЗначениеСвойства, True, True)
r = СвойстваKeeper.IsComplexPropertyValue(ОдноСвойство) ''это комплексное значение свойства?
If r = 1 Then 'да
strXml = "'<property id=""SPCSection"" expression="""" fromSource=""false"" format=""{$sectionName}"">''''<property id=""sectionName"" value=""Прочие изделия"" type=""string"" />''''<property id=""sectionNumb"" value=""30"" type=""int"" />'"
r = СвойстваKeeper.SetComplexPropertyValue(ОдноСвойство, strXml)
Else
r = СвойстваKeeper.SetPropertyValue(ОдноСвойство, "Василий", True) 'записываем свойство
End If
Компонент.Update
Обе программы запускать когда в компасе открыта модель.
В создании этих программ активнейшее участие принимали Михаил88 и Vi2. Им благодарность.
Цитата: Валерий Изранов от 06.10.21, 14:25:58dict_xml
А откуда вы вообще узнали о существовании этого? :)
"dict_xml" переменная строкового типа. Имя может быть любым.
В строке
dict_xml = {'Детали': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
ей присваивается значение
а в строке
print(property_keeper.SetComplexPropertyValue(iProperty, dict_xml['Прочие изделия']))
она используется.
Более подробно сможет рассказать Михаил88, когда сюда заглянет.
dict_xml - это словарь, где значение до ':' это ключ, после значение.
Пример:
'Стандартные изделия' - Ключ
'<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Стандартные изделия" type="string" />'
'<property id="sectionNumb" value="25" type="int" />' - Значение
Использование словаря не обязательно Вы можете напрямую сразу передавать xml строку вот так:
'<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
'<property id="sectionName" value="Стандартные изделия" type="string" />'
'<property id="sectionNumb" value="25" type="int" />'
Узнал из SDK
Screenshot_1.bmp
Содержимое этой строки я взял из файла 3D модели.
Компасовский документ можно открыть с помощью архиватора.
Внутри архива находится файл MetaProductInfo его можно открыть блокнотом.
Screenshot_2.bmp
скопировал и использовал в своем коде.
Имя раздела и номер раздела можно посмотреть здесь
Screenshot_3.bmp
Цитата: Михаил88 от 09.07.22, 17:11:10Компасовский документ можно открыть с помощью архиватора.
Ах вооот оно что. В примерах я такого не видел, а в справке...да вы и сами знает как там оно в справке у Компаса)))
Спасибо!