Using index in VBA - excel

I am trying to select ranges from an excel workbook to paste at certain locations in a word document template. I have a table in sheet 3 that has a column with Table1 then the cell next to it is empty. Table1 is written in the word document in the place where I want table one to be pasted. I have the following code to try and select the range of each table based on the header number of the table and loop through all tables. Any help would be appreciated, If you have another method let me know. This is the code I have so far.
Sub Auto()
Dim cell As Range
Dim rng As Range
Dim wdApp As New Word.Application
Dim wdDoc As Word.Document
Dim wdDoc2 As Word.Document
Dim FilePath As String
Dim FilePath2 As String
Dim ending As String
Dim rngPara As Range
Dim Prompt As String
Dim Filesave As String
Dim FileSave2 As String
Dim CL As Range
Dim rngg As Range
'On Error GoTo ErrorHandler
'FilePath = ThisWorkbook.Path
'FilePath2 = Left(FilePath, InStr(FilePath, "\Calculations") - 1)
'FileName2 = "Disclosures Temps.docx"
'StrDoc = FilePath2 & "\Input" & "\" & FileName2
'Set wdDoc2 = wdApp.Documents.Open(StrDoc)
Set rngPara = Sheet3.Range("A1:Z1058").Find("Table Key")
If rngPara Is Nothing Then
MsgBox "Table Key column was not found."
GoTo ErrorHandler
End If
Set rng = Sheet3.Range(rngPara, rngPara.End(xlDown))
For Each cell In rng
If cell.Value = "" Then Exit For
For i = 6 To Sheet3.Range("TableNumber").Value
rownum = WorksheetFunction.Match(Format(i, "0"), Range("A:A"), 0)
rownend = WorksheetFunction.Match(Format(i + 1, "0"), Range("A:A"), 0) - 1
rowww = rownum & ":" & rownum
coll = WorksheetFunction.Index(Sheet1.Range("4:4") = "", 0)
colnumber = WorksheetFunction.Match(True, WorksheetFunction.Index(Range("4:4") = "", 0), 0) - 1
ColLetter = Split(Cells(1, colnumber).Address, "$")(1)
rng.Cells.Offset(0, 1).Value = "A" & rownum & ":" & ColLetter & rowend
Next i
Next

You can access named ranges/tables in Excel VBA through the worksheets ListObjects collection. Knowing that we can loop through the worksheets and then through the ListObjects property to access each table. From there you can search for a key if you like or you can go off the name of the table instead which might be easier and paste where you want in the Word document.
The example below is meant to be run from the Word document directly but you can adapt to run from Excel instead. The example opens the Excel workbook containing the tables, loops through the worksheets and their ListObjects collection, copies the tables, and pastes them to the bottom of the Word document.
Sub InsertTablesFromExcelToEndOfDocument()
Const strWorkbookPath As String = "C:\temp\search.xlsm" 'the name and path of the workbook
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
Dim xlTable As Object
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open(FileName:=strWorkbookPath)
xlApp.Visible = False
For Each xlSheet In xlBook.Worksheets()
For Each xlTable In xlSheet.ListObjects 'Use ListObjects to access Named Table Ranges
Debug.Print "Worksheet Name: " & xlSheet.Name
With xlTable
Debug.Print "-- Table Name: " & .Name
Debug.Print "-- Table Range: " & .Range.Address
Debug.Print ""
.Range.Copy
With ThisDocument.Content
.InsertParagraphAfter
.Paragraphs.Last.Range.PasteExcelTable LinkedToExcel:=False, WordFormatting:=False, RTF:=False
End With
End With
Next xlTable
Next xlSheet
Cleanup:
xlApp.Quit
End Sub
Update
The following update is an adjustment to the previous code with some code to search for the table name in the document and paste the corresponding tables there. I went with surrounding the table names with angle brackets just so that it is less likely to mistake real content for the table placeholders
Sub InsertTablesFromExcelAtPlaceholders()
Const strWorkbookPath As String = "C:\temp\search.xlsm" 'the name and path of the workbook
Dim xlApp As Object
Dim xlBook As Object
Dim xlSheet As Object
Dim xlTable As Object
Dim myRange As Range
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Open(FileName:=strWorkbookPath)
xlApp.Visible = False
For Each xlSheet In xlBook.Worksheets()
For Each xlTable In xlSheet.ListObjects 'Use ListObjects to access Named Table Ranges
'Debug.Print "Worksheet Name: " & xlSheet.Name
Debug.Print "-- Table Name: " & xlTable.Name
'Debug.Print "-- Table Range: " & xlTable.Range.Address
'Debug.Print ""
Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="<" & xlTable.Name & ">"
While myRange.Find.Found = True
xlTable.Range.Copy
myRange.Paste
Set myRange = ActiveDocument.Content
myRange.Find.Execute FindText:="<" & xlTable.Name & ">", Forward:=True
Wend
Next xlTable
Next xlSheet
Cleanup:
xlApp.Quit
End Sub
Can I alter the code to work for a certain range that is not necessarily a table. like I want to specify the range like from the header to the last empty row and from column A to the last empty column. Is this possible?
Sure this is possible, but I would recommend converting the range to a named table instead if possible which would greatly simplify things. You're either defining this range there in the Excel workbook or directly in the code. It's easier to manage if you can define the range and the placeholder outside of the code rather than dipping into the code every time you need to define a new table range.
But back to your question, I think it would be easier to answer if I understood this "Table Key" idea you have. In the code you are looking through what looks like the whole spreadsheet for this "table key" however in your post you say "I have a table in sheet 3 that has a column with Table1 then the cell next to it is empty.". So is your table key actually the first cell in this column you mention? It would be helpful to see an example of the table and this key. If you're interested you can edit your post and add a screenshot or two.

