我怎样才能让这个数据透视表在我想要的位置显示我想要的值?

How can I get this PivotTable to display the values I want it to, in the location I want them to be?

经过多次咬牙切齿,&c,我在生成数据透视表方面取得了一点成功。它现在同时显示 "row filter"(在描述上)和 "column filter"(在 "month year" 列上),如下所示:

这是通过以下代码完成的:

var pch = _xlBook.PivotCaches();
Range sourceData = _xlBook.Worksheets["PivotData"].Range["A1:G318"]; // TODO: Make range dynamic

PivotCache pc = pch.Create(XlPivotTableSourceType.xlDatabase, sourceData);
PivotTable pvt = pc.CreatePivotTable(_xlPivotTableSheet.Range["A8"], "PivotTable");

pvt.PivotFields("Description").Orientation = XlPivotFieldOrientation.xlRowField;
pvt.PivotFields("MonthYr").Orientation = XlPivotFieldOrientation.xlColumnField;

源数据 ("PivotData") 如下所示:

数据透视表 应该 的样子,说完并编码后,是这样的:

我需要做什么才能实现这种外观(这些数据和这些位置)?我认为部分原因是将更多 XlPivotFieldOrientation 值分配给更多 PivotFields,但不知道它们应该是什么。

首先但可能是最不重要的(但仍然很重要),"Row Labels" 应该说 "Description" 而 "Column Labels" 应该说 "Month"

更新

我正在尝试逐个添加使各个列显示所需的代码。我试过这个:

pvt.AddDataField(pvt.PivotFields("TotalQty"), "Total Packages", XlConsolidationFunction.xlSum).NumberFormat = "###,##0";

...希望源数据的 "TotalQty" 列中的数据显示在标题为 "Total Packages"

的列中

确实显示了,但是标签"Total Packages"出现在了odd/out-of-the-way处:

如何让 "Total Packages" 标签显示在 "model" 屏幕截图中的位置?

更新 2

Hambone 在他的回答中提到了我的 TODO;我回到它并以这种方式动态化:

int rowsUsed = _xlBook.Worksheets["PivotData"].UsedRange.Rows.Count;
int colsUsed = _xlBook.Worksheets["PivotData"].UsedRange.Columns.Count;
string colsUsedAsAlpha = GetExcelColumnName(colsUsed);
string endRange = string.Format("{0}{1}", colsUsedAsAlpha, rowsUsed);
Range sourceData = _xlBook.Worksheets["PivotData"].Range[string.Format("A1:{0}",
  endRange)];

// Pass "1", get "A", etc.; from   
to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa
public static string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    while (dividend > 0)
    {
        var modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (dividend - modulo) / 26;
    }
    return columnName;
}

顺便说一句,我找不到我的青铜徽章了。

一些事情...您没有具体询问这个问题,但是在您的代码中您有一个 "TODO" 来使范围动态化。一个非常好的方法是将范围转换为 table。执行此操作后,您可以传递 table 而不是范围。 table,您可能从以前的帖子中知道是:

ListObject tab = _xlPivotTableSheet.ListObjects["Table1"];
PivotCache pc = pch.Create(XlPivotTableSourceType.xlDatabase, tab);

如果您这样做,边界就无关紧要了——table 全部作为一个数据源。

回到您手头的问题。您添加的数据字段没问题:

pvt.AddDataField(pvt.PivotFields("TotalQty"), "Total Packages",
    XlConsolidationFunction.xlSum);
pvt.AddDataField(pvt.PivotFields("TotalSales"), "Total Purchases",
     XlConsolidationFunction.xlSum);

计算字段有点棘手。我不太明白“占总价的百分比”的计算方法,但为了便于说明,这就是平均价格的计算方法:

PivotField avg = pvt.CalculatedFields().Add("Average Price", "=TotalSales/TotalQty", true);
avg.Orientation = XlPivotFieldOrientation.xlDataField;

你是对的——方向不是你所期望的。此设置在枢轴 table 级别完成 - 它是行或列。要获得您正在寻找的视图,您可以将其从默认列更改为行:

pvt.DataPivotField.Orientation = XlPivotFieldOrientation.xlRowField;

执行此操作后,我认为枢轴 table 看起来会更符合您的预期。