⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frxcross.pas

📁 报表控件。FastReport 是非常强大的报表控件
💻 PAS
📖 第 1 页 / 共 4 页
字号:
        Memo.Frame := CellMemos[j].Frame;
        DoOnCell(Memo, RowIndex, i, j, Cell);

        if FBorder then
        begin
          if FMatrix.PlainCells then
          begin
            if RowIndex = 0 then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftTop];
            if (i = 0) and (j = 0) then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftLeft];
            if (i = ColumnItems.Count - 1) and (j = CellLevels - 1) then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftRight];
            if RowIndex = RowItems.Count - 1 then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftBottom];
          end
          else
          begin
            if (RowIndex = 0) and (j = 0) then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftTop];
            if i = 0 then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftLeft];
            if i = ColumnItems.Count - 1 then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftRight];
            if (RowIndex = RowItems.Count - 1) and (j = CellLevels - 1) then
              Memo.Frame.Typ := Memo.Frame.Typ + [ftBottom];
          end;
        end;

        if FMatrix.PlainCells then
        begin
          CellSize := ColumnItem.CellSizes[j];
          Memo.SetBounds(ColumnItem.Bounds.Left - LeftMargin + AddWidth + CellOffs,
            RowItem.Bounds.Top - TopMargin,
            CellSize, RowItem.Bounds.Bottom);
          CellOffs := CellOffs + CellSize;
        end
        else
          Memo.SetBounds(ColumnItem.Bounds.Left - LeftMargin + AddWidth,
            RowItem.Bounds.Top + j * RowSize - TopMargin,
            ColumnItem.Bounds.Right, RowSize);
        CorrectDMPBounds(Memo);
        Memo.Visible := (Memo.Width <> 0) and (Memo.Height <> 0);
      end;
    end;

    RowItems.Free;
  end;

  procedure DoPagination(i, j: Integer);
  var
    k, kFrom, kTo: Integer;
  begin
    if ShowColumnHeader and (FRepeatHeaders or (i = 0)) and not FMatrix.NoColumns then
    begin
      Band := TfrxBand(FColumnBands[j]);
      Band.Top := CurY;
      Report.Engine.ShowBand(Band);
    end;

    if ShowRowHeader and (FRepeatHeaders or (j = 0)) and not FMatrix.NoRows then
    begin
      Band := TfrxBand(FRowBands[i]);
      if j = 0 then
        Band.Left := Left
      else
        Band.Left := 0;
      Band.Top := Band.Top + CurY;
      Report.Engine.ShowBand(Band);
      Band.Top := Band.Top - CurY;
    end;

    if FRepeatHeaders or (i = 0) then
      Report.Engine.CurY := CurY + ColumnHeaderHeight else
      Report.Engine.CurY := CurY;
    if FRepeatHeaders or (j = 0) then
    begin
      AddWidth := RowHeaderWidth;
      if j = 0 then
        AddWidth := AddWidth + Left;
    end
    else
      AddWidth := 0;

    kFrom := TfrxBand(FRowBands[i]).Tag mod 65536;
    kTo := TfrxBand(FRowBands[i]).Tag div 65536;

    for k := kFrom to kTo do
    begin
      Band := GetCellBand(k, j);
      Band.Top := Report.Engine.CurY;
      Report.Engine.ShowBand(Band);
      Band.Free;
    end;
  end;

begin
  AddSourceObjects;
  BuildColumnBands;
  BuildRowBands;
  ColumnItems := FMatrix.ColumnHeader.TerminalItems;
  Page := Report.PreviewPages.CurPage;
  CurY := Report.Engine.CurY;

  if FDownThenAcross then
    for i := 0 to FColumnBands.Count - 1 do
    begin
      for j := 0 to FRowBands.Count - 1 do
      begin
        Report.PreviewPages.CurPage := Page + j;
        DoPagination(j, i);
        if j <> FRowBands.Count - 1 then
          Report.Engine.NewPage;
      end;

      if i <> FColumnBands.Count - 1 then
        Report.Engine.NewPage;
      CurY := Report.Engine.CurY;
      Inc(Page, FRowBands.Count);

      Application.ProcessMessages;
      if Report.Terminated then break;
    end
  else
    for i := 0 to FRowBands.Count - 1 do
    begin
      for j := 0 to FColumnBands.Count - 1 do
      begin
        Report.PreviewPages.CurPage := Page + j;
        DoPagination(i, j);
        if j <> FColumnBands.Count - 1 then
        begin
          Report.PreviewPages.AddPageAction := apWriteOver;
          Report.Engine.NewPage;
        end;
      end;

      if i <> FRowBands.Count - 1 then
      begin
        Report.PreviewPages.AddPageAction := apAdd;
        Report.Engine.NewPage;
        Page := Report.PreviewPages.CurPage;
      end
      else
        Inc(Page, FColumnBands.Count);
      CurY := Report.Engine.CurY;

      Application.ProcessMessages;
      if Report.Terminated then break;
    end;

  if Parent is TfrxBand then
    CurY := CurY - Height;
  { print last page footers }
  if FColumnBands.Count > 1 then
    Report.Engine.EndPage;
  { position to last row, first column page }
  Report.PreviewPages.CurPage := Page - FColumnBands.Count;
  Report.PreviewPages.AddPageAction := apAdd;
  Report.Engine.CurY := CurY;

  ColumnItems.Free;
  ClearColumnBands;
  ClearRowBands;
