如何让我的数据透视表在我想要的位置显示我想要的值?

时间:2016-10-12 15:59:36

标签: c# excel pivot-table excel-interop

在咬牙切齿之后,我能够通过生成数据透视表获得一点点成功。它现在运行一个"行过滤器" (在描述上)和一个"列过滤器" (在"月份"列),如下:

enter image description here

使用以下代码完成:

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")如下所示:

enter image description here

数据透视表应该的样子,当所有内容都被说明和编码时,是这样的:

enter image description here

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

首先但可能最少(但仍然很重要),"行标签"应该说"描述"和#34;列标签"应该说"月"

更新

我试图逐个添加显示各种列所需的代码。我试过这个:

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

...希望来源数据的数据" TotalQty"列将显示在标题为#34; Total Packages"

的列中

它确实显示,但标签" Total Packages",出现在奇怪/偏僻的地方:

enter image description here

我如何获得" Total Packages"标签显示在"模型中的位置"屏幕截图?

更新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 http://stackoverflow.com/questions/181596/how-  
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;
}
顺便说一句,我找不到我的铜徽章。

1 个答案:

答案 0 :(得分:2)

有几件事......你并没有特别提出这个问题,但在你的代码中,你有一个" TODO"使范围变得动态。一个非常好的方法是将范围转换为表格。执行此操作后,您可以传递表而不是范围。您可能从之前的帖子中了解到的表格是:

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

如果你这样做,边界并不重要 - 表格全部作为一个数据源。

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

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;

你是对的 - 方向不是你所期望的。此设置在数据透视表级别完成 - 它是行或列。要获取您要查找的视图,请将其从默认列更改为行:

pvt.DataPivotField.Orientation = XlPivotFieldOrientation.xlRowField;

一旦你这样做,我认为数据透视表看起来会更像你期望的那样。