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

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

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

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

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

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

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

Метод MacroObject.AddObjects всегда возвращает False (API ver. 7)

Автор LevYNWA, 18.09.23, 16:14:05

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

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

LevYNWA

Добрый день!

Пробую составить макрос, который будет разносить графику вида на макроэлементы.

Для этого вызываю у объекта вида типа IView интерфейс IDrawingConatiner, от которого затем получаю коллекцию макроэлементов с помощью свойства DrawingContainer.MacroObjects.

Первый вопрос, но еще не сама суть проблемы, возникает здесь:
Результат выполнения этого свойства должен возвращать указатель, на коллекцию макроэлементов вида.
Но если в поток программы вывести получаемый объект, то результат всегда будет None.
Разве не должен быть просто пустой объект коллекции, который при выводе давал бы: <win32com.gen_py. ... instance at ...>?

Далее методом Add() у коллекции создаю объект макроэлемента типа IMacroObject.

После настройки свойств макроэлемента (их подсмотрел в одной из тем, выполняю метод AddObjects().

Он должен возвращать True при успешном добавлении и False в случае неудачи.
Так вод суть проблемы: в моих "умелых" руках метод MacroObject.AddObjects() всегда возвращает False.

Прикладываю код, который использовал для проверки работы на самом простом случае: только что созданный документ с парой отрезков в виде с номером 1.

В примере кода, по очереди передаю методу все объекты вида, массив которых получен с помощью DrawingContainer.Objects(0).
В моем случае там всего лишь два объекта с типом ILineSegment.

Насколько понял тип данных, получаемый от метода DrawingContainer.Objects(0), - VARIANT[SAFEARRAY], за исключением случая, когда объект на виде всего один.
Метод AddObjects() судя по SDK работает с SAFEARRAY.

Результат метода - False.
Подскажите, пожалуйста, что делаю не так?

Код:
# -*- coding: utf-8 -*-
#|123

import pythoncom
from win32com.client import Dispatch, gencache

import LDefin2D
import MiscellaneousHelpers as MH

#  Подключим константы API Компас
kompas6_constants = gencache.EnsureModule("{75C9F5D0-B5B8-4526-8681-9903C567D2ED}", 0, 1, 0).constants
kompas6_constants_3d = gencache.EnsureModule("{2CAF168C-7961-4B90-9DA2-701419BEEFE3}", 0, 1, 0).constants

#  Подключим описание интерфейсов API5
kompas6_api5_module = gencache.EnsureModule("{0422828C-F174-495E-AC5D-D31014DBBE87}", 0, 1, 0)
kompas_object = kompas6_api5_module.KompasObject(Dispatch("Kompas.Application.5")._oleobj_.QueryInterface(kompas6_api5_module.KompasObject.CLSID, pythoncom.IID_IDispatch))
MH.iKompasObject  = kompas_object

#  Подключим описание интерфейсов 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))
MH.iApplication  = application


Documents = application.Documents
#  Получим активный документ
kompas_document = application.ActiveDocument
kompas_document_1 = kompas_api7_module.IKompasDocument1(kompas_document)
kompas_document_2d = kompas_api7_module.IKompasDocument2D(kompas_document)
iDocument2D = kompas_object.ActiveDocument2D()

ViewsAndLayersManager = kompas_document_2d.ViewsAndLayersManager
Views = ViewsAndLayersManager.Views
View = Views.ViewByNumber(1)
View_1 = kompas_api7_module.IView1(View)

DrawingContainer = kompas_api7_module.IDrawingContainer(View)
Objects = DrawingContainer.Objects(0)

MacroObjects = DrawingContainer.MacroObjects

print(MacroObjects)#вот тут всегда выводится None

MacroObject = MacroObjects.Add()
MacroObject.Command = -1
MacroObject.DoubleClickEditable = True
MacroObject.HotPointsEditable = False
MacroObject.ExternalEditable = False
MacroObject.Name = "Макроэлемент"
MacroObject.PropertyObjectEditable = False


for Object in Objects:
    res = MacroObject.AddObjects(Object)
    print(res)#а вот тут всегда выводится False

MacroObject.Update()


View.Update()

Вират Лакх

Коллекция в питоне не отображается. Её содержимое можно проверить свойством Count.
+ Благодарностей: 1

lavgirb

+ Благодарностей: 1

LevYNWA

Цитата: Вират Лакх от 19.09.23, 05:31:21Коллекция в питоне не отображается. Её содержимое можно проверить свойством Count.

Спасибо за полезную информацию! По первой части вопроса проблемы более нет:)
Заменил строку кода:
print(MacroObjects)#вот тут всегда выводится Noneна:
print(MacroObjects.Count)
Вывод изменился на "0".

Заметил особенность:
Работа макроса добавляет макроэлемент в коллекцию (собственно, как и должен).
При повторном вызове программы вывод уже "1".

Но макроэлемента в окне компаса так и не видно.

А метод AddObjects() все еще возвращает False.

Цитата: lavgirb от 19.09.23, 08:28:31Может так попробовать?
res = MacroObject.AddObjects(ObjectS)

Уже пробовал, все также.

msvteh

Цитата: LevYNWA от 19.09.23, 11:47:47Но макроэлемента в окне компаса так и не видно.
IMacroObject::SetPlacement

LevYNWA

Цитата: msvteh от 19.09.23, 20:25:26IMacroObject::SetPlacement

Попробовал, не помогает

Да и в сообщении №3 этой темы приложен файлик с кодом, который делает макроэлемент с тем же набором свойств, что у меня. Без SetPlacement'а. (оттуда я и брал пример кода, когда не получилось создать макроэлемент самостоятельно)

Разница в том, что там используется DrawingContainer самого макроэлемента, которому добавляют линии через интерфейс коллекции ILineSegments.

Мне же было бы удобнее использовать метод MacroObject.AddObjects().
Да и просто интересно понять, почему он не срабатывает

Вират Лакх

Может просто очередной косяк API. Не к новому, а к существующему макроэлементу пробовали добавить?
+ Благодарностей: 1

LevYNWA

Цитата: Вират Лакх от 20.09.23, 15:09:22Может просто очередной косяк API. Не к новому, а к существующему макроэлементу пробовали добавить?

Удивительно, но сработало! Если макрообъект непустой, то добавление происходит без проблем, и соответственно метод AddObjects() возвращает True.
И не важно, существовал ли макроэлемент до вызова макроса.

Спасибо за Ваше любопытство, которого мне не хватило в решении вопроса!
Я и не подумал попробовать добавлять объекты в непустой макроэлемент)

Примерно такой алгоритм работает:
1 Создать макроэлемент
2 Создать в нем временный "мусорный" объект, используя DrawingContainer макроэлемента. Я добавляю точку, так как в моей рабочей задаче их точно нету (они игнорируются при поиске объектов). Но в целом это не важно. Так как программа "запоминает" объект, и в шаге пять обращаясь к нему, его легко удалить.
3 Обновить макроэлемент методом Update() - важно не пропустить этот шаг, у меня без этого макроэлемент не добавляется.
4 Добавить нужную графику в макроэлемент методом AddObjects(), который теперь вернет True.
5 Удалить временный объект методом Delete().