Тема: Печать всех layout'ов документа

Пишу программу для автоматизации печати документов в PDF. Отрывок кода:

  AutoCAD:=CreateOleObject('AutoCAD.Application');
  AutoCAD.Documents.Open(edSource.Text);
  AutoCAD.Visible:=true;
  WinExec('wscript.exe "D:\Program Files\Borland\Delphi7\Projects\PDF\dlg.js" "d:\test\doc.pdf"',SW_SHOWNORMAL);  // это скрипт, который работает с диалоговым окном принтера PDF (название документа вводит, кнопки нажимает)
  AutoCAD.ActiveDocument.Plot.PlotToDevice('Adobe PDF');
  AutoCAD.ActiveDocument.Close(True,'D:\doc.pdf');
  AutoCAD.Quit;

Всё бы было хорошо, если бы не одно НО: печатается лишь активный layout. А мне нужно чтобы в один PDF-документ распечатались все layout'ы.
После долгих исканий наткнулся на метод SetLayoutsToPlot в интерфейсе IPlot. Может он мне поможет? Был бы признателен, если бы кто-нибудь объяснил как с этим методом работать или вообще подсказал решение моей проблемы. Весия AutoCAD 2004

Re: Печать всех layout'ов документа

Попробуй программно копировать все объекты в один Layout, печатать, потом делать UNDO.

Re: Печать всех layout'ов документа

