Search Results for

    Show / Hide Table of Contents

    Построение отчета с помощью кода

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

    Ядро:

    • подготовка отчета к формированию (инициализация скрипта, источников данных, формирование дерева бэндов)

    • все вычисления (агрегатные функции, обработчики событий)

    • формирование новых страниц/колонок (автоматический вывод page/column header/footer, report title/summary)

    • прочая рутинная работа

    Обработчик:

    • вывод бэндов в определенном порядке

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

    Ядро представлено классом TfrxCustomEngine. Ссылка на экземпляр этого класса находится в свойстве TfrxReport.Engine. Ядро имеет следующие свойства и методы:

    Свойство или метод Описание
    procedure NewColumn Формирует новую колонку. Если колонка была последней, формирует новую страницу.
    procedure NewPage Формирует новую страницу.
    procedure ShowBand(Band: TfrxBand) Показывает бэнд.
    procedure ShowBand(Band: TfrxBandClass) Показывает бэнд заданного типа.
    function FreeSpace: Extended Возвращает количество свободного места на странице (в пикселах). После вывода очередного бэнда это значение уменьшается.
    property CurColumn: Integer Возвращает/устанавливает номер текущей колонки.
    property CurX: Extended Возвращает/устанавливает текущую позицию X.
    property CurY: Extended Возвращает/устанавливает текущую позицию Y. После вывода очередного бэнда это значение увеличивается.
    property DoublePass: Boolean Является ли отчет двухпроходным.
    property FinalPass: Boolean Является ли текущий проход последним.
    property FooterHeight: Extended Возвращает высоту page footer.
    property HeaderHeight: Extended Возвращает высоту page header.
    property PageHeight: Extended Возвращает высоту области печати страницы.
    property PageWidth: Extended Возвращает ширину области печати страницы.
    property TotalPages: Integer Возвращает количество страниц в готовом отчете (только на втором проходе двухпроходного отчета).

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

    Pascal:

    var
      i: Integer;
      Band1, Band2: TfrxMasterData;
    
    { находим нужные бэнды }
    Band1 := frxReport1.FindObject('MasterData1') as TfrxMasterData;
    Band2 := frxReport1.FindObject('MasterData2') as TfrxMasterData;
    for i := 1 to 6 do
    begin
      { выводим бэнды друг за другом }
      frxReport1.Engine.ShowBand(Band1);
      frxReport1.Engine.ShowBand(Band2);
      { делаем небольшой промежуток }
      if i = 3 then
        frxReport1.Engine.CurY := frxReport1.Engine.CurY + 10;
    end;
    

    C++:

    int i;
    TfrxMasterData * Band1;
    TfrxMasterData * Band2;
    
    // находим нужные бэнды 
    Band1 := dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData1"));
    Band2 := dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData2"));
    for(i = 1; i <= 6; i++)
    {
      // выводим бэнды друг за другом 
      frxReport1->Engine->ShowBand(Band1);
      frxReport1->Engine->ShowBand(Band2);
      // делаем небольшой промежуток 
      if(i == 3)
        frxReport1->Engine->CurY += 10;
    }
    

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

    Pascal:

    var
      i, j: Integer;
      Band1, Band2: TfrxMasterData;
      SaveY: Extended;
    
    Band1 := frxReport1.FindObject('MasterData1') as TfrxMasterData;
    Band2 := frxReport1.FindObject('MasterData2') as TfrxMasterData;
    SaveY := frxReport1.Engine.CurY;
    for j := 1 to 2 do
    begin
      for i := 1 to 6 do
      begin
        frxReport1.Engine.ShowBand(Band1);
        frxReport1.Engine.ShowBand(Band2);
        if i = 3 then
          frxReport1.Engine.CurY := frxReport1.Engine.CurY + 10;
      end;
      frxReport1.Engine.CurY := SaveY;
      frxReport1.Engine.CurX := frxReport1.Engine.CurX + 200;
    end;
    

    C++:

    int i, j;
    TfrxMasterData * Band1;
    TfrxMasterData * Band2;
    Extended SaveY;
    
    Band1 = dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData1"));
    Band2 = dynamic_cast <TfrxMasterData *> (frxReport1->FindObject("MasterData2"));
    SaveY = frxReport1->Engine->CurY;
    for(j = 1; j <= 2; j++)
    {
      for(i = 1; i <= 6; i++)
      {
        frxReport1->Engine->ShowBand(Band1);
        frxReport1->Engine->ShowBand(Band2);
        if(i == 3)
          frxReport1->Engine->CurY += 10;
      }
      frxReport1->Engine->CurY = SaveY;
      frxReport1->Engine->CurX += 200;
    }
    
    Back to top © 1998-2024 ООО «Быстрые отчеты»