Пакетная печать...

отредактировано 01:34 Раздел: FastReport 2.xx VCL
Мир вашему дебаггеру!

Никак не могу прийти к решению следующей задачи. ;)

Есть куча отчетов *.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 к отчету?

Заранее спасибо за ответы. ;)

Комментарии

  • отредактировано 01:34
    Про разные датасеты - не совсем понятно. Что, [cds_TMP2."COM_DOCUMENT_NUMBER"] в разных отчетах - это не одно и то же?
  • отредактировано 01:34
    AlexTZ написал:
    Про разные датасеты - не совсем понятно. Что, [cds_TMP2."COM_DOCUMENT_NUMBER"] в разных отчетах - это не одно и то же?
    Дело в том, что в одном отчете могут быть такие ссылки:

    [cds_TMP1."COM_DOCUMENT_NUMBER"]
    [cds_TMP2."COM_DOCUMENT_NUMBER"]
    (в одном отчете сцылки на разные датасеты)

    Но это, наверно, не главное. Для разных отчетов cds_TMP1 (датасеты) - разные (разные запросы, возвращающие разные наборы полей и строк)... И вот надо запихнуть разные отчеты в одно задание на печать. ;)

    В датасетах идет обычно одна строка. Отчетов много, многие есть наследие прошлого, но однако никаким образом их нельзя менять.

    Фактически, речь идет о том, как грамотно использовать TfrReport в режиме runtime в рамках указанных условий (четкое указание имени датасета в поле).

    PS Задача вроде бы стандартная - запустить несколько документов на печать потоком (imho было бы многим полезно иметь такой механизм). У меня была смешная идея: готовим отчет, сохраняем его в файл frp, а потом на лету создаем множество отчетов runtime, в которые грузим готовые frp и каждый такой отчетик складываем в композитный отчет. Все бы ничего, но такой вариант не проходит ;) Композитный отчет пуст.

    Спасибо за быстрый ответ. Задача очень насущная. ;)
  • FOXFOX
    отредактировано 01:34
    А кто мешает сформированные файлы (frp) "склеить" в один и его
    распечатать?
  • отредактировано 01:34
    Можно и склеивать, только не композитным отчетом, а frReport1.EMFPages.AddFrom(frReport2)
  • dondon
    отредактировано 01:34
    Есть небольшое предложение:
    При печати пакета документов с разными параметрами страниц происходит
    следующее:
    При смене размеров и ориентации страниц 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, в первом формирую отчеты, во втором показываю пользователю.

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.