Delphi - 无法更改 Excel 数据透视字段中的函数

Delphi - Unable to change Function in Excel PivotField

Delphi 10 / 西雅图,Excel 2013。我正在使用 Delphi 构建一个 Excel 插件。该插件将创建一个 Pivot table。我的挑战是设置我想要的特定功能(计数、平均值、总和等)。如果我不设置函数,则使用默认值 (COUNT),并且我的代码工作正常,枢轴 table 就像它应该的那样。如果我尝试更改 PivotField 上的函数,则会收到错误 "Unable to set the Function property of the PivotField class." 在搜索错误时,我发现了 2 个常见原因。 (1) Pivot table 必须具有默认版本 xlPivotTableVersion15,并且 (2) PivotField 方向必须设置为 xlDataField。我都做了,当鼠标悬停时,IDE 显示两者的整数值,所以我知道它们已定义。

我尝试获取(而不是设置)PivotField.function 的值。我收到类似的错误 "Unable to get the Function property of the PivotField class"。我想要求和的列称为“#Clicks”。有问题的代码行是

 myPivotTable.PivotFields('#Clicks').function := xlSum;

如果我注释掉这一行,我的例程 运行 没问题,尽管我得到的是默认的 COUNT 函数,而不是我想要的 SUM 函数。

任何想法表示赞赏。请注意,当该行被注释掉并且我 运行 代码时,我可以进入 Excel,进入 PivotField 列表,并将函数从 Count 更改为 Sum。这是我的完整代码。

procedure  T_ZTemplateForm.TestPivotTable;
var
myPivotCache: OleVariant;
myPivotTable : OleVariant;
myActive_WorkBook : OleVariant;
TabDestination : string;
f1: OleVariant;

begin
  // Add the new Sheet
  XLApp.Connect; // XLApp is a global variable, pointing to the Excel instance
  myActive_WorkBook := XLApp.ActiveWorkbook;
  XLApp.Worksheets.Add(EmptyParam, EmptyParam,1, xlWorksheet, LOCALE_USER_DEFAULT );

  // Get a handle to the new sheet and set the Sheet Name
  sheet_graph1 := XLApp.ActiveSheet;
  sheet_graph1.Name := 'Graph1';

  // Create a Pivot Cache
  myPivotCache := myActive_WorkBook.PivotCaches.Create(xlDatabase,'Raw Data!R1C1:R1048576C36',xlPivotTableVersion15);

  // Create a Pivot table within the PivotCache
  TabDestination := 'Graph1!R3C1';
  myPivotTable := myPivotCache.CreatePivotTable(TabDestination, 'PivotTable1',xlPivotTableVersion15);

   // Now start adding the fields...
   f1 :=  myPivotTable.PivotFields('Fiscal Quarter');
   f1.Orientation := xlRowField;
   f1.Position := 1;

   myPivotTable.PivotFields('#Clicks').orientation := xlDataField;
  // myPivotTable.PivotFields('#Clicks').function := xlSum;

end;

Update 我可以使用 Seattle 和 Excel 2007 重现你的 Set_Function 和 GetFunction 问题,所以请忽略我的原始版本的答案。

不过,我找到了一种使用 CreateDataField 创建一个 Function 为 xlCount 的 PivotField 的方法,而且非常简单。

给定局部变量

var
  DataField : OleVariant;
  Value : OleVariant;

以下代码毫无怨言地正确执行

  Value := xlCount;
  DataField := DestinationSheet.PivotTables('APivotTable').AddDataField(
    vPivotField,
    'Count',
    Value
    );

  DataField := DestinationSheet.PivotTables('APivotTable').AddDataField(
    vPivotField,
    'Count',
    xlCount
    );

失败并显示您引用的错误消息。所以我只能猜测,当使用 "raw" 值 xlCount 调用 AddDataField 时,编译器生成的 Function_ 参数在某种程度上是不正确的 "packaged" 而当参数是一个 OleVariant 包含xlCount 值,它已正确打包。

我会让你尝试其他 XlConsolidationFunction 值 - 我现在已经受够了这个问题!

原始答案:根据我的实验判断,您可以更改要使用的 Excel 'function' 而无需指定 [= 的最终参数(在您的情况下为 xlSum) 15=]。事实上,在西雅图和 Excel2007 中,如果没有为最终的 any 值获得 'The parameter is incorrect' 异常,我无法让 AddDataField 执行, 'function' 参数。

我有一本工作簿,其中包含 table 公司名称、股息支付日期和金额。 table headers 是公司、付款日期和金额。

下面的代码适用于我,允许我选择要应用于金额列的函数,只需将函数名称指定为 AddDataField 的 Caption 参数即可。我使用后期绑定主要是为了方便 set-up,这样我就可以轻松地省略不想指定的参数的参数。

代码:

procedure  TForm1.TestPivotTable;
var
  vXLApp : OleVariant;
  PivotCache: OleVariant;
  PivotTable : OleVariant;
  ActiveWorkBook : OleVariant;
  DestinationSheet : OleVariant;
  FN : String;
  Destination : OleVariant;
  PivotField : OleVariant;
  DataField : OleVariant;
begin
  vXLApp := CreateOleObject('Excel.Application');
  vXLApp.Visible := True;

  FN := 'D:\aaad7\officeauto\MAPivot.xlsm';
  Assert(FileExists(FN));
  vXLApp.Workbooks.Open(FN);
  ActiveWorkBook := vXLApp.ActiveWorkbook;

  PivotCache := ActiveWorkbook.PivotCaches.Create(SourceType := xlDatabase,
    SourceData := 'Table1', //'R2C1R30C3',
    Version:=xlPivotTableVersion2000);

  DestinationSheet := ActiveWorkBook.Sheets['Sheet3'];
  Destination := DestinationSheet.Name + '!R3C1';
  PivotTable := PivotCache.CreatePivotTable(TableDestination := Destination,
   TableName := 'APivotTable'
   );

  DestinationSheet.Select;
  DestinationSheet.Cells[3, 1].Select;
  DestinationSheet.PivotTables('APivotTable').PivotFields('Company').Orientation := xlRowField;
  DestinationSheet.PivotTables('APivotTable').PivotFields('Company').Position := 1;

  DestinationSheet.PivotTables('APivotTable').PivotFields('PayDate').Orientation := xlRowField;
  DestinationSheet.PivotTables('APivotTable').PivotFields('PayDate').Position := 2;

  DestinationSheet.PivotTables('APivotTable').PivotFields('Amount').Orientation := xlRowField;
  DestinationSheet.PivotTables('APivotTable').PivotFields('Amount').Position := 3;

  PivotField := DestinationSheet.PivotTables('APivotTable').PivotFields('Amount');
  DataField := DestinationSheet.PivotTables('APivotTable').AddDataField(
    Field := PivotField,
    Caption := 'Sum');
end;