• Добро пожаловать на Форум пользователей ПО АСКОН. Пожалуйста, авторизуйтесь.
 

Уважаемые пользователи,

Хотим проинформировать вас о режиме работы регистрации на нашем сайте.

Зарегистрироваться возможно в рабочие дни, с 8:00 до 20:00 (мск).

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

Благодарим вас за понимание и сотрудничество. Мы ценим ваше терпение и стремимся предоставить вам лучший опыт использования нашего сервиса.

С уважением,
Команда Ascon

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

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

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

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

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

Задача, поставленная в названии темы уже давно была решена.
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, найденные на форуме тоже оказались бессильны.

В чем подвох?
 

Михаил88

# -*- 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('Для выхода нажмите любую клавишу')


Запускать на текущей детали
+ Благодарностей: 3

Vi2

Цитата: Валерий Изранов от 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: Настройка > Параметры > Настройка списка свойств >  поставить галочку Раздел спецификации
В любом месте экрана нажать правую кнопку мыши > выбрать Свойства модели.
В появившемся окошке свойств два раза щелкнуть по строке  раздел спецификации.
В появившемся оконце выбрать нужный и ОБЯЗАТЕЛЬНО нажать зеленую галочку.

Vi2

Цитата: Валерий Изранов от 05.10.21, 09:36:21Вот такая получилась РАБОТАЮЩАЯ программка на VB6
Она не может быть работающей, потому что "Dim Документы As Kompas7.Documents" приводит к ошибке компиляции, а не заданный СвойстваMng - к ошибке выполнения.

Vi2

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. Это показывает, какие бывают свойства и их типы.

Vi2

Наверное, есть XML парсеры, такие как DOMDocument. Подключаешь в Refereneces что-то типа "Microsoft XML, v6.0"

Class DOMDocument60
    Member of MSXML2
    W3C-DOM XML Document 6.0 (Apartment)

И работаешь с этим переданным XML текстом как с объектами.

Михаил88

#67
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. Им благодарность.
+ Благодарностей: 1

streamdown


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

"dict_xml" переменная строкового типа. Имя может быть любым.
В строке
dict_xml = {'Детали': '<property id="SPCSection" expression="" fromSource="false" format="{$sectionName}">'
ей присваивается значение
а в строке
print(property_keeper.SetComplexPropertyValue(iProperty, dict_xml['Прочие изделия']))
она используется.

Более подробно сможет рассказать Михаил88, когда сюда заглянет.

Михаил88

#71
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
+ Благодарностей: 3

streamdown

Цитата: Михаил88 от 09.07.22, 17:11:10Компасовский документ можно открыть с помощью архиватора.
Ах вооот оно что. В примерах я такого не видел, а в справке...да вы и сами знает как там оно в справке у Компаса)))
Спасибо!