короче я нашёл несколько примеров с этим методом. Он действительно делает то, что мне нужно. В качестве параметра ему передаётся либо строка, либо массив строк (строки - это имена layout'ов). На VBA задать такой массив и передать его методу проще простого (примеры для VBA были). В Delphi я создал вариантный массив (OleVariant) типа varOleStr и поместил в него имена всех layout'ов. Однако при попытке передать этот массив в качесте параметра выскакивает ошибка "Параметр задан неверно". Что я делаю нетак? И чем массив строк в VBA отличается от вариантного массива в Delphi?

Re: Печать всех layout'ов документа

> Илья
Это немного не то, что мне нужно. Мне необходимо распечатать не на одну страницу, а в один многостраничный документ.

Re: Печать всех layout'ов документа

Ясно. Для трех layoutов будет так:
varvar1:=VarArrayCreate([0,2],varolestr );  //varvar1:olevariant
varvar1[0]:='lay1';
varvar1[1]:='lay2';
varvar1[2]:='lay3';
AcadDocument1.Plot.SetLayoutsToPlot(varvar1);

Re: Печать всех layout'ов документа

> Илья
Это действительно работает? Просто я два поста выше писал, что сделал то же самое и получил при этом сообщение об ошибке. Может проблема в том, что я не импортировал библиотеку типов?

Re: Печать всех layout'ов документа

Это конечно не исчерпывает темы, но я нашёл пусть даже и кривой, но выход:
1. Поочерёдно делать активными все layout'ы
2. Печатать их по одному во временную директорию
3. Склеить их через ADOBE PDF Maker (я просмотрел интерфейсы и методы - там вроде это просто сделать)

Re: Печать всех layout'ов документа

По поводу 3-го пункта - ошибочка вышла - не в мэйкере а в самом акробате.
Тем не менее очень интересно узнать как можно сконвертировать, используя лишь объект автокада (то что предложил Илья у меня не работает).

Re: Печать всех layout'ов документа

А какая ошибка выскакивает? У меня всё работает, как на дельфе 5, так и на си++ 5.3, библиотека типов от 2006 автокада

Re: Печать всех layout'ов документа

Если не лень, скидывай мне кусок программы на мыло, просто ради спортивного интереса.

Re: Печать всех layout'ов документа

Ошибся,не на 5 а на дельфе 7 работает

Re: Печать всех layout'ов документа

Можно поподробнее на счет "не импортировал библиотеку типов", не импортировал вообще? Работают ли другие обращения к автокаду в этой программе? Как ты подключался к автокаду в программе? Ошибка возникает при подстановке массива varolestr в SetLayoutsToPlot(olevariant)? или в другом месте?

Re: Печать всех layout'ов документа

Не импортировал вообще. Просто обращаюсь с автокадом, как с обычным COM-объектом. Остальные обращения вполне работают. Ошибка "Параметр задан неверно" возникает во время подстановки в качестве параметра вариантного массива.
На всякий случай кусок программы побольше:

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, XPMan, ComCtrls, ComObj, ExtCtrls;
//----------------------------------------------//
var
  frmMain: TfrmMain;
  //----Variants
  AutoCAD: Variant;
  //----
procedure TfrmMain.btnConvertClick(Sender: TObject);
var
  a,layouts: olevariant;
  i: integer;
begin
  AutoCAD:=CreateOleObject('AutoCAD.Application');
  AutoCAD.Documents.Open(edSource.Text);
  AutoCAD.Visible:=true;
  layouts:=VarArrayCreate([0,AutoCAD.ActiveDocument.Layouts.Count-1],varOleStr);
  for i:=0 to AutoCAD.ActiveDocument.Layouts.Count-1 do
  begin
    a:=i;
    layouts[i]:=AutoCAD.ActiveDocument.Layouts.Item(a).Name;
  end;
  AutoCAD.ActiveDocument.Plot.SetLayoutsToPlot(layouts);
  WinExec('wscript.exe "D:\Program Files\Borland\Delphi7\Projects\PDF\dlg.js" "d:\test\test.pdf"',SW_SHOWNORMAL);
  AutoCAD.ActiveDocument.Plot.PlotToDevice('Adobe PDF.pc3');
  AutoCAD.ActiveDocument.Close(True,'D:\doc.pdf');
  AutoCAD.Quit;
end;

Re: Печать всех layout'ов документа

var autocad:iacadapplication;
varvar1:olevariant;
begin
AutoCAD:=CreateOleObject('AutoCAD.Application') as iacadapplication; //Единственная ошибка которая возникала у меня несовместимость типов IDispatch и IAcadApplication, если не дописывать as iacadapplication как указано в исходном примере.
AutoCAD.Visible:=true;
varvar1:=VarArrayCreate([0,2],varolestr );
varvar1[0]:='lay1';
varvar1[1]:='lay2';
varvar1[2]:='lay3';
AutoCAD.ActiveDocument.Plot.SetLayoutsToPlot(varvar1);
end;

Re: Печать всех layout'ов документа

Точно! у меня тоже выскочила ошибка как и у тебя,
если объявить AutoCAD как Variant. Сделай его IacadApplication и AutoCAD:=CreateOleObject('AutoCAD.Application') as iacadapplication; как в моём примере.

Re: Печать всех layout'ов документа

Хм...Теперь AutoCAD.Documents.Open(edSource.Text) не работает - пишет, что недостаточно параметров.

Re: Печать всех layout'ов документа

Мда...не то это - всё равно по одному layout'ы печатаются. Значит, придётся в акробате склеивать (хотя я вот попробовал - ошибок не наблюдал, но ничего и не склеилось).

Re: Печать всех layout'ов документа

Лучше импортни ты эту библиотеку, хотя бы параметры функций будут на виду и гемороя меньше, про VB-шный хэлп забыть можно будет.
AutoCAD.Documents.Open('c:\q.dwg',emptyparam,emptyparam);
emptyparam-ы olevariant-здесь пустой параметр,а вообще первый отвечает за readonly второй password.
Черт бы их побрал эти layoutы, не судьба наверное.

Re: Печать всех layout'ов документа

Ну я написал процедуру для склеивания. Кому интересно:

procedure MergePages(name: strg; n: integer); //name - имя выходнонго файла, n - число layout'ов
var
  AcroApp: Variant;
  PDDoc: Variant;
  InsertPDDoc: Variant;
  iNumberOfPagesToInsert: Integer;
  iLastPage: Integer;
  i: integer;
begin
  AcroApp:=CreateOleObject('AcroExch.App');
  PDDoc:=CreateOleObject('AcroExch.PDDoc');
  InsertPDDoc:=CreateOleObject('AcroExch.PDDoc');
  AcroApp.Hide;
  PDDoc.Create;
  for i:=1 to n do
  begin
    InsertPDDoc.Open('D:\test\'+inttostr(i)+'.pdf'); //здесь указана временная папка, куда автокад печатает layout'ы (он их называет 1.pdf,2.pdf,...)
    iLastPage:=PDDoc.GetNumPages-1;
    iNumberOfPagesToInsert:=InsertPDDoc.GetNumPages;
    PDDoc.InsertPages(iLastPage,InsertPDDoc,0,iNumberOfPagesToInsert,False);
    InsertPDDoc.Close;
  end;
  PDDoc.Save(1,name);
  PdDoc.Close;
end;

Теперь проблема в другом - не все layout'ы умещаются на своих страницах. Может кто-нибудь сталкивался и решал эту проблему?
Кстати, выражаю благодарность Илье - после импорта всё заработало.

Re: Печать всех layout'ов документа

ALayout.StandardScale := acScaleToFit;