пятница, 12 сентября 2014 г.

FastReport запуск дизайнера в рантайме для ускорения отладки (FastReport Run Designer in Runtime)

Окружение

Delphi 7, FastReport 4

Ситуация

Работаю со сложным проектом и сложными печатными формами (отчетами).
В какой-то момент понял, что при разработке макетов отчетов выполняю по кругу такие действия:
1. правка в дизайн тайме
2. проверка в рантайме

  • запуск программы
  • ввод логина/пароля
  • открытие нужной формы
  • поиск нужного документа
  • вызов пункта меню Печать
  • просмотр отчета, получившегося на выходе 
  • определение что еще нужно править, 
  • возврат к шагу 1

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

Что захотелось сделать

Я подумал, что было бы классно: открыть в рантайме нужный документ открыть его макет и сразу же его дизайнерить.
и сразу же смотреть, что получается, без перезапуска программы.

По ходу решения задачи нашел 2 решения.


Решение 0. Самое простое

Тут идея проста как 3 копейки: нужно выполнить команду.

Report.DesignReport()

Но для этого нужно как-то эту команду вызвать, например, через кнопку или пункт меню в интерфейсе. А это мне не подходило, т.к. программа уже имела сложную инфраструктуру с динамически формирующимися пунктами меню и динамическим определением нужного макета отчета.

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

Решение 1. Через событие OnPreview

Это решение удобно, если отчетов не очень много, и не составит труда вписать по одной строчке кода в событие OnPreview отчета. Такое решение подойдет для небольших проектов.

Суть решения

1. делаю вспомогательный юнит (модуль)

-------------------------------------

unit uUtilsFr;

interface
uses
  frxClass, frxPreview;

type
   TFastReportDesignReportButtonOnClickStubClass = class(TObject)
  public
    procedure OnClick(Sender: TObject);
  end;


procedure FastReportAddDesignButtonToPreviewForm(AReport: TfrxReport);

implementation
uses
  Buttons;

var
  lfxDesignReportButtonOnClickStub: TFastReportDesignReportButtonOnClickStubClass;

{ TFastReportDesignReportButtonOnClickStubClass }

procedure FastReportAddDesignButtonToPreviewForm(AReport: TfrxReport);
var
  lfrxPreviewForm: TfrxPreviewForm;
  lbtnDesign: TSpeedButton;
begin
  lfrxPreviewForm := TfrxPreviewForm(AReport.PreviewForm);

  lbtnDesign := TSpeedButton.Create(lfrxPreviewForm);
  lbtnDesign.OnClick := lfxDesignReportButtonOnClickStub.OnClick;
  lbtnDesign.Caption := 'Дизайнер';
  lbtnDesign.Width:= 66;

  lfrxPreviewForm.ToolBar.InsertControl(lbtnDesign);
end;

procedure TFastReportDesignReportButtonOnClickStubClass.OnClick(
  Sender: TObject);
begin
  TfrxPreviewForm(TSpeedButton(Sender).Owner).Report.DesignReport;
end;

initialization
  lfxDesignReportButtonOnClickStub := TFastReportDesignReportButtonOnClickStubClass.Create;

finalization
  lfxDesignReportButtonOnClickStub.Free;
end.

-------------------------------------

2. В компоненте отчета в событие OnPreview добавляю строчку

FastReportAddDesignButtonToPreviewForm(TfrxReport(sender));

(тут по сути вызываю функцию из созданного в пункте 1 модуля)

Что получается на выходе
В окне превью отчета появляется кнопка "Дизайнер", которая открывает дизайнер отчета.

Решение 2. Через собственный компонент Экспорта

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

Идея решения: делаю свой фиктивный компонент экспорта отчетов. Суть экспорта: открытие дизайнера.

Сложность решения: нужен будет свой компонент (то есть я предполагаю, что понятия создания/регистрации компонентов в Delphi вам знакомы).

Суть решения

1. Делаем компонент


unit ufrxExportDesign;

interface

uses
  Classes, Controls, Dialogs, frxClass;

type
  TfrxExportDesign = class(TfrxCustomExportFilter)
  public
    constructor Create(AOwner: TComponent); override;

    class function GetDescription: String; override;
    function ShowModal: TModalResult; override;


  end;

implementation

{ TfrxPDFExport }

constructor TfrxExportDesign.Create(AOwner: TComponent);
begin
  inherited;
  ShowDialog:= true;
end;

class function TfrxExportDesign.GetDescription: String;
begin
  Result := 'Run Designer';
end;

function TfrxExportDesign.ShowModal: TModalResult;
begin
  Report.DesignReport();
  Result:= mrCancel;
end;

end.



2. регистрируем компонент. 

Тут код я не привожу, т.к. это будет зависеть от вашей инфраструктуры проектов

3. Кидаем компонент на форму с отчетами
(по сути достаточно одного компонента на приложение)

Что получается на выходе 
в подменю "Экспорт" окна предпросмотра отчета у вас появятся кнопка "Run Designer"

Примечание

Если Вы хотите посмотреть, что получилось, Вам все таки придется переоткрыть основное окно предпросмотра отчета, Но это, в любом случае, быстрее, чем перезапуск программы.

Самое главное: Как сохранить изменения

После того, как в рантайме вас все устраивает, в окне дизайнера вызовите команду "Соханить в файл".
Потом в дизайн-тайме открываете дизайнер этого же отчета и загружаете из файла.
В самом простом варианте этого достаточно

Комментариев нет:

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