Related

Mail merge into a Word document generates Error Code 4248

My goal is to use two dropdown menus (DM) within a workbook to open a filled-out document.
The DM 1 is to select which row of data will be merged.
The DM 2 is to select which template is being used.
I have separate code that highlights the selected row and opens the document.
Set doc = appWD.ActiveDocument gives me
error 4248 This command is not available because no document is open.
The template is open when I receive this error.
For Context:
Open_LPA_Template, run by itself, does open the Word document selected from the DM 2.
Select_Parcel, run by itself, does highlight the row of data selected from the DM 1.
Sub Run_Mail_Merge_LPA()
Dim doc As Word.Document
Dim appWD As Object
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim tbl As ListObject
Dim row As ListRow
Dim searchValue As String
Dim searchRange As Range
Dim foundCell As Range
' Get references to the workbook and worksheets
Set wb = ThisWorkbook
Set ws = wb.Worksheets(1)
Set ws2 = wb.Worksheets(2)
' Create an instance of the Word application
Set appWD = CreateObject("Word.Application")
' Open the Word document that has been selected in DM 2
Open_LPA_Template
' Select_Parcel's CODE: Select the Row of Data from DM 1 for the Mail Merge
ws2.Select
' Select cell D3 in worksheet 2
ws2.Range("D3").Select
' Store the value in D3 of worksheet 2 in a variable
searchValue = ws2.Range("D3").Value
' Set the search range to the entire column A of worksheet 1
ws.Select
Set searchRange = ws.Range("A:A")
' Use the Find method to search for the search value in the search range
Set foundCell = searchRange.Find(searchValue)
If Not foundCell Is Nothing Then
' If a match is found, select the cell
foundCell.Select
ActiveCell.EntireRow.Select
Else
' If no match is found, print a message
Debug.Print "Value not found in column A"
End If
' MAIL MERGE CODE: Set the active document to the Word document that was opened
Set doc = appWD.ActiveDocument
' Perform the mail merge
doc.MailMerge.MainDocumentType = wdFormLetters
doc.MailMerge.OpenDataSource _
Name:=row.Range, _
ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
WritePasswordDocument:="", WritePasswordTemplate:=""
doc.MailMerge.Execute
End Sub
Sub Open_LPA_Template()
Dim wb As Workbook
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim MainPath As String
Dim MainPath2 As String
Dim MainPath3 As String
Dim MainPath4 As String
Dim MainPath5 As String
Dim MainPath6 As String
Dim Parcel As String
Dim fileName As String
Dim FullPath As String
Dim mWord As Object
Set wb = ThisWorkbook
Set ws = wb.Worksheets(1)
Set ws2 = wb.Worksheets(2)
Set appWD = CreateObject("Word.Application")
appWD.Visible = True
MainPath = "C:\Users\ME\Dropbox (ORC)\Desktop\Templates\LPA\"
MainPath2 = "C:\Users\USER1\Dropbox (ORC)\Desktop\Templates\LPA\"
MainPath3 = "C:\Users\USER2\Dropbox (ORC)\Desktop\Templates\LPA\"
MainPath4 = "C:\Users\USER3\Dropbox (ORC)\Desktop\Templates\LPA\"
MainPath5 = "C:\Users\USER4\Dropbox (ORC)\Desktop\Templates\LPA\"
MainPath6 = "C:\Users\USER5\Dropbox (ORC)\Desktop\Templates\LPA\"
fileName = ws2.Range("E3")
' Check if the file exists at the first path
If Dir(MainPath & fileName & ".docx") <> "" Then
FullPath = MainPath & fileName & ".docx"
ElseIf Dir(MainPath2 & fileName & ".docx") <> "" Then
' If the file does not exist at the first path, check the second path
FullPath = MainPath2 & fileName & ".docx"
ElseIf Dir(MainPath3 & fileName & ".docx") <> "" Then
' If the file does not exist at either of the first two paths, check the third path
FullPath = MainPath3 & fileName & ".docx"
ElseIf Dir(MainPath4 & fileName & ".docx") <> "" Then
' If the file does not exist at any of the first three paths, check the fourth path
FullPath = MainPath4 & fileName & ".docx"
ElseIf Dir(MainPath5 & fileName & ".docx") <> "" Then
' If the file does not exist at any of the first four paths, check the fifth path
FullPath = MainPath5 & fileName & ".docx"
Else
' If the file does not exist at any of the first five paths, use the sixth path
FullPath = MainPath6 & fileName & ".docx"
End If
appWD.Documents.Open (FullPath)
There are six paths because it could be accessed/used by six people who get to the shared Word documents through their own computers.
Since you are creating a new instance of Word via
Set appWD = CreateObject("Word.Application")
That Word instance has no open documents. You need to open the relevant document and address it via code like:
Set doc = appWD.Documents.Open(Filename:="C:\Users\Aaron Bradow\Documents\Mail Merge Document.docx", AddToRecentFiles:=False, ReadOnly:=True)
The problem is that you create two separate instances of Word Application in the code and try to access a Document instance opened in another Word Application instance/process. If you want to use the ActiveDocument property you need to deal with a single Word Application instance in the code. So, you may pass a created Word Application instance as a parameter to the method to open files.
Be aware, the Documents.Open function from the Word object model opens the specified document and adds it to the Documents collection. It also returns a Document object which can be used instead of the ActiveDocument property in the code.
Sub OpenDoc()
Dim doc As Word.Document
Set doc = Documents.Open FileName:="C:\MyFiles\MyDoc.doc"
End Sub

