Механизм пакетной печати

 

Механизм пакетной печати описывается на примере печати счетов, для распечаток этот механизм аналогичен. Необходимость в этом механизме возникла в основном из-за возможности связывания с одним объектом базы данных сразу нескольких шаблонов, но при печати должен выбраться один конкретный шаблон. В нашем случае, объектом базы данных является таблица bills (платёжные документы). А шаблон определяется по правилам: для каждого клиента, либо для группы клиентов, либо по умолчанию можно задать какой шаблон использовать, если платёжный документ относится к тому или иному типу (Акт/Счёт/Счёт фактура), если указан оператор, или по другим параметрам.

 

1.Сначала пользователю предлагается выделить один, или несколько счетов (на примере приложения plBill, выделять можно с помощью (Ctrl+A), либо мышкой и клавишами (Shift и Ctrl)).

 

2.Затем пользователь нажимает Просмотр, Печать или Отправить по почте, для механизма пакетной печати – это не важно.

 

3.Особенность при печати счетов из приложения plBill. В настройках plAdmin > Справочники \ Глобальные параметры имеются опции:

Настройки интерфейса \ Запрашивать кол-во копий;

Настройки интерфейса \ Запрашивать параметры.

 

Глобальные параметры для механизма пакетной печати

Глобальные параметры для механизма пакетной печати

 

Соответственно, при включении этих опций можно дополнительно указать кол-во копий для каждого шаблона, и передать дополнительные параметры, которые настраиваются в приложении plBill > Справочники \ Параметры отчётов. Эти параметры будут передаваться в отчёты и их можно анализировать в скрипте шаблона.

 

4.Приложение заполняет временную таблицу bills_report_tmp: записи в этой таблице соответствует выделенным счетам в приложении; поле bill_id содержит ссылку на счёт (bills.bill_id), поле report_id – ссылку на шаблон (reports.report_id). Здесь следует обратить внимание на то, что в этой таблице bills_report_tmp значения в поле bill_id будут уникальны, а значения report_id будут повторяться (уникальных значений будет ровно столько, сколько разнообразных шаблонов будет использовано). Так как таблица временная, то она доступна только в текущей сессии приложения, «подсмотреть» эти данные из других приложений не получится. (Отличия для распечаток: вместо bills_report_tmp используется lists_report_tmp, вместо bill_id – поле sg_id, которое ссылается на service_groups.service_group_id.)

 

5.Приложение считывает временную таблицу и запускает механизм формирования отчётов следующим образом:

Инициализируется список задействованных шаблонов (т.е. он пустой).

Запускается цикл по записям временной таблицы:

 

Смотрится поле report_id, ищется соответствующий шаблон в списке. Если шаблон не найден – шаблон загружается из базы данных или кэша, и запускается на исполнение первый раз: в него передаётся параметр <report_id> и выполняется секция begin – end. скрипта шаблона. В этой секции имеет смысл указанный параметр определить как условие для исполняемых запросов к БД, затем выполнить эти запросы. Дальше запросы к БД выполнятся не должны.

Вот пример секции begin – end.:

 

begin
  bills_report_tmp.WhereCondition := <report_id>;
  bills.WhereCondition := <report_id>;
  bill_entries.WhereCondition := <report_id>;
 
  bills_report_tmp.Open;
  bills.Open;
  bill_entries.Open;
end.

 

Теперь шаблон в списке есть, он запускается на исполнение второй, третий и т.д. раз, здесь в отчёт передаётся параметр <bill_id> и запускается обработчик frxReportOnRunDialogs, в котором следует этот параметр обработать, например, так:

 

procedure frxReportOnRunDialogs(var Result: Boolean);
var
  R: TbuRecord;
begin
  // поиск записи в наборе данных по bill_id
  Result := bills_report_tmp.Locate('bill_id', [<bill_id>], R);
  // если нашли, то установка этой записи как текущей
  if Result then
    bills_report_tmp.CurrentRecord := R;
  // если не нашли, то дальше прогон шаблона прекращается 
  // до следующей итерации механизма пакетной печати
end;

 

После отработки цикла сформированные отчёты отображаются на экране (или печатаются).

 

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

1.Во вкладке Данные шаблона необходимо подготовить наборы данных:

 

bills_report_tmp, это набор данных, который делает простую выборку из базы по такому запросу:

 

SELECT bill_id 
 FROM bills_report_tmp 
 WHERE report_id = %where%

 

здесь в условие %where% будет подставлен report_id этого шаблона.

 

bills, это набор данных, выбирающий из базы выделенные пользователем счета, но с ограничением по данному шаблону. Запрос может быть таким:

 

SELECT b.bill_id, b.*, c.name client_name
  FROM bills_report_tmp brt, bills b, clients c
 WHERE brt.report_id = %where%
   AND b.bill_id = brt.bill_id
   AND c.client_id = b.client_id

 

Также для набора данных bills необходимо указать master-detail отношение к набору bills_report_tmp, это делается через свойства:

 

Master = bills_report_tmp
MasterFKFields = bill_id
MasterPKFields = bill_id

 

Указание этого отношения необходимо, чтобы при прогоне шаблона был сформирован только один отчёт по текущей записи bills_report_tmp, которая определяется в обработчике frxReportOnRunDialogs по передаваемому в шаблон параметру <bill_id>.

bill_entries, содержит детализацию по счёту (статьи счёта), запрос может быть таким:

 

SELECT be.bill_id, be.*
  FROM bills_report_tmp brt, bill_entries be
 WHERE brt.report_id = %where%
   AND be.bill_id = brt.bill_id

другие наборы данных, при необходимости.

 

Т.к. для этих наборов данных report_id заранее не известен, то для них надо указать свойство OpenDataSource = False, и открывать их в коде в секции begin – end. (см. выше)

 

2.Во вкладке Код необходимо прописать реакцию на передаваемые параметры <report_id> и <bill_id>, как это можно сделать указано выше. Здесь следует иметь ввиду, что обработчик frxReportOnRunDialogs должен быть связан с объектом Report шаблона; в плавающей панели Дерево отчёта этот объект находится на верхнем уровне:

 

 

3.Создавать диалоговые формы нет смысла, они будут игнорироваться.

 

4.Дальше создаются страницы отчёта (вкладка Page1) обычным образом.

 

Примечание

Наличие в шаблоне набора данных bills_report_tmp не является необходимым для работы механизма пакетной печати. Вместо него, в самом шаблоне, можно в качестве Master-набора данных использовать bills. Однако разработчик рекомендует использовать эту избыточность для того, чтобы сразу было видно предназначение шаблона именно для пакетной печати.