Помогите, pls, с SUM для UserDataset!

отредактировано 05:48 Раздел: FastReport 3.0
Всем здравствуйте!

При переходе от FR2 к FR3, решил упростить себе жизнь и использовать
агрегатную функцию SUM для подсчёта постраничных сумм (раньше они считались в коде программы вручную). И ничего не получается (вот уже целый день!). Уже всё упростил до предела!

Условия задачи таковы: есть простейший отчёт, состоящий из Data-band'а, MasterData1, подключённого к источнику данных 'frUserDataset' и PageFooter'а PageFooter1. В MasterData1 печатается переменная [TrNum] - тут всё в порядке: frUserDataset её распознаёт и возвращает её значение. А в PageFooter'е я хотел бы видеть сумму всех TrNum по листу. Как я ни пытался получить эту сумму, ничего не выходит:

[SUM(<frUserDataset."TrNum">,MasterData1)], [SUM(TrNum,MasterData1)], [SUM(<TrNum>,MasterData1)], [SUM(<MasterData1."TrNum">,MasterData1)] ....
в ответ или 'переменная TrNum не определена', или 'неправильное преобразование типа variant'. Я перепробовал, по-моему, уже все возможные варианты...

Кто-нибудь может сказать какое выражение должно стоять в Footer'е?

И ещё: почему появление с отчёте агрегатной функции вызывает срабатывание
onGetValue у Report'а? Я ведь не должен обрабатывать её в своём коде?
А так получается, что мой frUserDataset должен знать, что это не ошибочно
введённая в отчёт неправильная переменная, а функция, которую он не
должен обрабатывать, а должен просто пропустить. Или так и должно быть???

И где бы подробно почитать последовательность генерации событий
при построении отчёта из UserDataset'а? В каком порядке генерируются
вызовы событий frxReport'а и frxUserDataset'а, когда FR встречает в
документе свою переменную [xxx]?

Комментарии

  • gpigpi
    отредактировано February 2006
    Вот пример. Всё работает
    <span style='font-family:Courier'><span style='font-size:8pt;line-height:100%'>unit Unit1;

    interface

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

    type
    TForm1 = class(TForm)
    frxUserDataSet1: TfrxUserDataSet;
    Button1: TButton;
    frxReport1: TfrxReport;
    procedure frxUserDataSet1First(Sender: TObject);
    procedure frxUserDataSet1Next(Sender: TObject);
    procedure frxUserDataSet1CheckEOF(Sender: TObject; var Eof: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure frxReport1GetValue(const VarName: String;
    var Value: Variant);
    private
    { Private declarations }
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;
    i: integer;

    implementation

    {$R *.dfm}

    procedure TForm1.frxUserDataSet1First(Sender: TObject);
    begin
    i:=0;
    end;

    procedure TForm1.frxUserDataSet1Next(Sender: TObject);
    begin
    inc(i);
    end;

    procedure TForm1.frxUserDataSet1CheckEOF(Sender: TObject;
    var Eof: Boolean);
    begin
    if i>100 then eof:=true;
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    begin
    frxReport1.ShowReport();
    end;

    procedure TForm1.frxReport1GetValue(const VarName: String;
    var Value: Variant);
    begin
    if VarName='MyVar' then Value:=i;
    end;

    end.

    ====================Form=================

    object Form1: TForm1
    Left = 192
    Top = 114
    Width = 696
    Height = 480
    Caption = 'Form1'
    Color = clBtnFace
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'MS Sans Serif'
    Font.Style = []
    OldCreateOrder = False
    PixelsPerInch = 96
    TextHeight = 13
    object Button1: TButton
    Left = 174
    Top = 288
    Width = 75
    Height = 25
    Caption = 'Button1'
    TabOrder = 0
    OnClick = Button1Click
    end
    object frxReport1: TfrxReport
    Version = '3.20'
    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 = 'По умолчанию'
    ReportOptions.CreateDate = 38770.532729444440000000
    ReportOptions.LastChange = 38770.536258819450000000
    ScriptLanguage = 'PascalScript'
    ScriptText.Strings = (
    'begin'
    ''
    'end.')
    OnGetValue = frxReport1GetValue
    Left = 178
    Top = 194
    Datasets = <
    item
    DataSet = frxUserDataSet1
    DataSetName = 'frxUserDataSet1'
    end>
    Variables = <>
    Style = <>
    object Page1: TfrxReportPage
    PaperWidth = 209.973333333333300000
    PaperHeight = 296.862500000000000000
    PaperSize = 9
    LeftMargin = 10.000000000000000000
    RightMargin = 10.000000000000000000
    TopMargin = 10.000000000000000000
    BottomMargin = 10.000000000000000000
    object MasterData1: TfrxMasterData
    Height = 20.000000000000000000
    Top = 20.000000000000000000
    Width = 718.009912533333500000
    DataSet = frxUserDataSet1
    DataSetName = 'frxUserDataSet1'
    RowCount = 0
    object Memo1: TfrxMemoView
    Left = 10.000000000000000000
    Top = 2.000000000000000000
    Width = 80.000000000000000000
    Height = 16.000000000000000000
    Memo.UTF8 = (
    '[MyVar]')
    end
    end
    object PageFooter1: TfrxPageFooter
    Height = 20.000000000000000000
    Top = 62.000000000000000000
    Width = 718.009912533333500000
    object Memo3: TfrxMemoView
    Left = 12.000000000000000000
    Width = 80.000000000000000000
    Height = 16.000000000000000000
    Memo.UTF8 = (
    '[Sum(<MyVar>, MasterData1)]')
    end
    end
    end
    end
    object frxUserDataSet1: TfrxUserDataSet
    UserName = 'frxUserDataSet1'
    OnCheckEOF = frxUserDataSet1CheckEOF
    OnFirst = frxUserDataSet1First
    OnNext = frxUserDataSet1Next
    Left = 228
    Top = 194
    end
    end</span></span>
  • отредактировано 05:48
    Спасибо за помощь, пример, как и следовало ожидать, работает.
    А у меня в программе эта конструкция ( [SUM(<MyVar>, MasterData1)] )
    выдаёт ошибку 'неправильное преобразование типа variant', хотя логика
    работы мадуля построителя отчёта 'один в один', как в примере. Но с этим
    я как-нибудь разберусь.
    И, всё-таки, зачем Report генерирует событие onGetValue на '<MyVar>' и
    'SUM(<MyVar>, MasterData1)'? Ведь это не переменные, обрабатываемые
    UserDataset'ом, и он их просто игнорирует.
    Ещё раз спасибо!
  • gpigpi
    отредактировано 05:48
    Нужно различать события TfrxReport.OnGetValue и TfrxUserDataset.OnGetValue
    написал:
    Обработчик события TfrxReport.OnGetValue вызывается, если в тексте обнаружена
    неизвестная переменная. Обработчик должен вернуть значение переменной.
    т.е. он и должен вызываться при обнаружении MyVar.
    TfrxUserDataset.OnGetValue вызывается для присвоения значений полей frxUserDataset, которые описаны в свойстве Fields
  • отредактировано 05:48
    Я ещё понимаю, что onGetValue у Report'а вызывается, по [SUM(<....)], т.к само выражение находится в квадратных скобках, как переменная(, хотя Report дложен сам распознать, что в них стоит агрегатная функция и не дергать вышестоящий код), но зачем он дергает меня с '<MyVar>' в VarName, ведь это даже не имя переменной?

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

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.