Код для массового перименования позиций

Автор Sprinter500, 22.03.13, 20:25:41

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

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

  //disp := IDispatch( CreateKompasApplication );
     //newKompasAPI := disp As IApplication;
     newKompasAPI:=CreateOleObject('Kompas.Application.7') as iApplication;
     pDocuments := newKompasAPI.Documents;
     //pDocument := pDocuments.Add(1,true);//(doc tupe,visible-regim)
     pDocument := newKompasAPI.ActiveDocument;
     //pKompasDocument2D :=  pDocument as iKompasDocument2D;
     pKompasDocument2D :=  pDocument as iKompasDocument2D;
Строчку выделенную жирным уберите, я код не отрабатываю, поэтому пропустил букву s, а ActiveDocument возвращает интерфейс  IKompasDocument.

Sprinter500

Все равно возникает такая ошибка:

Можете проект запустить с открытым в Компасе файлом где есть линии выноски от 1 до 3, может сразу ясно станет в чем дело?

Документ должен быть открыт, проверок у Вас нет, воспользуйтесь отладчиком, он всё покажет.

Sprinter500

И так запущен. Как этим отладчиком воспользоваться? Я недавно начал в Delphi.

Sprinter500

Отладчик - Debugger?  Выдает вот это:

Поставьте точку останова, выполняйте по шагам свою процедуру и смотрите значения получаемых переменных после каждого шага.

Sprinter500

Что то ничего толкового с точками останова не получается. Ладно уж, и на том спасибо. Остановился буквально в шаге от цели.

Что почитать на тему API7 и в целом на тему прог-ия под КОМПАС кроме справки посоветуете? А уж если кроме справки ничего нет, то по какой версии читать?


Sprinter500

Выяснил что вызывает ошибку. Первая же строка в разделе begin процедуры:

newKompasAPI:=CreateOleObject('Kompas.Application.7') as iApplication;

Наверно для приложений как то иначе надо подключать?

Sprinter500

УРА!!! Наконец то заработало! Проблема решена кодом:

...
var {модуля}
  KOMPAS :IApplicationDisp;
  ksDocs :IDocumentsDisp;
  ksDoc :IKompasDocumentDisp;
...


procedure RENM();
var
   pKompasDocument2D : IKompasDocument2D;
   pViewsAndLayersManager : IViewsAndLayersManager;
   pViews : IViews;
   pView : IView;
   pSymbols2DContainer : ISymbols2DContainer;
   pDrawingContainer : IDrawingContainer;
   pLeaders : ILeaders;
   pBaseLeader : IBaseLeader;
   pLeader : ILeader;
   pDrawingObject : IDrawingObject;
   I:integer;
   oldValue, newValue: widestring;

begin
     pKompasDocument2D :=  ksDoc as iKompasDocument2D;
     pViewsAndLayersManager := pKompasDocument2D.ViewsAndLayersManager;
     pViews := pViewsAndLayersManager.Views;
     pView := pViews.ViewByNumber[1];
     pView.Current := true;
     pDrawingContainer := pView as iDrawingContainer;
     pSymbols2DContainer := pView as iSymbols2DContainer;
     pLeaders:= pSymbols2DContainer.Leaders;

oldValue:='2';
newValue:='5';

for I:=0 to pLeaders.Count-1 do
   begin
     pDrawingObject:=pLeaders.Item[1];
     if pDrawingObject<>nil then
        begin
            if pDrawingObject.DrawingObjectType=ksDrLeader then
                begin // Простая линия-выноска
                    pLeader:=pDrawingObject as ILeader;
                    if pLeader<>nil then
                        begin
                            if pLeader.TextOnShelf.Str=oldValue then
                                begin
                                  pLeader.TextOnShelf.Str:=newValue;
                                  pDrawingObject.Update;
                                end;
                            pLeader:=nil;
                        end;
                end;
        end;
   end;


end;

procedure STRT();
begin
  TRY
    //KOMPAS:=CreateOleObject('KOMPAS.Application.7') as IApplicationDisp;
    //KOMPAS.Visible:=TRUE;
    KOMPAS:=GetActiveOleObject('KOMPAS.Application.7') as IApplicationDisp;
    ShowMessage('КОМПАС запущен');
  EXCEPT
    KOMPAS:=nil;
  END;
end;

procedure OPF();
begin
  TRY
    //sDocs:=IDocumentsDisp(KOMPAS.Documents);
    ksDocs:=IDocumentsDisp(KOMPAS.ActiveDocument);
    //ksDoc:=IKompasDocumentDisp( ksDocs.Open('D:\Study\dr.cdw', TRUE, FALSE) );
    ksDoc:=IKompasDocumentDisp(ksDocs);
    RENM();
    ShowMessage('Открыли документ');
  EXCEPT
    ksDocs:=nil;
    ksDoc:=nil;
  END;
end;

//запускаем сначала STRT(); потом OPF();

Необходимый участок кода взял с ветки: http://forum.ascon.ru/index.php/topic,3363.msg19673.html#msg19673   пост Olegon. Спасибо ему и Sabahs. Осталось самое приятное - написать функционал самой программа. Всем помогавшим - вышлю готовую программу.

Sprinter500

В нем есть строка:
ksDoc :IKompasDocumentDisp;

Почему то в справке по SDK нет ничего о  IKompasDocumentDisp;
:)

Однако приведенный в предыдущем посте код рабочий (хотя показан не весь - остальное можно найти в выложенном ранее проекте).