Issue with running the Find method for ranges in two different workbooks

I am trying to run the Find method between two ranges in two different workbooks - If a value in the second range isn't found in the first range, then the data in the entire row to which the aforesaid cell belongs to should be copied from the second workbook and pasted in the first workbook. Each time I try to run my code I get runtime error #438 - Object doesn't support this property or method:
Option Explicit
Sub Data_Transfer()
Dim FileToOpen As Variant
Dim FileCount As Byte, SheetCount As Byte, SheetFound As Byte
Dim SelectedBook As Workbook
Dim WkSh As Worksheet
Dim Cell As Range, ChosenCell As Range, LookInRange As Range, LookAtRange As Range
FileToOpen = Application.GetOpenFilename(Title:="Select Files to Import Data", FileFilter:="Excel Files(*.xls*), *.xls*", MultiSelect:=True)
If IsArray(FileToOpen) Then 'Allows the user to click on the 'Cancel' button without it leading to an error
For FileCount = 1 To UBound(FileToOpen)
Set SelectedBook = Workbooks.Open(FileToOpen(FileCount))
'If a worksheet already exists for the month:
For SheetCount = 1 To ThisWorkbook.Worksheets.Count
If ThisWorkbook.Worksheets(SheetCount).Name = VBA.Replace(SelectedBook.Name, ".xls", "") Then
SheetFound = 1
Set WkSh = ThisWorkbook.Worksheets(SheetCount)
WkSh.Activate
MsgBox "A worksheet already exists for the selected month."
'Check if there are any expenses missing for the month:
Set LookInRange = ThisWorkbook.ActiveSheet.Range("C2:C" & Range("C2").End(xlDown).Row)
Set LookAtRange = SelectedBook.ActiveSheet.Range("C23:C" & Range("C2").End(xlDown).Row)
For Each Cell In LookAtRange
Set ChosenCell = LookAtRange.Find(LookInRange.Cell, , xlValues, xlWhole)
If ChosenCell Is Nothing Then
ChosenCell.EntireRow.Copy WkSh.Range("A" & Range("A1").End(xlDown).Row + 1)
End If
Next Cell
End If
If SheetFound = 1 Then: Exit Sub
Next SheetCount
'If a worksheet does not exist for the month:
With ThisWorkbook
.Worksheets.Add After:=Sheet11
.ActiveSheet.Name = VBA.Replace(SelectedBook.Name, ".xls", "")
SelectedBook.Worksheets(1).Range("A23").CurrentRegion.Copy .ActiveSheet.Range("A1")
SelectedBook.Close
For Each Cell In .ActiveSheet.Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row)
If VBA.Left(Cell.Value, 1) = "*" Then
Cell.EntireRow.Delete
End If
Next Cell
.ActiveSheet.Columns.AutoFit
End With
Next FileCount
End If
End Sub
Always specify for all Range, Cells, Rows and Columns objects in which workbook and worksheet they are.
If you don't do that for example like here:
Set LookAtRange = SelectedBook.ActiveSheet.Range("C23:C" & Range("C2").End(xlDown).Row)
Then the first Range is in SelectedBook.ActiveSheet but the second may be or may be not! As long it is not defined you don't know:
Set LookAtRange = SelectedBook.ActiveSheet.Range("C23:C" & SelectedBook.ActiveSheet.Range("C2").End(xlDown).Row)
So make clear that Range, Cells, Rows and Columns objects are always fully referenced to a workbook/worksheet.

