【问题标题】:VB.Net using VBA to access Excel Pivot tablesVB.Net 使用 VBA 访问 Excel 数据透视表
【发布时间】:2018-08-23 14:07:48
【问题描述】:

我创建了一个包含多个工作表的 xlsx 文件,每个工作表至少有一个数据透视表,供同一张工作表上的某种图表使用。所有这些数据透视表都使用另一个名为“数据”的工作表中的相同数据。在我完成所有工作后,我开始录制一些宏,然后创建一些 VBA 代码,以便在我运行代码时更新数据透视表。所有这一切都很好,我制作了一个 xlsm 文件。

我决定是时候将所有东西都整合到 VB.Net 中了。我的代码执行一个存储过程并带回我成功放入“数据”表中的所有其他表可以访问它的正确位置的数据。 然后我从带有数据透视表的第一张表开始,这就是我的问题开始的地方。下面是来自 Excel 的有效代码:

Sub UpdatePreviousMonth(intRecordCount As Integer)

    Sheets("Prev Month").Select

    Range("A6").Select

    ActiveSheet.PivotTables("ptPreviousMonth").ChangePivotCache _
        ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
        "C:\Users\me\Documents\[My Charts.xlsm]Data!R1C4:R" & CStr(intRecordCount) & "C4", Version:=xlPivotTableVersion15)

    ActiveSheet.PivotTables("ptPreviousMonth").PivotFields("Names").AutoSort xlAscending, "Names"

End Sub

这是我在 VB.Net 中无法使用的代码:

Private Sub UpdatePreviousMonth(intRecordCount As Integer, xlWorkbook As Excel.Workbook, xlWorkSheets As Excel.Sheets, xlWorkSheetData As Excel.Worksheet)
        Try
            Dim xlWorkSheet As Excel.Worksheet = CType(xlWorkSheets("Prev Month"), Excel.Worksheet) ' This line works...

            xlWorkSheet.PivotTables("ptPreviousMonth").ChangePivotCache _
                (xlWorkbook.PivotCaches.Create(SourceType:=Excel.XlPivotTableSourceType.xlDatabase, SourceData:=xlWorkSheetData.Range("R1C4:R" & CStr(intRecordCount) & "C4"), Version:=xlPivotTableVersion15))    

xlWorkSheet.PivotTables("ptPreviousMonth").PivotFields("Names").AutoSort(Excel.XlSortOrder.xlAscending, "Names")

            Catch ex As Exception
                End Try
  End Sub

问题从整个 xlWorkSheet.PivotTables("ptPreviousMonth").ChangePivotCache 行开始。 xlWorkSheet.PivotTables("ptPreviousMonth").ChangePivotCache 警告“后期绑定分辨率;可能会发生运行时错误”。我在 xlWorkSheet.PivotTables("ptPreviousMonth").PivotFields("Names").AutoSort 行收到相同的警告。

Version:=xlPivotTableVersion15 是一个例外'xlPivotTableVersion15' 未声明。由于其保护级别,它可能无法访问。

如您所见,我声明了 xlWorkSheet,所以我不知道为什么会收到警告,除非它与我无法识别的行的其余部分有关。

从我读到的 xlPivotTableVersion15 是可选的,所以我尝试在没有 Version:=xlPivotTableVersion15 的情况下运行代码并得到了

HRESULT 异常:0x800A03EC

这似乎意味着我缺少一个参数?

xlWorkSheetData 是数据所在的“数据”表。

有人可以帮忙吗?我觉得我很接近但找不到解决方案?

【问题讨论】:

    标签: excel vba vb.net


    【解决方案1】:

    编辑 - 我应该早点意识到这一点,但你不能在 Range 函数中使用 RC 样式。这导致xlWorkbook.PivotCaches.Create 语句的参数无效。下面的代码已被更正为使用有效的语法。


    我真的建议您启用 Option Strict。您已经在使用一些强类型互操作变量,没有理由不完成这项工作并避免后期绑定的不确定性。

    来自Worksheet.PivotTables Method 的文档:

    返回一个对象,该对象表示单个数据透视表(一个 数据透视表对象)或所有数据透视表报表的集合(一个 数据透视表对象)在工作表上。

    由于这个函数可以返回多种类型,所以使用VB的TryCast Operator将返回的Object转换为PivotTable

    随着版本问题,学习使用对象浏览器的(键盘:F2或查看菜单->对象浏览器)搜索功能。它有助于找到这些项目的定义位置和方式。

    Private Sub UpdatePreviousMonth(intRecordCount As Integer, xlWorkbook As Excel.Workbook, xlWorkSheets As Excel.Sheets, xlWorkSheetData As Excel.Worksheet)
        Try
            Dim xlWorkSheet As Excel.Worksheet = CType(xlWorkSheets("Prev Month"), Excel.Worksheet)
    
            Dim pt As Excel.PivotTable = TryCast(xlWorkSheet.PivotTables("ptPreviousMonth"), Excel.PivotTable)
            If pt IsNot Nothing Then
                Dim ver As Excel.XlPivotTableVersionList = Excel.XlPivotTableVersionList.xlPivotTableVersion15
                Dim sourceDataRange As Excel.Range = xlWorkSheetData.Range("A1:A1").Resize(intRecordCount)
                Dim cache As Excel.PivotCache = xlWorkbook.PivotCaches.Create(SourceType:=Excel.XlPivotTableSourceType.xlDatabase, SourceData:=sourceDataRange, Version:=ver)
                pt.ChangePivotCache(cache)
            End If
    
            pt = CType(xlWorkSheet.PivotTables("ptPreviousMonth"), Excel.PivotTable)
            If pt IsNot Nothing Then
                Dim field As Excel.PivotField = CType(pt.PivotFields("Names"), Excel.PivotField)
                field.AutoSort(Excel.XlSortOrder.xlAscending, "Names")
            End If
    
        Catch ex As Exception
        End Try
    End Sub
    

    【讨论】:

    • 请原谅,但声明XlPivotTableVersionList 变量有什么意义?
    • @JohnyL,它主要是为了提请注意 xlPivotTableVersion15 定义的类型,因为 OP 在定位它时遇到问题。
    • 好吧,很公平,但我不认为这是一种好风格,因为它会使代码膨胀...... :)
    • 感谢 TnTinMn,但是我仍然在 Dim 缓存中遇到同样的错误 As Excel.PivotCache = xlWorkbook.PivotCaches.Create(SourceType:=Excel.XlPivotTableSourceType.xlDatabase, SourceData:=xlWorkSheetData.Range(" R1C4:R" & CStr(intRecordCount) & "C4"), 版本:=ver)
    • @TiltingCode,我刚刚验证了此代码模式有效。我建议您验证传递给UpdatePreviousMonth 的参数是否正确,并突破SourceData 范围以验证它是否正确。即:Dim sourceDataRange As Excel.Range = xlWorkSheetData.Range("R1C4:R" & CStr(intRecordCount) & "C4").
    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多