如何防止为数据透视表生成总计行和总计行(C#/Excel Interop)?

How can I prevent Total and Grand Total rows from being generated for PivotTables (C# / Excel Interop)?

我有一个看起来像这样的数据透视表:

但是请注意,它为每个 "real" 行显示一个 "Total" 行;另外,末尾有一个 "Grand Total" 行。这些完全是多余的 - 这个数据不需要累加。

我想可能是因为我需要将传递给 PivotTableWizard 方法的参数之一从 "true" 更改为 false,所以我找到 this documentation for it 并认为解决方法是更改第五个和第六个参数的值从真到假,如下所示:

 _xlBook.PivotTableWizard(
        Excel.XlPivotTableSourceType.xlDatabase,
        pivotData,
        pivotDestination,
        pivotTableName,
        false, //true,
        false, //true,
        true,
        true,
        useDefault,
        useDefault,
        false,
        false,
        Excel.XlOrder.xlDownThenOver,
        0,
        useDefault,
        useDefault
);

...但这没有什么区别 - 我仍然得到那些 rogue/spurious "Total" 行。

如何防止总计行 generated/displaying?

更新

This MS page 具体表明将 "RowGrand" arg 设置为 true 将显示行的总计,下一个 arg "ColumnGrand" 的设计类似。

但是,像我一样将这些值设置为 false:

static readonly object useDefault = Type.Missing;
string pivotTableName = @"Pivot Test";
. . .
pivotData = _xlSheet.Range["A1:D25"];
pivotDestination = _xlSheet.Range["F7", useDefault];
_xlBook.PivotTableWizard(
        Excel.XlPivotTableSourceType.xlDatabase, // SourceType
        pivotData,                               // SourceData
        pivotDestination,                        // TableDestination
        pivotTableName,                          // TableName
        false, //true,                           // RowGrand
        false, //true,                           // ColumnGrand
        true,                                    // SaveData
        true,                                    // HasAutoFormat
        useDefault,                              // AutoPage
        useDefault,                              // Reserved
        false,                                   // BackgroundQuery
        false,                                   // OptimizeCache
        Excel.XlOrder.xlDownThenOver,            // PageFieldOrder
        0,                                       // PageFieldWrapCount
        useDefault,                              // ReadData
        useDefault                               // Connection
);

...没有区别 - 数据透视表仍然显示不需要的总数 - ISIS 在这里搞什么?

更新 2

我以 MS post here 为基础做了一些调整,得出了这个:

private void GeneratePivotTableOnSheet2()
{
    // Select a range of data for the Pivot Table.
    pivotData = _xlSheet.get_Range("A1", "D25");

    // Select location of the Pivot Table.
    pivotDestination = _xlSheet.get_Range("A32", useDefault);

    // Add a Pivot Table to the Worksheet.
    _xlBook.PivotTableWizard(
        Excel.XlPivotTableSourceType.xlDatabase,
        pivotData,
        pivotDestination,
        pivotTableName2,
        true,
        true,
        true,
        true,
        useDefault,
        useDefault,
        false,
        false,
        Excel.XlOrder.xlDownThenOver,
        0,
        useDefault,
        useDefault
        );

    // Set variables for used to manipulate the Pivot Table.
    pivotTable =
        (Excel.PivotTable)_xlSheet.PivotTables(pivotTableName2);
    titlePivotField = ((Excel.PivotField)pivotTable.PivotFields(1));
    authorPivotField = ((Excel.PivotField)pivotTable.PivotFields(2));
    //pubyearPivotField = ((Excel.PivotField)pivotTable.PivotFields(3));

    // Format the Pivot Table.
    pivotTable.Format(Excel.XlPivotFormatType.xlReport2);
    pivotTable.InGridDropZones = false;

    // Set Sales Region as a Row Field.
    titlePivotField.Orientation =
        Excel.XlPivotFieldOrientation.xlRowField;
    authorPivotField.Orientation =
        Excel.XlPivotFieldOrientation.xlRowField;
    //pubyearPivotField.Orientation =
    //    Excel.XlPivotFieldOrientation.xlRowField;

    _xlSheet.Columns.AutoFit();

    Directory.CreateDirectory(PivotTablePracticeConstsAndUtils.OUTPUT_DIRECTORY);
    String _uniqueFolder = PivotTablePracticeConstsAndUtils.OUTPUT_DIRECTORY;
    string filename = String.Format("{0}\TwainBooks.xlsx", _uniqueFolder);
    if (File.Exists(filename))
    {
        File.Delete(filename);
    }

    _xlBook.SaveAs(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

    MessageBox.Show("File has been written");
}

有了这个,结果有点令人鼓舞,但仍然令人困惑;原因如下:

如果我声明两个 PivotFields(标题和作者),然后 select 通过 select 选中生成的传播sheet 上的复选框,然后 select 第三个(出版年),然后筛选其中一个值,数据显示在数据透视表中。在此之前,仅显示列标题 - 我必须手动检查 "pub year" 并过滤数据(不保留列默认具有 select 的 "All" 值)以查看任何数据.

它应该显示来自 git-go 的所有数据,对吧(所有 "All"s selected)?

然后为什么在手动完成时添加 "pub year" PivotField 工作(有点),但如果我尝试以编程方式添加它(代码中的 commented-out "pubyearPivotField" 行以上),不是吗?!?

IOW 总而言之:很多持续的刺激正在发生,但到目前为止还没有珍珠。

更新 3

这绝对比 Goofy 和 Barney Feif 串联起来更愚蠢:使用代码将 Author PivotField 设置为 Page 类型,并将 Title 和 YearPublished 设置为 Row Type,当 sheet已打开。

但是,如果我取消选中 "Year Published" 然后 re-check 它(它是从 git-go 选中的)数据确实显示。

所以这显然是一个 Excel 互操作错误;但是有没有办法以编程方式取消选中然后检查该字段?

更新 4

我也试过这个:

pubyearPivotField.EnableItemSelection = false;
pubyearPivotField.EnableItemSelection = true;

...但是没用。

更新 5

所以我想记录一个宏,记录当我取消选中 re-check "YEAR PUBLISHED" 复选框时发生的事情。

这是记录的内容:

Sub MacroUncheckCheckPTField()
'
' MacroUncheckCheckPTField Macro
'

'
    ActiveSheet.PivotTables("PivotTest3").PivotFields("Sum of YEAR PUBLISHED"). _
        Orientation = xlHidden
    ActiveSheet.PivotTables("PivotTest3").AddDataField ActiveSheet.PivotTables( _
        "PivotTest3").PivotFields("YEAR PUBLISHED"), "Sum of YEAR PUBLISHED", xlSum
End Sub

我不知道为什么 "Sum of " 是其中的一部分。我没有设置任何数据字段;数据透视表底部有一个 (bogus/unwanted) "Grand Total" 行总结了年份(当然,sense/has 没有值)。

但我不太清楚如何处理该宏 - 即,如何将其转换为 C#。

当我尝试 here 时,我得到,“转换错误:无法转换代码。详细信息: -- 第 1 列第 1 行:预计 EOF 请检查原代码有无错误后重试。"

是的,那是 "VB" 而不是 "VBA",但我认为值得一试。

我在 sheet(手动)中所做的就是首先取消选中 "Year Published" 复选框,然后 re-check 它;这就是让数据显示在数据透视表中所需要的全部。这是它的样子:

我试过了(设置 CurrentPage val only allowable on PageFields):

authorPivotField.CurrentPage = "(All)";

...但没有区别。

更新 6

我尝试将其作为 VBA-to-C# 宏的转换:

_xlSheet.PivotTables("PivotTest3").PivotFields("Sum of YEAR PUBLISHED")._Orientation = Excel.XlPivotFieldOrientation.xlHidden;
_xlSheet.PivotTables("PivotTest3").AddDataField(_xlSheet.PivotTables("PivotTest3")
    .PivotFields("YEAR PUBLISHED"), "Sum of YEAR PUBLISHED", Excel.XlConsolidationFunction.xlSum);

...但是爆炸了:“无法获取数据透视表的数据透视字段 属性 class

更新 7

因此,以我的思维方式,Excel Interop PivotTable 代码的工作方式的问题之一在于各种字段类型的命名法,这似乎具有误导性或充其量 non-optimal对我来说。

Excel.XlPivotFieldOrientation 的可能值为:

xlColumnField
xlDataField
xlHiddenField
xlPageField
xlRowField

在 tarheel 国家,这些 do/how 它们有什么不同,每个都与其兄弟不同?从他们的教名来看,这并不总是很明显。我会建议这些替代品,以更好地理解它们存在的理由:

xlColumnField = xlDisplayField (in my tests, I see no difference between this and xlRowField)
xlDataField = xlCalculatedField (it is a data field, but aren't they all?)
xlHiddenField = xlInitiallyHidden (it is available in the checkbox list, and checking it will visiblize it)
xlPageField = xlFilterField
xlRowField = xlDisplayField (in my tests, I see no difference between this and xlColumnField)

这绝不是完美的(数据透视表中没有数据显示,直到我先取消选中,然后重新选中“”对话框中的 "Year Published" 复选框),但它确实回答了问题(消除总计行):

// Select a range of data for the Pivot Table.
pivotData = _xlSheet.get_Range("A1", "D25");

// Select location of the Pivot Table.
pivotDestination = _xlSheet.get_Range("A30", useDefault);

// Add a Pivot Table to the Worksheet.
_xlBook.PivotTableWizard(
    Excel.XlPivotTableSourceType.xlDatabase,
    pivotData,
    pivotDestination,
    pivotTableName3,
    true,
    true,
    true,
    true,
    useDefault,
    useDefault,
    false,
    false,
    Excel.XlOrder.xlDownThenOver,
    0,
    useDefault,
    useDefault
    );

// Set variables for used to manipulate the Pivot Table.
pivotTable =
    (Excel.PivotTable)_xlSheet.PivotTables(pivotTableName3);
titlePivotField = ((Excel.PivotField)pivotTable.PivotFields(1));
authorPivotField = ((Excel.PivotField)pivotTable.PivotFields(2));
pubyearPivotField = ((Excel.PivotField)pivotTable.PivotFields(3));
statusPivotField = ((Excel.PivotField)pivotTable.PivotFields(4));

// Format the Pivot Table.
pivotTable.Format(Excel.XlPivotFormatType.xlReport2);
pivotTable.InGridDropZones = false;

// Set Page Field
authorPivotField.Orientation =
    Excel.XlPivotFieldOrientation.xlPageField;

// Set Row Field[s]
titlePivotField.Orientation =
    Excel.XlPivotFieldOrientation.xlRowField;
pubyearPivotField.Orientation =
    Excel.XlPivotFieldOrientation.xlRowField;
statusPivotField.Orientation =
    Excel.XlPivotFieldOrientation.xlHidden;

authorPivotField.CurrentPage = "(All)";

_xlSheet.Columns.AutoFit();

为什么它确实有效(特别是因为传递给 PivotTableWizard 的两个 "totals" 参数是 "true"),但我不明白...