【问题标题】:Delphi - Unable to change Function in Excel PivotFieldDelphi - 无法更改 Excel PivotField 中的函数
【发布时间】:2017-03-25 20:49:22
【问题描述】:

Delphi 10 / Seattle, Excel 2013。我正在使用 Delphi 构建 Excel 插件。这个插件将创建一个数据透视表。我的挑战是设置我想要的特定功能(计数、平均值、总和等)。如果我没有设置函数,则使用默认值 (COUNT),并且我的代码工作正常,数据透视表就像它应该的那样。如果我尝试更改 PivotField 上的函数,则会收到错误消息“无法设置 PivotField 类的 Function 属性”。在搜索错误时,我发现了 2 个常见原因。 (1) Pivot 表必须具有默认版本的 xlPivotTableVersion15,并且 (2) PivotField 方向必须设置为 xlDataField。我都做了,当鼠标悬停时,IDE 会显示两者的整数值,所以我知道它们是定义的。

我尝试获取(而不是设置)PivotField.function 的值。我收到类似的错误“无法获取 PivotField 类的函数属性”。我要汇总的列称为“#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;

【问题讨论】:

  • 您如何准确地创建您的“#Clicks”数据透视字段?
  • @@MartynA - #Clicks 是原始数据表上数据列之一的名称/标题。该表的每一列都可以在 PivotCache/PivotTable 中访问(至少据我了解)。
  • 附加信息:当我查看 Excel_TLB 文件时,它说 PivotTable.Function 已更改为 'PivotTable.Function_' 不幸的是,这对我没有帮助,但它可能是一个线索。

标签: excel delphi com pivot-table


【解决方案1】:

更新我可以使用西雅图和 Excel 2007 重现您的 Set_Function 和 GetFunction 问题,因此请忽略我的答案的原始版本。

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

给定局部变量

var
  DataField : OleVariant;
  Value : OleVariant;

以下代码可以毫无问题地正确执行

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

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

因您引用的错误消息而失败。所以我只能猜测,当使用“原始”值xlCount 调用AddDataField 时,编译器生成的Function_ 参数不知何故被错误地“打包”,而当参数是包含xlCount 值的OleVariant 时,它是正确包装。

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

原始答案:根据我的实验,您可以更改要使用的 Excel“函数”,而无需指定 AddDataField 的最终参数(在您的情况下为 xlSum)。事实上,对于西雅图和 Excel2007,我无法让 AddDataField 执行,而不会得到最终的“函数”参数的 any 值的“参数不正确”异常。

我有一个工作簿,其中包含公司名称、股息支付日期和金额的表格。表头是 Company、PaymentDate 和 Amount。

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

代码:

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;

【讨论】:

  • @@MartynA,我试过你的代码,虽然它可以工作,但它并没有解决问题。您将默认数据透视表版本设置为 xlPivotTableVersion2000。此版本中的默认函数似乎是 Sum,因此当您不指定任何其他内容时,您会得到这样的结果。不幸的是,在您的示例中,SUM 是我所能得到的,我无法选择 Count 或任何的其他功能。注意:当我查看 Excel_TLB 文件时,它说 PivotTable.Function 已更改为 PivotTable.Function_ 不幸的是,这对我没有帮助,但这可能是一个线索。还有其他想法吗?
  • a) 您是否使用西雅图提供的 Excel 类型库导入之一,如果是,您是否通过在 IDE 中转到 Component | Import Component 创建了自己的导入类型库?我正在使用从我安装的 Excel 2007 生成的一个。我只是将 Version2000 用作最低公分母。 b) 我认为重命名 PivotTable.Function 没有任何意义 - Delphi 的类型库导入器经常这样做是为了避免 .Pas 文件中的名称与 Delphi 保留字等冲突,包括“应用程序”。跨度>
  • @@MartynA - 我在 IDE 中通过 Import 生成了自己的。它被称为 Excel_TLB,基于 C:\Program Files (x86)\Microsoft Office\Office15\EXCEL.EXE(这是我安装的 Excel 2013 版本)
猜你喜欢
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
相关资源
最近更新 更多