如何在VBA中以编程方式重新定义数据透视表数据源

时间:2015-02-11 19:27:09

标签: excel-vba access-vba vba excel

使用'CopyFromRecordset'是将数据源从MS Access保持到数据透视表的一种有效方法 - '取消链接'。

Access数据库生成独立的报告,可以通过电子邮件发送无宏。

我正在尝试编写一个自动重新定义数据透视表数据源的例程。我知道足以清理一个记录的宏,因此它没有留下打开的杂散Excel对象,但有时我会遗漏一些让对象打开的东西 - 或者没有将对象设置为正确。

在这种特殊情况下,它就在这一行:

xlSheet.ListObjects.Add(xlSrcRange, xlSheet.Range(rngWorkingRange), , xlYes).Name _
        = "tbl_MOSI"

我得到运行时错误'1004' 对象定义错误

以下是我的完整例程供参考:

Public Sub GetMOSIData(strSheetToPlaceData As String, strPathToWorkbook As String)

'Puts a recordset into a specific cell of an Excel workbook 


'''
'8 objects created
Dim xlApp As Object
Dim WB As Object
Dim xlSheet As Object
Dim xlMain As Object
Dim xlOther As Object
Dim fld As Variant
Dim rs As DAO.Recordset
Dim rngWorkingRange As Range


Dim x As Integer


'''
'6 objects set
Set xlApp = CreateObject("Excel.Application")
Set WB = xlApp.Workbooks.Open(strPathToWorkbook)

Set xlSheet = WB.Sheets(strSheetToPlaceData) 'or you can manually type the sheet name in place of strSheetToPlaceData
Set xlMain = WB.Sheets("MOSI")
Set xlOther = WB.Sheets("SKL-LV-View")

Set rs = CurrentDb.OpenRecordset("Select * from " & strSheetToPlaceData)

'Assumes you will use A1 as the anchor cell - but it can be changed

'FIRST CLEAR THE RANGE OF CELLS
xlSheet.Range("A1").CurrentRegion.ClearContents

'PLACE THE FIELD NAMES
x = 1
For Each fld In rs.Fields
    xlSheet.Cells(1, x).Value = fld.Name
    x = x + 1
Next

'PLACE
xlSheet.Range("A2").CopyFromRecordset rs

'determine the data range for the PivotTable


'RECORDING FOR REFERENCE - I DON'T USE THIS CODE
'
'    Sheets("tbl_MOSI_Detail").Select
'    Range("C4").Select
'    ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A$1:$AB$23411"), , xlYes).Name _
'        = "Table1"
'    Range("Table1[#All]").Select
'    ActiveSheet.ListObjects("Table1").TableStyle = "TableStyleLight9"
'    ActiveSheet.ListObjects("Table1").Name = "tbl_MOSI"
'    Sheets("MOSI").Select
'    Range("G4").Select
'    ActiveSheet.PivotTables("pvMOSI").ChangePivotCache ActiveWorkbook.PivotCaches. _
'        Create(SourceType:=xlDatabase, SourceData:="tbl_MOSI_Detail!tbl_MOSI", _
'        Version:=xlPivotTableVersion12)
'END RECORDING FOR REFERENCE

'ATTEMPT to clean up recording...
'7th object set
Set rngWorkingRange = xlSheet.Range("A1").CurrentRegion

'convert tbl_MOSI_Detail Range into a Table

    xlSheet.ListObjects.Add(xlSrcRange, xlSheet.Range(rngWorkingRange), , xlYes).Name _
        = "tbl_MOSI"
    xlSheet.ListObjects("tbl_MOSI").TableStyle = "TableStyleLight9"

'set pvMOSI to point to this table
    xlMain.PivotTables("pvMOSI").ChangePivotCache WB.PivotCaches. _
        Create(SourceType:=xlDatabase, SourceData:="tbl_MOSI_Detail!tbl_MOSI", _
        Version:=xlPivotTableVersion12)

xlMain.RefreshAll
xlMain.Select

WB.Save
WB.Close

xlApp.Quit

'8 objects destroyed
Set rs = Nothing
Set rngWorkingRange = Nothing
Set fld = Nothing
Set xlSheet = Nothing
Set xlMain = Nothing
Set xlOther = Nothing
Set WB = Nothing
Set xlApp = Nothing


PresentExcel (strPathToWorkbook)
MsgBox "MOSI report is complete", vbOKOnly, "MOSI"


End Sub

1 个答案:

答案 0 :(得分:0)

您的rngWorkingRange变量是一个范围,您可以像使用字符串一样使用它。你需要

xlSheet.ListObjects.Add(xlSrcRange, rngWorkingRange, , xlYes).Name _
    = "tbl_MOSI"

你也可以说xlSheet.Range(rngWorkingRange.Address),但这只是愚蠢的。

您所说的是xlSheet.Range(rngWorkingRange.Value),因为Value是Range对象的默认属性。如果rngWorkingRange是单个单元格,其值可以解释为范围地址,则不会出现错误。但是rngWorkingRange.Value返回一个数组,xlSheet.Range(...)不知道如何处理数组。