Пакетная печать...
Мир вашему дебаггеру!
Никак не могу прийти к решению следующей задачи.
Есть куча отчетов *.frf (выписки). Их модефицировать нельзя по организационным причинам. Они представляют из себя одностраничные документы, в которых поля могут ссылаться на разные (!) датасеты. Ссылка идет явно в виде, например:
[<span style='color:red'>cds_TMP2</span>."COM_DOCUMENT_NUMBER"]...
Все бы ничего, но печать должна идти на принтер одним заданием. Т.е. все 1500 этих документов должны выйти на сетевой принтер один за одним и другие задания на печать не должны попасть между ними. Причем, на каждый документ идет вызов своего запроса...
Задумка такая... Создается композитный отчет... На каждый документ создается в runtime свой датасет (или несколько), в отчете на лету меняем [<span style='color:red'>cds_TMP2</span>."COM_DOCUMENT_NUMBER"] на [<span style='color:red'>имя_нового_датасета</span>."COM_DOCUMENT_NUMBER"] И так до конца. Затем композитный отчет выводим на печать. Все бы ничего, но при создании в runtime TfrReport и др. компоненотов выявляются различные глюки. Например, печатается одна запись вместо всех... Версия 2.47.
Вопросы:
1. Правильно ли я нашел выход? Нет ли другого способа печатать потоком, чтобы ничего не создавать "на лету"? Если не на лету, то все работает супер. Но в этом случае я кидаю на печать по одному документу, что категорически не устраивает заказчика.
2. Если я нашел правильное решение, то как сделать это правильно? Нет ли каких-то свойств, которые надо настраивать runtime? Нужно ли подвязывать TfrDBDataset к отчету?
Заранее спасибо за ответы.
Никак не могу прийти к решению следующей задачи.
Есть куча отчетов *.frf (выписки). Их модефицировать нельзя по организационным причинам. Они представляют из себя одностраничные документы, в которых поля могут ссылаться на разные (!) датасеты. Ссылка идет явно в виде, например:
[<span style='color:red'>cds_TMP2</span>."COM_DOCUMENT_NUMBER"]...
Все бы ничего, но печать должна идти на принтер одним заданием. Т.е. все 1500 этих документов должны выйти на сетевой принтер один за одним и другие задания на печать не должны попасть между ними. Причем, на каждый документ идет вызов своего запроса...
Задумка такая... Создается композитный отчет... На каждый документ создается в runtime свой датасет (или несколько), в отчете на лету меняем [<span style='color:red'>cds_TMP2</span>."COM_DOCUMENT_NUMBER"] на [<span style='color:red'>имя_нового_датасета</span>."COM_DOCUMENT_NUMBER"] И так до конца. Затем композитный отчет выводим на печать. Все бы ничего, но при создании в runtime TfrReport и др. компоненотов выявляются различные глюки. Например, печатается одна запись вместо всех... Версия 2.47.
Вопросы:
1. Правильно ли я нашел выход? Нет ли другого способа печатать потоком, чтобы ничего не создавать "на лету"? Если не на лету, то все работает супер. Но в этом случае я кидаю на печать по одному документу, что категорически не устраивает заказчика.
2. Если я нашел правильное решение, то как сделать это правильно? Нет ли каких-то свойств, которые надо настраивать runtime? Нужно ли подвязывать TfrDBDataset к отчету?
Заранее спасибо за ответы.
Комментарии
[cds_TMP1."COM_DOCUMENT_NUMBER"]
[cds_TMP2."COM_DOCUMENT_NUMBER"]
(в одном отчете сцылки на разные датасеты)
Но это, наверно, не главное. Для разных отчетов cds_TMP1 (датасеты) - разные (разные запросы, возвращающие разные наборы полей и строк)... И вот надо запихнуть разные отчеты в одно задание на печать.
В датасетах идет обычно одна строка. Отчетов много, многие есть наследие прошлого, но однако никаким образом их нельзя менять.
Фактически, речь идет о том, как грамотно использовать TfrReport в режиме runtime в рамках указанных условий (четкое указание имени датасета в поле).
PS Задача вроде бы стандартная - запустить несколько документов на печать потоком (imho было бы многим полезно иметь такой механизм). У меня была смешная идея: готовим отчет, сохраняем его в файл frp, а потом на лету создаем множество отчетов runtime, в которые грузим готовые frp и каждый такой отчетик складываем в композитный отчет. Все бы ничего, но такой вариант не проходит Композитный отчет пуст.
Спасибо за быстрый ответ. Задача очень насущная.
распечатать?
При печати пакета документов с разными параметрами страниц происходит
следующее:
При смене размеров и ориентации страниц FastReport завершает документ,
меняет параметры и продолжает в новом документе - очень не удобно при
сетевой, многопользовательской печати - документы путаются.:-)
Для тех у кого уже эта проблема встала - вот куски кода.
FR_Class:
procedure TfrReport.DoPrintReport(PageNumbers: String; Copies: Integer;
Collate: Boolean; PrintPages: TfrPrintPages);
procedure PrintPage(n: Integer);
begin
.............
if not Prn.IsEqual(pgSize, pgWidth, pgHeight, pgBin, pgOr) then
begin
//EndDoc;
EndPage(Prn.Printer.Handle);
Prn.SetPrinterInfo(pgSize, pgWidth, pgHeight, pgBin, pgOr, True);
NewPage;
//BeginDoc;
end
.............
end;
FR_Prntr:
procedure TfrPrinter.SetPrinterInfo(pgSize, pgWidth, pgHeight, pgBin: Integer;
pgOr: TPrinterOrientation; SetImmediately: Boolean);
begin
//if FPrinter.Printing then Exit;
...............
end;
procedure TfrPrinter.SetSettings;
var
i, n: Integer;
begin
.............
If FPrinter.Printing then
ResetDC(FPrinter.Handle,FMode^)
else
FPrinter.SetPrinter(FDevice, FDriver, FPort, FDeviceMode);
finally
.............
end;
Так же TfrCompositReport у меня работать не захотел, я решил проблему
таким образом:
procedure TfrEMFPages.AddFrom(Report: TfrReport; ClearSource: Boolean = true);
var
I: Integer;
Stream: TStream;
begin
if (Report <> nil) and (Report.EMFPages.Count > 0) then
begin
Stream := TMemoryStream.Create;
try
Report.EMFPages.SaveToStream(Stream);
while Report.EMFPages.Count > 0 do
begin
FPages.Add(Report.EMFPages.FPages[0]);
Report.EMFPages.FPages.Delete(0);
end;
Stream.Position := 0;
If not ClearSource then
Report.EMFPages.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
end;
Если будут вопросы пишите, может че не учел, но у меня все работает хорошо, без глюков.
А по поводу AddFrom я использую 2 TfrReport, в первом формирую отчеты, во втором показываю пользователю.