Как через APIv7 читать/писать атрибуты документов?

Автор Ugin, 19.10.07, 12:45:02

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

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

Ugin

В компас3д  в меню файл/свойства/атрибуты можно добавить/удалить/изменить дополнительные атрибуты документа
как эти атрибуты прочитать/записать через API 7-ой версии? (ну или 5-ой, но для файлов a3d/m3d)

333

См CreateAttrIterator
для 3D документа можно еще через IDocument3D::AttributeCollection

ugin

спасибо за совет, но как прочитать значения с их помощью все равно не разбрался
в API7 таких функций нет вообще,
CreateAttrIterator  - это функции dll есть ее аналог ksCreateAttrIterator
как получить его вроде разобрался,
но как из него получить название атрибута и значения так и не понял  :`(

Ugin

как прочитать значение таки разобрался :) благодаря найденому примеру на форуме
а вот как узнать название атрибута пока неясно...

333

У атрибута можно получить только номер типа атрибута и ключи
См GetAttrKeysInfo
далее можно использовать ksGetAttrType
Но нужно знать имя библиотеки типов.

Ugin

спасибо за помощь.

не поможете победить еще один нюанс?
есть пример SDK\Pascal\DELPHIAUTO\step3d2\step3D21.pas

там есть процедура:
procedure GetSetUserParamComponent;
var
  part: ksPart;
  par: ksUserParam;
  item: ksLtVariant;
  arr: ksDynamicArray;
  par2: ksUserParam;
  item2: ksLtVariant;
  arr2: ksDynamicArray;
  a: double;
  b: double;
  c: integer;
  d: integer;
begin
   if iDocument3D.IsDetail then
  begin
      iKompasObject.ksError('Текущий документ должен быть сборкой');
      exit;
  end;

  part := ksPart( iDocument3D.GetPart(0) ); // первая деталь в сборке
   par := ksUserParam( iKompasObject.GetParamStruct(ko_UserParam) );
  item := ksLtVariant( iKompasObject.GetParamStruct(ko_LtVariant) );
   arr := ksDynamicArray( iKompasObject.GetDynamicArray(LTVARIANT_ARR) );
   if ( par = nil ) or ( item = nil ) or ( arr = nil ) or ( part = nil ) then
      exit;

   par.Init();
   par.SetUserArray( arr );
   item.Init();
     item.doubleVal := 12.12;
     arr.ksAddArrayItem( -1, item );
   item.Init();
     item.DoubleVal := 21.21;
      arr.ksAddArrayItem( -1, item );
  item.Init();
     item.IntVal := 666;
     arr.ksAddArrayItem( -1, item );
  item.Init();
     item.IntVal := 999;
     arr.ksAddArrayItem( -1, item );

   part.SetUserParam(par); // установка пользовательской структуры
   part.Update();

  // размер пользовательской структуры
   iKompasObject.ksMessage( Format('Размер пользовательской структуры %d', [ part.GetUserParamSize() ] ) );


если я точно этот код копирую в свое тестовое приложение
(в нем переписано только подключение к Kompas - iKompasObject := GetActiveOleObject('KOMPAS.Application.5') as KompasObject;)
то строка :
part.SetUserParam(par);
не срабатывает (возвращает false)
и последующий вызов GetUserParamSize тоже возвращает 0

333

Пользовательские параметры может записывать только прикладная библиотека. .rtw или .dll
Кроме самой пользовательской информации в параметрах запоминается номер команды, имя библиотеки и путь к библиотеке.
Если их явно не задать то запоминается текущая рабочая библиотека. Но при работе контроллера нет рабочей библиотеки и поэтому параметры не записюваются.
Вы можете код из Контроллера(.exe)  перенести в отдельную dll и из контроллера подгрузить данную dll как прикладную библиотеку непосредственно в Компас. Выполнить нужные действия вызывая команды из Вашей dll и выгрузить dll
К томуже код будет работать гораздо быстрее т.к. dll будет находиться в одном адресном пространстве с Компасом.
См функции
KompasObject::ksAttachKompasLibrary
KompasObject::ksExecuteKompasLibraryCommand
KompasObject::ksExecuteKompasLibraryCommandEx
KompasObject::ksGetExternalInterface
KompasObject::ksDetachKompasLibrary

Причем функция KompasObject::ksExecuteKompasLibraryCommandEx позволяет передать в библиотеку интерфейс связи через который можно будет передавать данные из контроллера в библиотеку и из библиотеки в контроллер.

Пример для функций ksAttachKompasLibrary ksExecuteKompasLibraryCommand ksDetachKompasLibrary есть в SDK




Ugin

вот как оно оказывается  8-)
примера в SDK не нашел к сожалению, но в принципе как подключать и вызывать разобрался и сам.
не ясно только куда и как при использовании ksExecuteKompasLibraryCommandEx(libid,123,MyDispatchData)

( точнее я использую аналог - IApplication.LibraryManager.ProceduresLibraries
  • .Execute(123,MyDispatchData))
    передается MyDispatchData?
    как внутри библиотеки получить к этому объекту доступ?

333



Ugin

Почему иногда в коде вида:
        if ki.ksCreateAttrIterator(ref,0,0,0,0,0) then
        begin
          variable := 0;
          pAttr := ki.ksMoveAttrIterator('F', variable);
          while pAttr <> 0 do
          begin
            k := attr.ksGetAttrKeysInfo(pAttr,k1,k2,k3,k4,tt);
            ....

иногда не срабатывает attr.ksGetAttrKeysInfo ?
хотя атрибут там точно есть, паролей на него никаких нет..

Ugin

Вот локализовал глюк, кто нибудь может пояснить - я виноват (в чем?) или компас (как быть?):

var
  d1,d2: ksDocument3D;
  attr1, attr2: ksAttributeObject;
  attrPar1, attrPar2: ksAttributeParam;
  pAttr, res, rowsCount, columnsCount: integer;
  tip: double;
begin
  DeleteFile('c:\temp\d1.m3d');
  DeleteFile('c:\temp\d2.m3d');
  d1 := ksDocument3D(KompasApp2.Document3D);
  if d1.Create(false,true) then
    d1.SaveAs('c:\temp\d1.m3d')
  else
    raise Exception.Create('e1');
  d2 := ksDocument3D(KompasApp2.Document3D);
  if d2.Create(false,true) then
    d2.SaveAs('c:\temp\d2.m3d')
  else
    raise Exception.Create('e2');

  attr1 := ksAttributeObject(KompasApp2.GetAttributeObject);
  tip := 2.75033446165000e+011;
  attrPar1 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
  pAttr := attr1.ksCreateAttr(d1.Reference,attrPar1,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
  if pAttr <> 0 then
  begin
    res := attr1.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
    if res <> 0 then
    begin
      log('error1');
      log(KompasApp2.ksStrResult);
    end;
  end;
  attr2 := ksAttributeObject(KompasApp2.GetAttributeObject);
  attrPar2 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
  pAttr := attr2.ksCreateAttr(d2.Reference,attrPar2,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
  if pAttr <> 0 then
  begin
    res := attr2.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
    if res <> 0 then
    begin
      log('error2');   
      log(KompasApp2.ksStrResult);
    end;
  end;
end;

в логе будет ошибка "error2" - почему непонятно  :`(

Ugin

упс, сверху код чуть чуть неправильный.. на самом деле ошибка будет "error1"
вот код:
....
  attr1 := ksAttributeObject(KompasApp2.GetAttributeObject);
  tip := 2.75033446165000e+011;
  attrPar1 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
  pAttr := attr1.ksCreateAttr(d1.Reference,attrPar1,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
  if pAttr <> 0 then
  begin
    res := attr1.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
    if res = 0 then  // <- тут было неверное условие
    begin
      log('error1');
      log(KompasApp2.ksStrResult);
    end;
  end;

  attr2 := ksAttributeObject(KompasApp2.GetAttributeObject);
  attrPar2 := ksAttributeParam(KompasApp2.GetParamStruct(ko_Attribute));
  pAttr := attr2.ksCreateAttr(d2.Reference,attrPar2,tip,'C:\Program Files\ASCON\KOMPAS-3D V9\Sys\spds.lat');
  if pAttr <> 0 then
  begin
    res := attr2.ksGetAttrTabInfo(pAttr, rowsCount, columnsCount);
    if res = 0 then  // <- тут было неверное условие
    begin
      log('error2');
      log(KompasApp2.ksStrResult);
    end;
  end;

и в лог пишется:
error1
Невозможно создать документ. Документ с таким именем уже открыт.