pivotGrid 交叉表的数据钻取(原创)

一、创建用于显示底层数据的窗口
创建一个窗口,form的名称改为 frmDrill,保存时该类的名称自动保存为 TfrmDrill。
向窗口中添加一个 cxGrid,其中的TableView默认情况下类型为 DBTableView,将其删除,另外创建一个 TableView,不需要做其他设置。
如果希望在弹出的 Drill 窗口中显示行号,可以在 TableView 的 CustomDrawIndicatorCell 事件中加入以下代码:

procedure TfrmDrill.cxGrid1TableView1CustomDrawIndicatorCell(
  Sender: TcxGridTableView; ACanvas: TcxCanvas;
  AViewInfo: TcxCustomGridIndicatorItemViewInfo; var ADone: Boolean);
var
  AIndicatorViewInfo: TcxGridIndicatorRowItemViewInfo;
  ATextRect: TRect;
  // AStyle: TcxStyle;
  aCV: TcxCanvas;
begin
  if not (AViewInfo is TcxGridIndicatorRowItemViewInfo) then
    Exit;
  aCV := ACanvas;
  ATextRect := AViewInfo.ContentBounds;
  AIndicatorViewInfo := AViewInfo as TcxGridIndicatorRowItemViewInfo;
  InflateRect(ATextRect, -2, -1);
  //这个if段是为了加粗显示当前行号,可不用
  if AIndicatorViewInfo.GridRecord.Selected then
    begin
      aCV.Font.Style := Canvas.Font.Style + [fsBold];
      aCV.Font.Color := clRed;
    end
  else
    begin
      aCV.Font.Style := Canvas.Font.Style - [fsBold];
      acv.Font.Color := Canvas.Font.Color;
    end;
  // 在行标志中绘制行号
  Sender.LookAndFeelPainter.DrawHeader(ACanvas, AViewInfo.ContentBounds,
    ATextRect, [], cxBordersAll, cxbsNormal, taCenter, vaCenter,
    False, False, IntToStr(AIndicatorViewInfo.GridRecord.Index + 1),
    // AStyle.Font, AStyle.TextColor, AStyle.Color);
    acv.Font, acv.font.Color, acv.Brush.color);
  ADone := True;
end;

二、在 PivotGrid 所在窗体中写入下面过程,其中需要根据自己建立的 Drill 弹出窗口设置的变量名已经注释在行尾。

procedure cxShowDrillDownDataSource(ACrossCell: TcxPivotGridCrossCell);
  // 根据 pivotGrid 中的预设的所有列逐列在 AGridView 中创建列对象
  procedure CreateColumns(APivotGrid: TcxCustomPivotGrid; AGridView: TcxGridTableView);
  var
    I: Integer;
    AField: TcxPivotGridField;
  begin
    for I := 0 to APivotGrid.FieldCount - 1 do
    begin
      AField := APivotGrid.Fields[I];
      with AGridView.CreateColumn do
      begin
        Caption := AField.Caption;
        Visible := AField.Visible;
        Hidden := AField.Hidden;
      end;
    end;
  end;

var
  AForm: TfrmDrill;  // TfrmDrill 是自行创建的弹出窗口的类名
  ADataSource: TcxCustomDataSource;
  i, ColumnWidthSum: integer;
begin  
  AForm := TfrmDrill.Create(nil); // TfrmDrill 是自行创建的弹出窗口的类名
  try
    CreateColumns(ACrossCell.PivotGrid, AForm.cxGrid1TableView1);  // cxGrid1TableView1 是弹出窗口中的 cxGrid 中的 TableView 对象名
    // 根据单元格创建 Drill 数据源
    ADataSource := ACrossCell.CreateDrillDownDataSource;
    try
      AForm.Font.Size := frmMain.Font.Size;
      
      // 把数据源连接到弹出窗口中的 TableView.
      AForm.cxGrid1TableView1.DataController.CustomDataSource := ADataSource;
      AForm.cxGrid1TableView1.ApplyBestFit();

      // 计算 Drill 窗体显示所有列所需的最小宽度,避免显示横向滚动条
      ColumnWidthSum := 0;
      // 如果显示了行标记列,可使用下面的代码
      //ColumnWidthSum := AForm.cxGrid1TableView1.OptionsView.IndicatorWidth + 50;
      for i := 0 to AForm.cxGrid1TableView1.ColumnCount - 1 do
        ColumnWidthSum := ColumnWidthSum + AForm.cxGrid1TableView1.Columns[i].Width;

      if (ColumnWidthSum > AForm.ClientWidth) and (ColumnWidthSum < Screen.DesktopWidth) then
        AForm.Width := ColumnWidthSum;

      AForm.ShowModal;
    finally
      ADataSource.Free;
    end;
  finally
    AForm.Free;
  end;
end;

三、在 PivotGrid 的 DblClick 事件中写入以下代码:

procedure TForm1.cxDBPivotGrid1DblClick(Sender: TObject);
var
  ACrossCell: TcxPivotGridCrossCell;
begin
  with cxDBPivotGrid1.HitTest do
  begin
    // 如果双击位置是数据单元格
    if HitAtDataCell then
    begin
      // 取得双击的数据单元格
      ACrossCell := TcxPivotGridDataCellViewInfo(HitObject).CrossCell;
      cxShowDrillDownDataSource(ACrossCell);
    end;
  end;
end;
posted @ 2024-10-16 08:51  汉学  阅读(65)  评论(0)    收藏  举报