【问题标题】:How can I get this PivotTable to display the values I want it to, in the location I want them to be?我怎样才能让这个数据透视表在我想要的位置显示我想要的值?
【发布时间】:2016-10-17 22:44:27
【问题描述】:

在咬牙切齿之后,我能够在生成数据透视表方面取得一点成功。它现在同时显示“行过滤器”(在描述上)和“列过滤器”(在“月年”列上),如下所示:

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

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 有关,但不知道它们应该是什么。

首先但可能最不重要(但仍然很重要),“行标签”应该说“描述”,“列标签”应该说“月”

更新

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

pvt.AddDataField(pvt.PivotFields("TotalQty"), "总包数", XlConsolidationFunction.xlSum).NumberFormat = "###,##0";

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

确实会显示,但标签“Total Packages”出现在一个奇怪/偏僻的地方:

如何让“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;
}

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

【问题讨论】:

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


    【解决方案1】:

    有几件事...您没有特别问这个问题,但是在您的代码中,您有一个“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;
    

    完成此操作后,我认为数据透视表的外观会更符合您的预期。

    【讨论】:

    • 使用第一段代码,是否会改变我现有的代码:PivotCache pc = pch.Create(XlPivotTableSourceType.xlDatabase, sourceData);到:PivotCache pc = pch.Create(XlPivotTableSourceType.xlDatabase, tab); ?
    • 是的,完全正确。表 (ListObjects) 是真正的游戏规则改变者。我非常喜欢他们。
    猜你喜欢
    • 2018-04-09
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2018-05-28
    • 1970-01-01
    相关资源
    最近更新 更多