Создание и удаление объектов в Fast Report VCL (Delphi)

Я использую FastReport 4 для отображения некоторых динамически сгенерированных данных и реорганизации их в отчете.

Я использую объект "шаблон" в отчете, чтобы получить начальную позицию (в моей реальной программе я копирую свойства шрифта, выравнивание и т. Д.)

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

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

Как правильно создавать и удалять объекты из отчета Fast Report?

Вот паскаль:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, frxClass;

type
  TForm1 = class(TForm)
    frxReport1: TfrxReport;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
  modelObj: TfrxComponent;
  newObj: TfrxMemoView;
begin
  modelObj := frxReport1.FindObject('modelObj');
  newObj := TfrxMemoView.Create(modelObj.Parent);
  newObj.CreateUniqueName;
  newObj.Text := 'Whee';
  newObj.SetBounds(modelObj.Left, modelObj.Top + modelObj.Height,
    modelObj.Width, modelObj.Height);
  frxReport1.PrepareReport;
  frxReport1.ShowPreparedReport;
  newObj.Free;
end;

end.

Вот DFM:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object btn1: TButton
    Left = 224
    Top = 48
    Width = 75
    Height = 25
    Caption = 'btn1'
    TabOrder = 0
    OnClick = btn1Click
  end
  object frxReport1: TfrxReport
    Version = '4.15'
    DotMatrixReport = False
    IniFile = '\Software\Fast Reports'
    PreviewOptions.Buttons = [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbEdit, pbNavigator, pbExportQuick]
    PreviewOptions.Zoom = 1.000000000000000000
    PrintOptions.Printer = 'Por defecto'
    PrintOptions.PrintOnSheet = 0
    ReportOptions.CreateDate = 41905.757295162040000000
    ReportOptions.LastChange = 41905.757295162040000000
    ScriptLanguage = 'PascalScript'
    ScriptText.Strings = (
      'begin'
      ''
      'end.')
    Left = 72
    Top = 32
    Datasets = <>
    Variables = <>
    Style = <>
    object Data: TfrxDataPage
      Height = 1000.000000000000000000
      Width = 1000.000000000000000000
    end
    object Page1: TfrxReportPage
      PaperWidth = 216.000000000000000000
      PaperHeight = 279.000000000000000000
      PaperSize = 1
      LeftMargin = 10.000000000000000000
      RightMargin = 10.000000000000000000
      TopMargin = 10.000000000000000000
      BottomMargin = 10.000000000000000000
      object PageHeader1: TfrxPageHeader
        Height = 279.685220000000000000
        Top = 18.897650000000000000
        Width = 740.787880000000000000
        object modelObj: TfrxMemoView
          Left = 166.299320000000000000
          Top = 30.236240000000000000
          Width = 264.567100000000000000
          Height = 18.897650000000000000
          ShowHint = False
          Color = clYellow
          Font.Charset = DEFAULT_CHARSET
          Font.Color = clBlack
          Font.Height = -13
          Font.Name = 'Arial'
          Font.Style = []
          Memo.UTF8W = (
            'Model')
          ParentFont = False
        end
      end
    end
  end
end

1 ответ

Решение

Извините, за мой вводящий в заблуждение первый ответ.
Похоже, внутренняя ошибка в PrepareReport, объекты, кажется, обмениваются.

var
  modelObj: TfrxComponent;
  newObj: TfrxMemoView;
  cn:String;
begin
  modelObj := frxReport1.FindObject('modelObj');
  newObj := TfrxMemoView.Create(modelObj.Parent);
  newObj.CreateUniqueName;
  cn := newObj.Name; // keep for dirty workaround
  newObj.Text := 'Whee';
  newObj.SetBounds(modelObj.Left, modelObj.Top + modelObj.Height,
    modelObj.Width, modelObj.Height);

  Showmessage('New: ' + newObj.Name + '  modelObj: ' + modelObj.Name);
  frxReport1.PrepareReport;
  Showmessage('New: ' + newObj.Name + '  modelObj: ' + modelObj.Name);

  frxReport1.ShowPreparedReport;
  newObj :=  TfrxMemoView(frxReport1.FindObject(cn)); // dirty workaround
  newObj.Free;
end;

Выход:

New: Memo1  modelObj: modelObj
New: modelObj  modelObj: Memo1

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

Другие вопросы по тегам