Combining workbook values into a single column

I have a task where I have two workbooks, one source and one destination. The task is to search a column in the destination workbook for a value that contains a certain string. When found, I have to search the source workbook in a certain column to find a matching string. I then take values from 2 other columns in that same row in the source workbook, combine them, and write them to a cell in the destination workbook.
The issue is that the values are being written to the wrong rows in the destination workbook, like this:
example1Broken
When it should look like this:
example2proper
Here is my current vba:
Sub CombineWorkbooks()
Dim var As Variant
Dim col As Variant
Dim i As Long
Dim Cell As Range
Dim wbSource As Workbook
Set wbSource = Workbooks.Open(Filename:="CopyFromWorkbookSource.xlsx", UpdateLinks:=3)
Dim wbDest As Workbook
Set wbDest = Workbooks.Open(Filename:="CopyFromWorkbookDest.xlsm", UpdateLinks:=3)
Dim address As Variant
Dim newAddressRow As Variant
Dim sourceVal1 As Variant
Dim sourceVal2 As Variant
'Dest wb number column that contains the search query
Dim sourceCol As Integer
sourceCol = 1
wbDest.Activate
'col = Split(ActiveCell(1).address(1, 0), "$")(0)
For i = 1 To Rows.Count
var = Cells(i, sourceCol).Value
If var Like "*WI*" And Not IsEmpty(Cells(i, sourceCol).Value) Then
wbSource.Activate
Set Cell = Nothing
Set Cell = Selection.Find(What:=var, LookIn:=xlValues)
If Cell Is Nothing Then
' MsgBox "Nothing"
Else
'We found a match!
MsgBox "Found hit for " & var & ": " & Cell.address
'This is where the value was found in the source workbook
address = Cell.address
'This is where the new value must go in the dest workbook NOTE the column letter must change!
newAddressRow = Split(address, "$A$")(1)
'Get the cell values from the source wb
sourceVal1 = Cells(newAddressRow, 2)
sourceVal2 = Cells(newAddressRow, 3)
MsgBox "SourceVal1: " & sourceVal1 & " SourceVal2: " & sourceVal2 & " Newaddressrow: " & newAddressRow & " i: " & i
'Activate the dest workbook for pasting
wbDest.Activate
'Write the source wb values into a single cell in the dest wb
Cells(i, 2).Value = sourceVal1 & Chr(10) & sourceVal2
End If
End If
Next i
End Sub
Consider removing the address variable and set the sourceVals using the found Cell's Row parameter. Also consider direct referencing workbooks and sheets instead of activating; see below.
Sub CombineWorkbooks()
Dim i As Long
Dim Cell As Range
Dim wbSource As Workbook
Dim wbDest As Workbook
Dim sourceCol As Integer 'Destwb number column that contains the search query
Set wbSource = Workbooks.Open(Filename:="CopyFromWorkbookSource.xlsx", UpdateLinks:=3)
Set wbDest = Workbooks.Open(Filename:="CopyFromWorkbookDest.xlsm", UpdateLinks:=3)
sourceCol = 1
' start at 2 to dodge the header
For i = 2 To wbDest.Sheets(1).Rows.Count
'this conditional can be removed if all non-header rows will contain WI
If wbDest.Sheets(1).Cells(i, sourceCol).Value Like "*WI*" Then
Set Cell = wbSource.Sheets(1).UsedRange.Find(What:=wbDest.Sheets(1).Cells(i, sourceCol).Value, LookIn:=xlValues)
If Not Cell Is Nothing Then
'We found a match!
'Write the source wb values into a single cell in the dest wb
Cells(i, 2).Value = wbSource.Sheets(1).Cells(Cell.Row, 2) & Chr(10) & wbSource.Sheets(1).Cells(Cell.Row, 3)
End If
End If
Next i
End Sub