Sprinter500

Как быть с заменой текста в линиях-выносках, решили. А вот, еще вопрос знатокам: как реализовать замену вертикального текста в таблице? да и вообще в целом любого текста в таблице.

Стандартная замена в прикладной библиотеке Компаса не работает на вертикальном тексте.

Цитата: Sprinter500 от 14.04.14, 18:08:46
Выяснил что вызывает ошибку. Первая же строка в разделе begin процедуры:

newKompasAPI:=CreateOleObject('Kompas.Application.7') as iApplication;

Наверно для приложений как то иначе надо подключать?
У меня таких проблем нет.
+ Благодарностей: 1

Sprinter500

Это у тебя для EXE скрин (так как Form1 есть) или все таки для RTW. Я так полагаю их по разному надо подключать. Пришли пож-та тот проект, что запечатлен на скриншоте - потестирую, может и у меня без проблем запустится? ))) А так проблема решена уже в принципе. Но все таки хочется знать "почему", если у тебя работает а у меня нет.

Может для Exe надо так же настройки проекта вносить как для RTW?:

2. В настройках проекта установить выравнивание: выключить опцию
Project Options - Compiler - Code Generation - Aligned Record fields.

Это из справки.

Для Exe, для rtw делается иначе. Весь проект на первом рисунке, плюс сам проект.
+ Благодарностей: 1

Цитата: Sprinter500 от 14.04.14, 20:40:51
Как быть с заменой текста в линиях-выносках, решили. А вот, еще вопрос знатокам: как реализовать замену вертикального текста в таблице? да и вообще в целом любого текста в таблице.

Стандартная замена в прикладной библиотеке Компаса не работает на вертикальном тексте.
Вертикальный текст обсуждался здесь http://forum.ascon.ru/index.php/topic,24881.msg180076.html#msg180076
+ Благодарностей: 1

Sprinter500

Спасибо. А по номеру строки и столбца возможно ли организовать чтение текста из ячеек таблицы Компаса? И как быть с объединенными ячейками?

Sprinter500

Цитата: Sabahs от 14.04.14, 21:22:26
У меня таких проблем нет.

Да. Ты прав. У меня тоже нет. Ситуация прояснилась - вместо:
newKompasAPI:=CreateOleObject('Kompas.Application.7') as iApplication;
для уже запущенного Компаса (а именно так мне надо было) надо:
newKompasAPI:=GetActiveOleObject('Kompas.Application.7') as iApplication;

К тому же не надо было связываться с диспетчером iDispatch - это похоже только для библиотек.
Вот пример более простого рабочего кода с исправленными ошибками:

procedure TForm1.Button1Click(Sender: TObject);
var
   newKompasAPI: iApplication;
   disp : IDispatch;
   pDocuments : iDocuments;
   pDocument : IKompasDocument;
   pKompasDocument2D : IKompasDocument2D;
   pViewsAndLayersManager : IViewsAndLayersManager;
   pViews : IViews;
   pView : IView;
   pSymbols2DContainer : ISymbols2DContainer;
   pDrawingContainer : IDrawingContainer;
   pLeaders : ILeaders;
   pBaseLeader : IBaseLeader;
   pLeader : ILeader;
   pDrawingObject : IDrawingObject;

   I:integer;
   oldValue, newValue: widestring;
begin
     newKompasAPI:=GetActiveOleObject('Kompas.Application.7') as iApplication;
     pDocuments := newKompasAPI.Documents;
     pDocument := newKompasAPI.ActiveDocument;
     pKompasDocument2D :=  pDocument as iKompasDocument2D;
     pViewsAndLayersManager := pKompasDocument2D.ViewsAndLayersManager;
     pViews := pViewsAndLayersManager.Views;
     pView := pViews.ViewByNumber[1];
     pView.Current := true;
     pDrawingContainer := pView as iDrawingContainer;
     pSymbols2DContainer := pView as iSymbols2DContainer;
     pLeaders:= pSymbols2DContainer.Leaders;

oldValue:='2';
newValue:='5';

for I:=0 to pLeaders.Count-1 do
   begin
     pDrawingObject:=pLeaders.Item[1];
     if pDrawingObject<>nil then
        begin
            if pDrawingObject.DrawingObjectType=ksDrLeader then
                begin // Простая линия-выноска
                    pLeader:=pDrawingObject as ILeader;
                    if pLeader<>nil then
                        begin
                            if pLeader.TextOnShelf.Str=oldValue then
                                begin
                                  pLeader.TextOnShelf.Str:=newValue;
                                  pDrawingObject.Update;
                                end;
                            pLeader:=nil;
                        end;
                end;
        end;
   end;
end;

Sprinter500

В приведенном примере происходит замена текста для одной строки, а как быть если текст состоит из нескольких строк. Если я я правильно понял надо использовать iTextLine или iTextLines. Вопрос как? Пока не могу разобраться.

ЦитироватьВ приведенном примере происходит замена текста для одной строки, а как быть если текст состоит из нескольких строк.
Разбираться из чего состоит текст.
IText - Текст, состоит из iTextLines.
iTextLines - Массив SAFEARRAY строк текста, состоит из iTextLine.
iTextLine - Интерфейс строки текста, состоит из TextItems.
iTextItems - Массив SAFEARRAY компонентов строки текста, состоит из ITextItem.
Смотрите примеры Step1_API7_2D, Step2_API7_2D, Step3_API7_2D, чтобы понять, как устроен текст.