Событие страницы OnManualBuild

       Построением отчета обычно занимается ядро FastReport. Оно выводит бэнды отчета в определенной последовательности столько раз, сколько имеется данных, формируя таким образом готовый отчет. Иногда необходимо вывести отчет нестандартной формы, который ядро FastReport сформировать не в состоянии. В этом случае можно воспользоваться возможностью построения отчета вручную, с помощью события OnManualBuild, имеющегося у страницы отчета. Если определить обработчик этого события, ядро FastReport при формировании страницы передаст управление ему. При этом ядро отчета автоматически выводит имеющиеся на странице бэнды "Заголовок отчета", "Заголовок страницы", "Заголовок колонки", "Подвал отчета", "Подвал страницы", "Подвал колонки", "Фон". Ядро также обрабатывает формирование новых страниц/колонок. Задача обработчика события OnManualBuild – вывести в определенном порядке дата-бэнды и их заголовки/подвалы.

 

       Т.е., суть обработчика OnManualBuild состоит в том, чтобы давать ядру FastReport команды на вывод определенных бэндов. Все остальное ядро сделает самостоятельно: сформирует новую страницу, когда место на текущей закончится, выполнит скрипты, прикрепленные к событиям и т.д.

 

       Приведем пример простого обработчика. В отчете имеется два бэнда master data, не подключенных к данным:

 

clip0192

 

       Обработчик выведет эти бэнды в чередующемся порядке, каждый по 6 раз. После шести бэндов будет сделан небольшой промежуток.

 

PascalScript:

 

procedure Page1OnManualBuild(Sender: TfrxComponent);

var

i: Integer;

begin

for i := 1 to 6 do

begin

   { выводим бэнды друг за другом }

   Engine.ShowBand(MasterData1);

   Engine.ShowBand(MasterData2);

   { делаем небольшой промежуток }

   if i = 3 then

     Engine.CurY := Engine.CurY + 10;

end;

end;

 

C++ Script:

 

void Page1OnManualBuild(TfrxComponent Sender)

{

int i;

 

for (i = 1; i <= 6; i++)

{

   // выводим бэнды друг за другом

   Engine.ShowBand(MasterData1);

   Engine.ShowBand(MasterData2);

   // делаем небольшой промежуток

   if (i == 3)

     Engine.CurY = Engine.CurY + 10;

}

}

 

 

_img267

 

 

       Следующий пример выведет две группы бэндов рядом друг с другом.

 

PascalScript:

 

procedure Page1OnManualBuild(Sender: TfrxComponent);

var

i, j: Integer;

SaveY: Extended;

begin

SaveY := Engine.CurY;

for j := 1 to 2 do

begin

   for i := 1 to 6 do

   begin

     Engine.ShowBand(MasterData1);

     Engine.ShowBand(MasterData2);

     if i = 3 then

       Engine.CurY := Engine.CurY + 10;

   end;

   Engine.CurY := SaveY;

   Engine.CurX := Engine.CurX + 200;

end;

end;

 

 

C++Script:

 

void Page1OnManualBuild(TfrxComponent Sender)

{

int i, j;

Extended SaveY;

 

SaveY = Engine.CurY;

for (j = 1; j <= 2; j++)

{

   for (i = 1; i <= 6; i++)

   {

     Engine.ShowBand(MasterData1);

     Engine.ShowBand(MasterData2);

     if (i == 3)

       Engine.CurY = Engine.CurY + 10;

   }

   Engine.CurY = SaveY;

   Engine.CurX = Engine.CurX + 200;

}

}

 

_img268

 

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

 

       Наконец, покажем, как построить отчет типа "Список клиентов" (мы его строили неоднократно по ходу данной книги) с помощью события OnManualBuild. В нашем примере подключим дата-бэнд к источнику данных.

 

_img269

 

       Скрипт события следующий:

 

PascalScript:

 

procedure Page1OnManualBuild(Sender: TfrxComponent);

var

DataSet: TfrxDataSet;

begin

DataSet := MasterData1.DataSet;

DataSet.First;

while not DataSet.Eof do

begin

   Engine.ShowBand(MasterData1);

   DataSet.Next;

end;

end;

 

C++Script:

 

void Page1OnManualBuild(TfrxComponent Sender)

{

TfrxDataSet DataSet;

 

DataSet = MasterData1.DataSet;

DataSet.First();

while (!DataSet.Eof)

{

   Engine.ShowBand(MasterData1);

   DataSet.Next();

}

}

 

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

 

DataSet := MasterData1.DataSet;

 

вернет ссылку на источник данных. Получить ссылку на нужный источник можно и так:

 

DataSet := Report.GetDataSet('Customers');

 

       Естественно, интересующий нас источник должен быть добавлен в отчет в диалоге "Отчет|Данные...".