Find values from a Word table in an Excel table

I want to iterate through the values of a column in a table in a word file, and check if those values are in a column in a table in an Excel file. I have the following code:
Private Sub CompararColumnas_Click()
Dim wrdTbl As Table
'Set your table
With ActiveDocument
If ActiveDocument.Tables.Count >= 1 Then
Set wrdTbl = .Tables(InputBox("Table # to copy? There are " & .Tables.Count & " tables to choose from."))
End If
End With
Dim AD_UsersPath As String
AD_UsersPath = "C:\Users\" & Environ("Username") & "\Desktop\Comparar Columnas VBA\Animales.xlsx"
Dim AD_USERS As Object
Set AD_USERS = CreateObject("Excel.Application")
AD_USERS.Visible = False
AD_USERS.Application.Workbooks.Open AD_UsersPath
LastRow = ThisDocument.Tables(1).Columns(1).Cells.Count
Dim I As Integer
For I = 1 To LastRow
wVal = ThisDocument.Tables(1).Cell(I, 1)
User = AD_USERS.Cells(AD_USERS.Range("A:A").Find(What:=wVal).Row, 1).Text
wrdTbl.Cell(I, 2).Range.Text = User
Next I
End Sub
This code iterates in wVal the values from the first column in a table from Word and after that it goes to Excel to find those values in the first column of the Excel table. If it finds them, it copies the values in the second column of the word table. However, it gives me an error 91. If instead of Find(What:=wVal) I put something like Find(What:="Word") it does not give me an error and puts the word "Word" in every cell of the second column of the word table. How can I solve this?
Cell values in Word have a two-character "end of cell" marker (Chr(13) + Chr(7)) which you need to remove:
Private Sub CompararColumnas_Click()
Dim wrdTbl As Table
'Set your table
With ActiveDocument
If ActiveDocument.Tables.Count > 1 Then
Set wrdTbl = .Tables(InputBox("Table # to copy? There are " & _
.Tables.Count & " tables to choose from."))
Else
Set wrdTbl = .Tables(1) 'default to the only table
End If
End With
Dim AD_UsersPath As String, wb As Object, ws As Object
AD_UsersPath = "C:\Users\" & Environ("Username") & _
"\Desktop\Comparar Columnas VBA\Animales.xlsx"
Dim AD_USERS As Object
Set AD_USERS = CreateObject("Excel.Application")
AD_USERS.Visible = False
Set wb = AD_USERS.Workbooks.Open(AD_UsersPath)
Set ws = wb.Worksheets(1)
Dim LastRow As Long, I As Long, User
LastRow = wrdTbl.Columns(1).Cells.Count
For I = 1 To LastRow
wVal = TwrdTbl.Cell(I, 1)
Left(wVal, Len(wVal)-2) 'strip off "end of cell" marker
User = ws.Cells(ws.Range("A:A").Find(What:=wVal).Row, 1).Text
wrdTbl.Cell(I, 2).Range.Text = User
Next I
wb.Close False
AD_USERS.Quit
End Sub

Filter pivot table (connected to an external source) with range of random items