end;

procedure TfrxCustomCrossView.ClearColumnBands;
var
  i: Integer;
begin
  for i := 0 to FColumnBands.Count - 1 do
    TObject(FColumnBands[i]).Free;
  FColumnBands.Clear;
end;

procedure TfrxCustomCrossView.ClearRowBands;
var
  i: Integer;
begin
  for i := 0 to FRowBands.Count - 1 do
    TObject(FRowBands[i]).Free;
  FRowBands.Clear;
end;

procedure TfrxCustomCrossView.AddSourceObjects;
var
  i: Integer;
begin
  for i := 0 to CellLevels - 1 do
    Report.PreviewPages.AddToSourcePage(CellMemos[i]);
  for i := 0 to ColumnLevels - 1 do
  begin
    Report.PreviewPages.AddToSourcePage(ColumnMemos[i]);
    Report.PreviewPages.AddToSourcePage(ColumnTotalMemos[i]);
  end;
  for i := 0 to RowLevels - 1 do
  begin
    Report.PreviewPages.AddToSourcePage(RowMemos[i]);
    Report.PreviewPages.AddToSourcePage(RowTotalMemos[i]);
  end;
end;

procedure TfrxCustomCrossView.SetupOriginalComponent(Obj1, Obj2: TfrxComponent);
begin
  THackComponent(Obj1).FOriginalComponent := THackComponent(Obj2).FOriginalComponent;
  THackComponent(Obj1).FAliasName := THackComponent(Obj2).FAliasName;
end;

procedure TfrxCustomCrossView.BuildColumnBands;
var
  i, LeftIndex, RightIndex: Integer;
  Items: TList;
  Item: TfrxCrossHeader;
  Memo: TfrxCustomMemoView;
  LargeBand: TfrxNullBand;
  CurWidth, AddWidth, LeftMargin, RightMargin: Extended;

  procedure CreateBand;
  var
    i: Integer;
    Band: TfrxNullBand;
    Memo, CutMemo: TfrxCustomMemoView;
    CutSize: Extended;
  begin
    Band := TfrxNullBand.Create(Report);
    Band.Left := AddWidth;
    Band.Tag := LeftIndex + RightIndex * 65536;

    { move in-bounds memos to the new band }
    i := 0;
    while i < LargeBand.Objects.Count do
    begin
      Memo := LargeBand.Objects[i];
      if Memo.Left < RightMargin then
      begin
        if Memo.Left + Memo.Width <= RightMargin + 5 then
        begin
          Memo.Parent := Band;
          Memo.Visible := Memo.Width > 0;
          Dec(i);
        end
        else { cut off the memo }
        begin
          CutSize := RightMargin - Memo.Left;
          CutMemo := CreateMemo(Band);
          CutMemo.Assign(Memo);
          CutMemo.Width := CutSize;
          SetupOriginalComponent(CutMemo, Memo);
          Memo.Width := Memo.Width - CutSize;
          Memo.Left := Memo.Left + CutSize;
          if Memo is TfrxDMPMemoView then
          begin
            Memo.Left := Memo.Left + fr1CharX;
            Memo.Width := Memo.Width - fr1CharX;
          end;
          CutMemo.Frame.Typ := CutMemo.Frame.Typ - [ftRight];
          Memo.Frame.Typ := Memo.Frame.Typ - [ftLeft];
          Memo := CutMemo;
        end;

        Memo.Left := Memo.Left - LeftMargin;
      end;
      Inc(i);
    end;

    FColumnBands.Add(Band);
  end;

