rm_formreport.pas

来自「report machine 2.3 功能强大」· PAS 代码 · 共 1,965 行 · 第 1/5 页

PAS
1,965
字号
procedure TRMFormReport.Clear;
begin
  while FReportObjects.Count > 0 do
  begin
    TRMFormReportObject(FReportObjects[0]).Free;
    FReportObjects.Delete(0);
  end;
end;

procedure TRMFormReport.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited Notification(AComponent, Operation);
  if Operation = opRemove then
  begin
    if AComponent = FPrintControl then
      PrintControl := nil;
  end;
end;

function TRMFormReport.CreateReportFromGrid: Boolean;
var
  i, j: Integer;
  liPage: TRMPage;
  liBandPageHeader: TRMBandView;
  liBandPageDetail: TRMBandView;
  liBandColumnFooter: TRMBandView;
  liBandPageFooter: TRMBandView;
  liBandReportSummary: TRMBandView;
  liDetailBandList: TStringList;
  liGroupFooterBands: TList;
  Nexty: Integer;

  procedure GetFormRect;
  var
    i: Integer;
    liLeft, liTop: Integer;
  begin
    if PrintControl is TScrollingWinControl then
    begin
      with TScrollingWinControl(PrintControl) do
      begin
        HorzScrollBar.Position := 0;
        VertScrollBar.Position := 0;
      end;
    end;

    if PrintControl.ControlCount > 0 then
    begin
      FormHeight := 0;
      liLeft := 99999; liTop := 99999;
      for i := 0 to PrintControl.ControlCount - 1 do
      begin
        liLeft := Min(liLeft, PrintControl.Controls[i].Left);
        liTop := Min(liTop, PrintControl.Controls[i].Top);
        FormWidth[0] := IntToStr(Max(StrToInt(FormWidth[0]), PrintControl.Controls[i].Left + PrintControl.Controls[i].Width));
        FormHeight := Max(FormHeight, PrintControl.Controls[i].Top + PrintControl.Controls[i].Height);
      end;
      FormWidth[0] := IntToStr(StrToInt(FormWidth[0]) - liLeft);
      FormHeight := FormHeight - liTop;
    end
    else
    begin
      FormWidth[0] := IntToStr(PrintControl.ClientWidth);
      FormHeight := PrintControl.ClientHeight;
    end;
  end;

  procedure PrintObject(Sender: TControl; aOffsetX, aOffsetY: Integer);
  var
    i: Integer;
    OldOffsX, OldOffsY: Integer;
    liList: TList;
    tmp: TRMFormReportObject;
    liPrintObjectClass: TClass;
    liOwnerDraw: Boolean;
    liFound: Boolean;
    liView: TRMView;
  begin
    OldOffsX := OffsX; OldOffsY := OffsY;
    OffsX := aOffsetX; OffsY := aOffsetY;
    if Sender is TScrollingWinControl then
    begin
      with TScrollingWinControl(Sender) do
      begin
        HorzScrollBar.Position := 0;
        VertScrollBar.Position := 0;
      end;
    end;

    liPrintObjectClass := nil;
    liOwnerDraw := False; liFound := False;
    if Assigned(FOnPrintObject) then
      FOnPrintObject(Self, liPage, Sender, liPrintObjectClass, liOwnerDraw);
    if (not liOwnerDraw) and (liPrintObjectClass = nil) then
    begin
      for i := FFormReportList.Count - 1 downto 0 do
      begin
        if Sender is TRMAddInFormReportObjectInfo(FFormReportList.Objects[i]).ClassRef then
        begin
          liFound := True;
          liPrintObjectClass := TRMAddInFormReportObjectInfo(FFormReportList.Objects[i]).ObjectClass;
          Break;
        end;
      end;
    end;
    if (not liOwnerDraw) and (liPrintObjectClass <> nil) then
    begin
      tmp := TRMFormReportObject(liPrintObjectClass.NewInstance);
      tmp.CreateObject;
      try
        liView := nil;
        tmp.OnGenerate_Object(Self, liPage, Sender, liView);
        if (liView <> nil) and Assigned(FOnAfterCreateObject) then
          FOnAfterCreateObject(Sender, liView);
        if not tmp.AutoFree then
          FReportObjects.Add(tmp);
      finally
        if tmp.AutoFree then
          tmp.Free;
      end;
    end;

    liFound := liFound or liOwnerDraw;
    if (not liFound) and (Sender is TWinControl) and (TWinControl(Sender).ControlCount > 0) then
    begin
      liList := TList.Create;
      try
        for i := 0 to TWinControl(Sender).ControlCount - 1 do
          liList.Add(TWinControl(Sender).Controls[I]);

        liList.Sort(ListSortCompare); //按上到下、左到右排序
        for i := 0 to liList.Count - 1 do
          PrintObject(TControl(liList[i]), aOffsetX + TWinControl(Sender).Left, aOffsetY + TWinControl(Sender).Top);
      finally
        liList.Free;
      end;
    end;

    OffsX := OldOffsX; OffsY := OldOffsY;
  end;

  procedure MakeGroups;
  var
    i, j, liNextY: Integer;
    liBandView: TRMBandView;
    liDataSet: TDataSet;
  begin
    liDataSet := nil;
    if ReportDataSet.DataSet <> nil then
      liDataSet := ReportDataSet.DataSet
    else if (ReportDataSet.DataSource <> nil) and (ReportDataSet.DataSource.DataSet <> nil) then
      liDataSet := ReportDataSet.DataSource.DataSet;
    if liDataSet = nil then Exit;

    for i := 0 to Report.Pages.Count - 1 do
    begin
      liPage := Report.Pages[i];

      for j := 0 to FGroups.Count - 1 do
      begin
        if (Length(FGroups[j].GroupFieldName) > 0) and (liDataSet.FindField(FGroups[j].GroupFieldName) <> nil) then
        begin
          liBandView := TRMBandView(RMCreateObject(gtBand, ''));
          liBandView.CreateUniqueName;
          liBandView.BandType := btGroupHeader;
          liBandView.PNewPageAfter := FGroups[j].FormNewPage;
          liBandView.GroupCondition := Format('[%s.%s."%s"]', [liDataSet.Owner.Name, liDataSet.Name, FGroups[j].GroupFieldName]);
          liBandView.SetBounds(0, NextY + 1, 0, 0);
          Inc(NextY, 1);
          liPage.Objects.Add(liBandView);
        end;
      end;

      liNextY := NextY;
      for j := FGroups.Count - 1 downto 0 do
      begin
        if (Length(FGroups[j].GroupFieldName) > 0) and (liDataSet.FindField(FGroups[j].GroupFieldName) <> nil) then
        begin
          liBandView := TRMBandView(RMCreateObject(gtBand, ''));
          liBandView.CreateUniqueName;
          liBandView.BandType := btGroupFooter;
          liBandView.SetBounds(0, liNextY + 1, 0, 0);
          Inc(liNextY, 1);
          liPage.Objects.Add(liBandView);
          liGroupFooterBands.Add(liBandView);
        end;
      end;
    end;
  end;

  procedure MakeGroupFooter;
  var
    i, j, k, SaveNextY: Integer;
    liGroupFooter: TRMBandView;
    liPage: TRMPage;
  begin
    if liGroupFooterBands.Count > 0 then
    begin
      k := 0;
      SaveNextY := NextY;
      for i := 0 to Report.Pages.Count - 1 do
      begin
        NextY := SaveNextY;
        liPage := Report.Pages[i];
        liGroupFooter := TRMBandView(liGroupFooterBands[k]);
        liGroupFooter.y := NextY;
        for j := 0 to FGroupFooterViews.Count - 1 do
        begin
          if liPage.FindObject(TRMView(FGroupFooterViews[j]).Name) <> nil then
          begin
            Inc(TRMView(FGroupFooterViews[j]).y, NextY);
            CalcRect(TRMView(FGroupFooterViews[j]), TRMBandView(liGroupFooterBands[0]), StrToInt(FormWidth[i]));
            TRMBandView(liGroupFooterBands[k]).dy := Max(TRMBandView(liGroupFooterBands[k]).dy, TRMView(FGroupFooterViews[j]).y + TRMView(FGroupFooterViews[j]).dy - TRMBandView(liGroupFooterBands[k]).y);
          end;
        end;

        Inc(k);
        NextY := liGroupFooter.y + liGroupFooter.dy + 1;
        for j := k to liGroupFooterBands.Count - 1 do
        begin
          if liPage.FindObject(TRMBandView(liGroupFooterBands[j]).Name) <> nil then
          begin
            TRMBandView(liGroupFooterBands[j]).y := NextY;
            NextY := NextY + TRMBandView(liGroupFooterBands[j]).dy + 1;
            Inc(k);
          end;
        end;
      end;
    end;
  end;

  procedure MakePageHeader;
  var
    i, j: Integer;
    liPage: TRMPage;
  {$IFDEF INFOPOWER}
    t: TRMwwRichView;
  {$ELSE}
  {$IFDEF RX}
    t: TRMRxRichView;
  {$ELSE}
    t: TRMRichView;
  {$ENDIF}
  {$ENDIF}
  begin
    for i := 0 to Report.Pages.Count - 1 do
    begin
      liPage := Report.Pages[i];

      liBandPageHeader := TRMBandView(RMCreateObject(gtBand, ''));
      liBandPageHeader.CreateUniqueName;
      liBandPageHeader.BandType := btPageHeader;
      liBandPageHeader.x := 0;
      liBandPageHeader.y := 0;
      liBandPageHeader.dx := 0;
      liBandPageHeader.dy := 0;
      liPage.Objects.Add(liBandPageHeader);
      NextY := 0;
      if Length(PageHeader.Caption.Text) > 0 then //标题
      begin
{$IFDEF INFOPOWER}
        t := TRMwwRichView(RMCreateObject(gtAddin, 'TRMwwRichView'));
{$ELSE}
{$IFDEF RX}
        t := TRMRxRichView(RMCreateObject(gtAddin, 'TRMRxRichView'));
{$ELSE}
        t := TRMRichView(RMCreateObject(gtAddin, 'TRMRichView'));
{$ENDIF}
{$ENDIF}
        t.Prop['FrameTyp'] := 0;
        t.CreateUniqueName;
        t.Prop['BandAlign'] := rmbaWidth;
        t.SetBounds(0, liBandPageHeader.y, 10, PageHeader.Height);
        PageHeader.GetStrings(t.RichEdit.Lines);
        liPage.Objects.Add(t);
        NextY := t.dy + 6;
        liBandPageHeader.dy := NextY;
      end;

      for j := 0 to FPageHeaderViews.Count - 1 do
      begin
        if liPage.FindObject(TRMView(FPageHeaderViews[j]).Name) <> nil then
        begin
          Inc(TRMView(FPageHeaderViews[j]).y, liBandPageHeader.y + NextY);
          CalcRect(TRMView(FPageHeaderViews[j]), liBandPageHeader, StrToInt(FormWidth[i]));
          if liBandPageHeader.dy < TRMView(FPageHeaderViews[j]).y + TRMView(FPageHeaderViews[j]).dy - liBandPageHeader.y then
            liBandPageHeader.dy := TRMView(FPageHeaderViews[j]).y + TRMView(FPageHeaderViews[j]).dy - liBandPageHeader.y;
        end;
      end;
    end;
  end;

  procedure MakeColumnFooter;
  var
    i, j: Integer;
    liPage: TRMPage;
  begin
    for i := 0 to Report.Pages.Count - 1 do
    begin
      liPage := Report.Pages[i];

      liBandColumnFooter := TRMBandView(RMCreateObject(gtBand, ''));
      liBandColumnFooter.CreateUniqueName;
      liBandColumnFooter.BandType := btColumnFooter;
      liBandColumnFooter.x := 0;
      liBandColumnFooter.y := NextY;
      liBandColumnFooter.dy := 0;
      liPage.Objects.Add(liBandColumnFooter);
      for j := 0 to FColumnFooterViews.Count - 1 do
      begin
        if liPage.FindObject(TRMView(FColumnFooterViews[j]).Name) <> nil then
        begin
          Dec(TRMView(FColumnFooterViews[j]).y, FGridTop + FGridHeight);
          Inc(TRMView(FColumnFooterViews[j]).y, liBandColumnFooter.y);
          CalcRect(TRMView(FColumnFooterViews[j]), liBandColumnFooter, StrToInt(FormWidth[i]));
          if liBandColumnFooter.dy < TRMView(FColumnFooterViews[j]).y + TRMView(FColumnFooterViews[j]).dy - liBandColumnFooter.y then
            liBandColumnFooter.dy := TRMView(FColumnFooterViews[j]).y + TRMView(FColumnFooterViews[j]).dy - liBandColumnFooter.y;
        end;
      end;
    end;
  end;

  procedure MakePageFooter;
  var
    i, j: Integer;
    liPage: TRMPage;
  {$IFDEF INFOPOWER}
    t: TRMwwRichView;
  {$ELSE}
  {$IFDEF RX}
    t: TRMRxRichView;
  {$ELSE}
    t: TRMRichView;
  {$ENDIF}
  {$ENDIF}
  begin
    for i := 0 to Report.Pages.Count - 1 do
    begin
      liPage := Report.Pages[i];

      liBandPageFooter := TRMBandView(RMCreateObject(gtBand, ''));
      liBandPageFooter.CreateUniqueName;
      liBandPageFooter.BandType := btPageFooter;
      liBandPageFooter.x := 0;
      liBandPageFooter.y := liBandColumnFooter.y + liBandColumnFooter.dy + 1;
      liBandPageFooter.dy := 3;
      liPage.Objects.Add(liBandPageFooter);
      for j := 0 to FPageFooterViews.Count - 1 do
      begin
        if liPage.FindObject(TRMView(FPageFooterViews[j]).Name) <> nil then
        begin
          Dec(TRMView(FPageFooterViews[j]).y, liBandColumnFooter.y + 1 {FGridTop + FGridHeight});
          Inc(TRMView(FPageFooterViews[j]).y, liBandPageFooter.y);
          CalcRect(TRMView(FPageFooterViews[j]), liBandPageFooter, StrToInt(FormWidth[i]));
          if liBandPageFooter.dy < TRMView(FPageFooterViews[j]).y + TRMView(FPageFooterViews[j]).dy - liBandPageFooter.y then
            liBandPageFooter.dy := TRMView(FPageFooterViews[j]).y + TRMView(FPageFooterViews[j]).dy - liBandPageFooter.y;
        end;
      end;

      if Length(PageFooter.Caption.Text) > 0 then
      begin
{$IFDEF INFOPOWER}
        t := TRMwwRichView(RMCreateObject(gtAddin, 'TRMwwRichView'));
{$ELSE}
{$IFDEF RX}
        t := TRMRxRichView(RMCreateObject(gtAddin, 'TRMRxRichView'));
{$ELSE}
        t := TRMRichView(RMCreateObject(gtAddin, 'TRMRichView'));
{$ENDIF}
{$ENDIF}
        t.CreateUniqueName;
        t.Prop['FrameTyp'] := 0;
        t.Prop['BandAlign'] := rmbaWidth;
        t.SetBounds(0, liBandPageFooter.y + liBandPageFooter.dy + 6, 10, PageHeader.Height);
        PageFooter.GetStrings(t.RichEdit.Lines);
        liPage.Objects.Add(t);
        liBandPageFooter.dy := liBandPageFooter.dy + t.dy + 6;
      end;
    end;
  end;

  procedure MakePageDetail;
  var
    i, j: Integer;
  begin
    liBandPageDetail := nil;
    for i := 0 to Report.Pages.Count - 1 do
    begin
      liPage := Report.Pages[i];

      if FPageDetailViews.Count > 0 then
      begin
        liBandPageDetail := TRMBandView(RMCreateObject(gtBand, ''));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?