Воссоздать исходные данные из кэша сводной таблицы
Я пытаюсь извлечь исходные данные из сводной таблицы, использующей кэш сводной таблицы, и поместить их в пустую электронную таблицу. Я попробовал следующее, Но он возвращает ошибку, определенную приложением или объектом.
ThisWorkbook.Sheets.Add.Cells(1,1).CopyFromRecordset ThisWorkbook.PivotCaches(1).Recordset
документация указывает, что PivotCache.Recordset-это тип ADO, поэтому это должно работать. У меня есть библиотека ADO включена в ссылках.
любые предложения о том, как этого достичь?
3 ответов
к сожалению, кажется, что нет способа напрямую манипулировать PivotCache в Excel.
Я нашел работу. Следующий код извлекает сводный кэш для каждой сводной таблицы, найденной в книге, помещает его в новую сводную таблицу и создает только одно сводное поле (чтобы гарантировать, что все строки из сводного кэша включены в общую сумму), а затем запускает ShowDetail, который создает новый лист со всеми данными сводной таблицы.
Я все равно как найти способ работать непосредственно с PivotCache, но это делает работу.
Public Sub ExtractPivotTableData()
Dim objActiveBook As Workbook
Dim objSheet As Worksheet
Dim objPivotTable As PivotTable
Dim objTempSheet As Worksheet
Dim objTempPivot As PivotTable
If TypeName(Application.Selection) <> "Range" Then
Beep
Exit Sub
ElseIf WorksheetFunction.CountA(Cells) = 0 Then
Beep
Exit Sub
Else
Set objActiveBook = ActiveWorkbook
End If
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
For Each objSheet In objActiveBook.Sheets
For Each objPivotTable In objSheet.PivotTables
With objActiveBook.Sheets.Add(, objSheet)
With objPivotTable.PivotCache.CreatePivotTable(.Range("A1"))
.AddDataField .PivotFields(1)
End With
.Range("B2").ShowDetail = True
objActiveBook.Sheets(.Index - 1).Name = "SOURCE DATA FOR SHEET " & objSheet.Index
objActiveBook.Sheets(.Index - 1).Tab.Color = 255
.Delete
End With
Next
Next
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
перейдите в окно немедленное и введите
?файл thisworkbook.PivotCaches(1).QueryType
Если вы получаете что-то другое, чем 7 (xlADORecordset), то свойство Recordset не применяется к этому типу PivotCache и вернет эту ошибку.
Если вы получаете ошибку в этой строке, то ваш PivotCache не основан на внешних данных вообще.
Если ваши исходные данные поступают из ThisWorkbook( т. е. данные Excel), то вы можете использовать
?файл thisworkbook.PivotCaches(1).Параметр sourcedata
чтобы создать объект диапазона и выполнить цикл через него.
Если ваш QueryType равен 1 (xlODBCQuery), то SourceData будет содержать строку подключения и commandtext для создания и набора записей ADO, например:
Sub DumpODBCPivotCache()
Dim pc As PivotCache
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Set pc = ThisWorkbook.PivotCaches(1)
Set cn = New ADODB.Connection
cn.Open pc.SourceData(1)
Set rs = cn.Execute(pc.SourceData(2))
Sheet2.Range("a1").CopyFromRecordset rs
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Sub
вам нужна ссылка ADO, но вы сказали, что у вас уже есть этот набор.
Я обнаружил, что у меня такая же проблема, мне нужно программно очищать данные, поступающие по-разному, с кэшированными сводными данными. Хотя тема немного устарела, по-прежнему не существует прямого доступа к данным.
ниже вы можете найти мой код, который является более обобщенной доработка уже написал решение.
основное отличие удаление фильтра из полей, как иногда pivot поставляется с фильтрами, и если вы вызываете .Showdetail пропустит отфильтрованные данные.
Я использую его для очистки от другого формата файла без необходимости открывать их, он служит мне довольно хорошо до сих пор.
надеюсь, что это полезно.
кредит spreadsheetguru.com о процедуре очистки фильтра (хотя я не помню, сколько оригинально и сколько мое, если честно)
Option Explicit
Sub ExtractPivotData(wbFullName As String, Optional wbSheetName As_
String, Optional wbPivotName As String, Optional sOutputName As String, _
Optional sSheetOutputName As String)
' This routine extracts full data from an Excel workbook and saves it to an .xls file.
Dim iPivotSheetCount As Integer
Dim wbPIVOT As Workbook, wbNEW As Workbook, wsPIVOT As Worksheet
Dim wsh As Worksheet, piv As PivotTable, pf As PivotField
Dim sSaveTo As String
Application.DisplayAlerts = False
calcOFF
Set wbPIVOT = Workbooks.Open(wbFullName)
' loop through sheets
For Each wsh In wbPIVOT.Worksheets
' if it is the sheet we want, OR if no sheet specified (in which case loop through all)
If (wsh.name = wbSheetName) Or (wbSheetName = "") Then
For Each piv In wsh.PivotTables
' remove all filters and fields
PivotFieldHandle piv, True, True
' make sure there's at least one (numeric) data field
For Each pf In piv.PivotFields
If pf.DataType = xlNumber Then
piv.AddDataField pf
Exit For
End If
Next pf
' make sure grand totals are in
piv.ColumnGrand = True
piv.RowGrand = True
' get da data
piv.DataBodyRange.Cells(piv.DataBodyRange.Cells.count).ShowDetail = True
' rename data sheet
If sSheetOutputName = "" Then sSheetOutputName = "datadump"
wbPIVOT.Sheets(wsh.Index - 1).name = sSheetOutputName
' move it to new sheet
Set wbNEW = Workbooks.Add
wbPIVOT.Sheets(sSheetOutputName).Move Before:=wbNEW.Sheets(1)
' clean new file
wbNEW.Sheets("Sheet1").Delete
wbNEW.Sheets("Sheet2").Delete
wbNEW.Sheets("Sheet3").Delete
' save it
If sOutputName = "" Then sOutputName = wbFullName
sSaveTo = PathWithSlash(wbPIVOT.path) & FilenameNoExtension(sOutputName) & "_data_" & piv.name & ".xls"
wbNEW.SaveAs sSaveTo
wbNEW.Close
Set wbNEW = Nothing
Next piv
End If
Next wsh
wbPIVOT.Close False
Set wbPIVOT = Nothing
calcON
Application.DisplayAlerts = True
End Sub
Sub PivotFieldHandle(pTable As PivotTable, Optional filterClear As Boolean, Optional fieldRemove As Boolean, Optional field As String)
'PURPOSE: How to clear the Report Filter field
'SOURCE: www.TheSpreadsheetGuru.com
Dim pf As PivotField
Select Case field
Case ""
' no field specified - clear all!
For Each pf In pTable.PivotFields
Debug.Print pf.name
If fieldRemove Then pf.Orientation = xlHidden
If filterClear Then pf.ClearAllFilters
Next pf
Case Else
'Option 1: Clear Out Any Previous Filtering
Set pf = pTable.PivotFields(field)
pf.ClearAllFilters
' Option 2: Show All (remove filtering)
' pf.CurrentPage = "(All)"
End Select
End Sub