begin
  ClearColumnBands;
  LargeBand := TfrxNullBand.Create(nil);
  Items := FMatrix.ColumnHeader.AllItems;

  { create one large band }
  for i := 0 to Items.Count - 1 do
  begin
    Item := Items[i];
    Memo := CreateMemo(LargeBand);
    Memo.Assign(Item.Memo);
    SetupOriginalComponent(Memo, Item.Memo);
    Memo.Text := Memo.FormatData(Item.Value);
    Memo.Highlight.Condition := '';
    with Item.Bounds do
      Memo.SetBounds(Left, Top, Right, Bottom);
    CorrectDMPBounds(Memo);
    Memo.Visible := (Memo.Width <> 0) and (Memo.Height <> 0);
    DoOnColumnHeader(Memo, Item);
  end;

  Items.Free;

  { cut it to small bands for each page }
  Items := FMatrix.ColumnHeader.TerminalItems;
  AddWidth := RowHeaderWidth;
  CurWidth := Report.Engine.PageWidth - AddWidth;
  LeftMargin := -Left;
  RightMargin := LeftMargin + CurWidth;
  LeftIndex := 0;
  RightIndex := Items.Count - 1;

  for i := 0 to Items.Count - 1 do
  begin
    Item := Items[i];
    { find right terminal item }
    if Item.Bounds.Left + Item.Bounds.Right - LeftMargin > CurWidth then
    begin
      RightMargin := Item.Bounds.Left;
      RightIndex := i - 1;
      CreateBand;
      LeftMargin := RightMargin;
      if FRepeatHeaders then
        AddWidth := RowHeaderWidth else
        AddWidth := 0;
      CurWidth := Report.Engine.PageWidth - AddWidth;
      RightMargin := LeftMargin + CurWidth;
      LeftIndex := RightIndex + 1;
      RightIndex := Items.Count - 1;
    end;
  end;
  { add last band }
  CreateBand;

  LargeBand.Free;
  Items.Free;
end;

procedure TfrxCustomCrossView.BuildRowBands;
var
  i, TopIndex, BottomIndex: Integer;
  Items: TList;
  Item: TfrxCrossHeader;
  Memo: TfrxCustomMemoView;
  LargeBand: TfrxNullBand;
  CurHeight, AddHeight, TopMargin, BottomMargin: Extended;

  procedure CreateBand;
  var
    i: Integer;
    Band: TfrxNullBand;
    Memo, CutMemo: TfrxCustomMemoView;
    CutSize: Extended;
  begin
    Band := TfrxNullBand.Create(Report);
    Band.Top := AddHeight;
    Band.Tag := TopIndex + BottomIndex * 65536;

    { move in-bounds memos to the new band }
    i := 0;
    while i < LargeBand.Objects.Count do
    begin
      Memo := LargeBand.Objects[i];
      if Memo.Top < BottomMargin then
      begin
        if Memo.Top + Memo.Height <= BottomMargin + 5 then
        begin
          Memo.Parent := Band;
          Dec(i);
        end
        else { cut off the memo }
        begin
          CutSize := BottomMargin - Memo.Top;
          CutMemo := CreateMemo(Band);
          CutMemo.Assign(Memo);
          CutMemo.Height := CutSize;
          SetupOriginalComponent(CutMemo, Memo);
          Memo.Height := Memo.Height - CutSize;
          Memo.Top := Memo.Top + CutSize;
          if Memo is TfrxDMPMemoView then
          begin
            Memo.Top := Memo.Top + fr1CharY;
            Memo.Height := Memo.Height - fr1CharY;
          end;
          CutMemo.Frame.Typ := CutMemo.Frame.Typ - [ftBottom];
          Memo.Frame.Typ := Memo.Frame.Typ - [ftTop];
          Memo := CutMemo;
        end;

        Memo.Top := Memo.Top - TopMargin;
      end;
      Inc(i);
    end;

    FRowBands.Add(Band);
  end;

begin
  ClearRowBands;
  LargeBand := TfrxNullBand.Create(nil);
  Items := FMatrix.RowHeader.AllItems;

  { create one large band }
  for i := 0 to Items.Count - 1 do
  begin
    Item := Items[i];
    Memo := CreateMemo(LargeBand);
    Memo.Assign(Item.Memo);
    SetupOriginalComponent(Memo, Item.Memo);
    Memo.Text := Memo.FormatData(Item.Value);
    Memo.Highlight.Condition := '';
    with Item.Bounds do
      Memo.SetBounds(Left, Top, Right, Bottom);
    CorrectDMPBounds(Memo);
    Memo.Visible := (Memo.Width <> 0) and (Memo.Height <> 0);
    DoOnRowHeader(Memo, Item);
  end;

  Items.Free;

  { cut it to small bands for each page }
  Items := FMatrix.RowHeader.TerminalItems;
  AddHeight := ColumnHeaderHeight;
  CurHeight := Report.Engine.FreeSpace - AddHeight;
  TopMargin := 0;
  BottomMargin := TopMargin + CurHeight;
  TopIndex := 0;
  BottomIndex := Items.Count - 1;

  for i := 0 to Items.Count - 1 do
  begin
    Item := Items[i];
    { find right terminal item }
    if Item.Bounds.Top + Item.Bounds.Bottom - TopMargin > CurHeight then
    begin
      BottomMargin := Item.Bounds.Top;
      BottomIndex := i - 1;
      CreateBand;
      TopMargin := BottomMargin;
      if FRepeatHeaders then
        AddHeight := ColumnHeaderHeight else
        AddHeight := 0;
      CurHeight := Report.Engine.PageHeight - Report.Engine.HeaderHeight -
        Report.Engine.FooterHeight - AddHeight;
      BottomMargin := TopMargin + CurHeight;

⌨️ 快捷键说明

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