Excel VBA - Get data from Pivot Table using 3 row elements and 1 column element

别说谁变了你拦得住时间么 提交于 2020-12-30 03:55:27

问题


I have a Pivot Table with more than 11,000 rows of data and 53 columns. I need a piece of code that very efficiently fetches data from a particular cell in the Pivot Table.

This is what the Pivot Table looks like:

I need to be able to fetch data from particular cells using the three (3) columns to the left as the conditions from picking the correct row and offset to the correct column by using the week numbers 1-50 at the top.

Here's a snippet of my current code (which works, but is probably highly inefficient since I need to this query about 48 times right now.

Dim oWB As Workbook: Set oWB = Workbooks.Open(tWB.Path & "\Telledata egeneide YTD.xlsx", ReadOnly:=True)
Dim oWS As Worksheet: Set oWS = oWB.Sheets("Telledata")
Dim pivotdata As Integer
Dim storeNo As Integer = 1101 'Example only - this can be anything between 1101 and 1199
Dim storeLoc As String = "0002" 'Example only - this value can be anything between 0001 and 0003
Dim materialGroup As Integer = 1120 'Example only - this can be anything between 1110 and 1899
Dim week as Integer = 11 'Example only - this can be anything between 1 and 50

pivotdata = Application.WorksheetFunction.CountIfs(oWS.Range("A:A"), storeNo, _
                                    oWS.Range("B:B"), storeLoc, _
                                    oWS.Range("C:C"), materialGroup, _
                                    oWS.Range("C:C").Offset(0, week), ">4")

I'm looking for values that are higher than 4. As mentioned, the query at the end needs to be run up to 48 times as it currently stands, as the variables in the code snippet changes.

Example query:

storeNo: 1101
storeLoc: 0001
materialGroup: 1141, 1142, 1143, 1410, 1420, 1451, 1220, 1260, 1270, 1710, 1720, 1730
week: 11, 12

storeNo: 1101
storeLoc: 0002
materialGroup: 1141, 1142, 1143, 1410, 1420, 1451, 1220, 1260, 1270, 1710, 1720, 1730
week: 11, 12

As you can see, all the queries have to be run twice (for each storeLoc), plus I have to check two WEEK columns (the chosen week and the week after).

I've been thinking about a For / For Each loop, but not sure how to go about that...


回答1:


Here's one approach using a dictionary lookup based on the unique combinations of the 3 lookup columns:

(untested)

Sub Tester()
    
    Dim pt As PivotTable, rngRows As Range, rngData As Range
    Dim dict As Object, arrRows, arrData, r As Long, k
    
    Set pt = ActiveSheet.PivotTables(1)
    
    'https://peltiertech.com/referencing-pivot-table-ranges-in-vba/
    Set rngRows = pt.RowRange   'get the rows range (includes headers)
    Set rngRows = rngRows.Offset(1, 0).Resize(rngRows.Rows.Count - 1) 'exclude headers
    arrRows = rngRows.Value     '... get as 2D array
    
    'create lookup based on the 3 columns
    Set dict = CreateObject("scripting.dictionary")
    For r = 1 To UBound(arrRows, 1)
        k = Key(arrRows(r, 1), arrRows(r, 2), arrRows(r, 3))
        dict(k) = r 'link the key to the row number
    Next r
    
    Set rngData = pt.DataBodyRange    'the data from the table
    arrData = rngData.Value           '... as 2D array
    
    
    'now you can use the lookup to quickly locate the data you want
    k = Key(storeNo, storeLoc, materialGroup)
    If dict.exists(k) Then
        weekVal = arrData(dict(k), WeekNum)
        If weekNum < UBound(arrData, 2) Then 
            nextWeekVal = arrData(dict(k), WeekNum + 1)
        End If
    Else
        'no match found
    End If
    
End Sub

'create key by concatenating the values with "|"
Function Key(v1, v2, v3)
    Key = Join(Array(v1, v2, v3), "|")
End Function




回答2:


Formula Solution

You can use INDEX & MATCH here to extract the value that corresponds to the row that fits your storeNo, storeLoc, materialGroup and the column that matches the week input.

=INDEX($A$1:$F$4,MATCH(1,($A$1:$A$4=H2)*($B$1:$B$4=I2)*($C$1:$C$4=J2),0),MATCH(K2,$A$1:$F$1))

Table Reference

Assuming a table (or pivot table) structure like below...

And a input table with target criteria like so...

Depending on your version of excel you may need to confirm this formula as array. To do that, enter the formula and confirm with CTRL + SHIFT + ENTER



来源:https://stackoverflow.com/questions/65352434/excel-vba-get-data-from-pivot-table-using-3-row-elements-and-1-column-element

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!