I have a list of random items that I want to filter in an Excel pivot table. The pivot table is connected to an external data source. Is there any way I can filter my entire list in the pivot table without adding one item at a time to the filter?
I've tried below code in VBA, which works on a local data source, but not when it's external.
"56607016", "84000110", "8A20371" are some examples of items from my list.
If there is a better solution than VBA here, please tell me.
Sub FilterPivotItems()
Dim PT As PivotTable
Dim PTItm As PivotItem
Dim FiterArr() As Variant
' use an array to select the items in the pivot filter you want to keep visible
FiterArr = Array("56607016", "84000110", "8A20371")
' set the Pivot Table
Set PT = ActiveSheet.PivotTables("PivotTable2")
' loop through all Pivot Items in "Product number" Pivot field
For Each PTItm In PT.PivotFields("[Released products].[Product number].[Product number]").PivotItems
If Not IsError(Application.Match(PTItm.Caption, FiterArr, 0)) Then ' check if current item is not in the filter array
PTItm.Visible = True
Else
PTItm.Visible = False
End If
Next PTItm
End Sub
The error message I get when running:
"Run-time error '1004': Unable to get the _NewEnum property of the PivotItems class"
Instead of using For Each loop, change the FilterArr to pivot reference and then you can use set the value of the .VisibleItemsList to your FilterArr. Here is an example.
FilterArr = Array( _
"[myTableName].[myPivotField].&[myPivotItem1]", _
"[myTableName].[myPivotField].&[myPivotItem2]")
ActiveSheet.PivotTables("PivotTable2").PivotFields( _
"[myTableName].[myPivotField].[myPivotField]").VisibleItemsList = FilterArr
This example assumes that you have a worksheet in the same workbook, with a table that contains the values for which the pivot table should be filtered. The pivot filter string for each filter value is created with a formula in the adjacent column and then read into an array. Additional variables are created with the values from named ranges.
Sub FilterPivot_WithListOfValues()
'---------------------------------------------------------------------------------------------------------
' Purpose: Dynamically create an array based on the values of one column of a table.
'
' Customize: Inputs in this sub come from 6 named ranges on a worksheet in this workbook.
' myPivotTableName, myPivotFieldName, mySheetName,
' myFilterTableName, smyDataTableName, myFilterCol
'
' Revisions:
' 09/30/19 Sub created
'
'---------------------------------------------------------------------------------------------------------
'~~~> Set the data types for the variables.
Dim oPT As PivotTable
Dim oPF As PivotField
Dim oPI As PivotItem
Dim strPT As String 'pivot table name
Dim strPF As String 'pivot field name
Dim strWS As String 'pivot table sheet name
Dim oWS As Worksheet
Dim oFTable As ListObject
Dim oDTable As ListObject
Dim strFTable As String 'filter table name
Dim strDTable As String 'data table name
Dim strFilterString As String 'pivot table filter string
Dim FilterArr() As Variant
Dim TempArray
Dim i As Long
Dim iCol As Long
'~~~> Assign the variables.
strPT = [myPivotTableName]
strPF = [myPivotFieldName]
strWS = [mySheetName]
strFTable = [myFilterTableName]
strDTable = [myDataTableName]
iCol = [myFilterCol]
'~~~> Build the filter string. Don't include the quotation marks wrapper.
' That is automatically added by .PivotFields
strFilterString = "[" & strDTable & "].[" & strPF & "].[" & strPF & "]"
'~~~> Check the variables in the Immediate Window.
Debug.Print "Variable Set: strPT = " & strPT
Debug.Print "Variable Set: strPF = " & strPF
Debug.Print "Variable Set: strWS = " & strWS
Debug.Print "Variable Set: strDTable = " & strDTable
Debug.Print "Variable Set: strFTable = " & strFTable
Debug.Print "Variable Set: iCol = " & iCol
Debug.Print "Variable Set: strFilterString = " & strFilterString
'~~~> Set the path for the table variable
Set oFTable = Range(strFTable).ListObject
'~~~> Set the path for the sheet variable
Set oWS = Worksheets(strWS)
'~~~> Create an array list from a table column.
TempArray = oFTable.DataBodyRange.Columns(iCol)
'~~~> Convert from vertical array to horizontal array list.
FilterArr = Application.Transpose(TempArray)
DisplayArrayValues:
'~~~> Loop through each item in the table array and display in Immediate Window [ctrl + g]
For i = LBound(FilterArr) To UBound(FilterArr)
Debug.Print FilterArr(i)
Next i
ApplyPivotFilters:
'~~~> Apply filters to the pivot table.
Set oPF = oWS.PivotTables(strPT).PivotFields(strFilterString)
With oPF
.VisibleItemsList = FilterArr
End With
ReleaseVariables:
'~~~> Release the variables from memory.
Set oPT = Nothing
Set oPF = Nothing
Set oPI = Nothing
Set oWS = Nothing
Set oFTable = Nothing
Set oDTable = Nothing
strPT = vbNullString
strPF = vbNullString
strWS = vbNullString
strFTable = vbNullString
strDTable = vbNullString
strFilterString = vbNullString
i = vbNull
iCol = vbNull
End Sub
This is a snip of the filter table and named ranges.
This is the formula that is used to generate the filter string.
="["&myDataTableName&"].["&myPivotFieldName&"].&["&[#[Pivot Items]]&"]"

Resources