【问题标题】:How to add pivot table filters with Microsoft.Office.Interop.Excel in C#如何在 C# 中使用 Microsoft.Office.Interop.Excel 添加数据透视表过滤器
【发布时间】:2019-06-07 22:06:43
【问题描述】:

我基于 Excel (.xlsx) 文件创建了一个数据透视表。该程序将字段添加到行、值和过滤器。使用 PivotFilters.Add2 会导致 0x800a03ec 错误,从而终止程序。如何正确使用PivotFilters.Add2?

我尝试过滤具有不同数据类型的不同字段。另外,我尝试使用Type.Missing 代替未使用的参数。对于 VB,似乎有很多关于这种方法的信息,但对于 C# 来说没有那么多。

过滤器中选择的项目应该在最后一行的两个日期之间。

    var xlApp = new Microsoft.Office.Interop.Excel.Application();
    xlApp.Visible = true;
    var workBook = xlApp.Workbooks.Open(spreadsheetLocation);
    var workSheet1 = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets["Data"];
    var workSheet2 = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets.Add();

    Microsoft.Office.Interop.Excel.Range last = workSheet1.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
    Microsoft.Office.Interop.Excel.Range range = workSheet1.get_Range("A1", last);

    Microsoft.Office.Interop.Excel.PivotCaches pivotCaches = null;
    Microsoft.Office.Interop.Excel.PivotCache pivotCache = null;
    Microsoft.Office.Interop.Excel.PivotTable pivotTable = null;
    Microsoft.Office.Interop.Excel.PivotFields pivotFields = null;
    Microsoft.Office.Interop.Excel.PivotField filterField = null;
    Microsoft.Office.Interop.Excel.PivotField accNumField = null;
    Microsoft.Office.Interop.Excel.PivotField amountPaidField = null;

    pivotCaches = workBook.PivotCaches();
    pivotCache = pivotCaches.Create(XlPivotTableSourceType.xlDatabase, range);

    pivotTable = pivotCache.CreatePivotTable(workSheet2.Cells[1,1]);
    pivotFields = (Microsoft.Office.Interop.Excel.PivotFields)pivotTable.PivotFields();
    amountPaidField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AmountPaid");
    amountPaidField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlDataField;
    amountPaidField.NumberFormat = "$#,###,###.00";

    accNumField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AccNumber");
    accNumField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlRowField;

    filterField = (Microsoft.Office.Interop.Excel.PivotField)pivotFields.Item("AccDate");
    filterField.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlPageField;
    filterField.EnableMultiplePageItems = true;
    filterField.PivotFilters.Add2(XlPivotFilterType.xlDateBetween, Type.Missing, DateTime.Now.AddDays(-30), DateTime.Now.AddDays(-20));

【问题讨论】:

  • 如果您手动尝试,您会发现,您无法将过滤器添加到页面字段(仅适用于行或列字段)。因此,您必须遍历其枢轴项并设置它们的可见性。而且您必须确保至少有一个数据透视项保持可见(如果您尝试将它们全部设置为不可见,则会出现错误)。

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


【解决方案1】:
  #First it deletes two rows and then it creates a pivot table#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Office.Interop.Excel;
    
    
    namespace ConsoleApplication4
    {
        class Program
        {
            public static string Column(int column)
            {
                column--;
                if (column >= 0 && column < 26)
                    return ((char)('A' + column)).ToString();
                else if (column > 25)
                    return Column(column / 26) + Column(column % 26 + 1);
                else
                    throw new Exception("Invalid Column #" + (column + 1).ToString());
            }
    
            static void Main(string[] args)
    
            {
               
    
                try
                {
                    string path = @"C:\Users\UX155512\Documents\Book1fd.xlsx";
                    var excelFile = new Application();
                    Workbook workBook = excelFile.Workbooks.Open(path);
                    Worksheet workSheet = workBook.Worksheets[1];
                    Worksheet pivotSheet = workBook.Worksheets.Add(
                        System.Reflection.Missing.Value,
                        workBook.Worksheets[workBook.Worksheets.Count],
                        1,
                        System.Reflection.Missing.Value);
    
    
    
    
                    Range last = workSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell, Type.Missing);
                    int lastRow = last.Row;
                    int lastCol = last.Column;
                    string lastColVal = Column(lastCol);
                    string lastFilledCol = lastColVal + lastRow.ToString();
                    Console.WriteLine(lastFilledCol);
                    Console.WriteLine(lastColVal);
                  
                    Console.WriteLine(lastRow);
                    Console.WriteLine(lastCol);
    
                   
                    for (int i = 1; i <= lastRow; i++)
                    {
                        if (workSheet.Cells[1][i].Value == ("HDR"))
                        {
                            workSheet.Rows[i].Delete();
                            Console.WriteLine("The Row Containing HDR has been deleted");
                        }
                        if (workSheet.Cells[1][i].Value == ("TRL"))
                        {
                            workSheet.Rows[i].Delete();
                            Console.WriteLine("The Row Containing TLR has been deleted");
                        }
    
                    }
    
    
                   
                    Range lastRange = workSheet.Range["A1", lastFilledCol];
    
                    
    
                    
                    pivotSheet.Name = "Pivot Table";
                   
                    Range range = pivotSheet.Cells[1, 1];
                    PivotCache pivotCache = (PivotCache)workBook.PivotCaches().Add(XlPivotTableSourceType.xlDatabase, lastRange);
                    PivotTable pivotTable = (PivotTable)pivotSheet.PivotTables().Add(PivotCache: pivotCache, TableDestination: range);
                    PivotField pivotField = (PivotField)pivotTable.PivotFields("Plan Number");
                    pivotField.Orientation = XlPivotFieldOrientation.xlRowField;
    
                    PivotField pivotField2 = (PivotField)pivotTable.PivotFields("Source");
                    pivotField2.Orientation = XlPivotFieldOrientation.xlColumnField;
    
                    PivotField pivotField3 = (PivotField)pivotTable.PivotFields("Total");
                    pivotField3.Orientation = XlPivotFieldOrientation.xlDataField;
                    pivotField3.Function = XlConsolidationFunction.xlSum;
                   
    
                 
                    workBook.SaveAs(@"C:\Users\UX155512\Documents\Excel Dump\Trial9.xlsx");
                    workBook.Close();
                    
    
                   
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                   
                }
    
                Console.Read();
            }
        }
    }

【讨论】:

    【解决方案2】:

    正如 Asger 上面提到的,过滤器不能添加到页面字段中。相反,必须设置枢轴项的可见性属性。

    var pivotItems = filterField.PivotItems();
    DateTime date = Convert.ToDateTime(item.Name);
    foreach (var item in pivotItems)
    {
        item.Visible = false;
        if (date < DateTime.Now.AddDays(-30) || date > DateTime.Now.AddDays(-20))
        {
            item.Visible = true;
        }
    }
    

    【讨论】:

    • 回答得很好,但请记住:至少一个数据透视项必须保持可见(您不能禁用页面字段的所有数据透视项)。最坏的情况:如果只有循环的最后一个数据透视项满足条件,那么在 ... 之前直接将其设置为 Visible = false 并得到一个错误。
    【解决方案3】:

    找到几乎任何互操作问题的答案的最佳方法是记录一个宏,然后检查源代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 2017-03-17
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 2021-11-11
      • 2013-09-03
      相关资源
      最近更新 更多