I had a problem internally with my users with the JET/ACE methods I had been using for years to query internal same workbook data in ListObject tables. After running down many options I thought I had a winner by using an autofilter on the tables, pulling the data into an array and trying to clean it up and passing it back to the existing code. While this works most of the time I found a scenario that it's only pulling some of the data. I have a LO table I'm testing with that has 30 rows and the auto filter is clearing out rows 13-15 and 28-30. When get to the part of code that gets the DataBodyRange.SpecialCells(xlCellTypeVisible) to set the array it only pulls rows 1-12 and not all 24 rows that are showing in the autofilter.
Here's the code for that portion
Here's the code for that portion
VBA Code:
Public Function QueryTable(sTable As String, sCol As String, sQuery As Variant, Optional sCol2 As String, Optional sQuery2 As Variant, Optional sCol3 As String, Optional sQuery3 As Variant, Optional sSortCol As String, Optional blDesc As Boolean, Optional arFields As Variant) As Variant
Dim tbl As ListObject
Dim iCol As Integer
Dim iCol2 As Integer
Dim iCol3 As Integer
Dim iSortCol As Integer
Dim arResults As Variant
Dim arReturn() As String
Dim iLoop1 As Integer
Dim iLoop2 As Integer
Set tbl = GetTable(sTable)
Call WriteLogFile("QueryTable: Table " & tbl.Name & " sCol = " & sCol, True)
On Error GoTo ERROR:
iCol = CInt(Application.Match(sCol, tbl.HeaderRowRange, 0))
If sCol2 <> "" Then iCol2 = CInt(Application.Match(sCol2, tbl.HeaderRowRange, 0))
If sCol3 <> "" Then iCol3 = CInt(Application.Match(sCol3, tbl.HeaderRowRange, 0))
tbl.AutoFilter.ShowAllData
tbl.Range.AutoFilter Field:=iCol, Criteria1:=sQuery, Operator:=xlFilterValues
If sCol2 <> "" Then tbl.Range.AutoFilter Field:=iCol2, Criteria1:=sQuery2, Operator:=xlFilterValues
If sCol3 <> "" Then tbl.Range.AutoFilter Field:=iCol3, Criteria1:=sQuery3, Operator:=xlFilterValues
If sSortCol <> "" Then
Dim rngSort As Range
Dim tmp As String
tmp = sTable & "[" & sSortCol & "]"
Set rngSort = Range(sTable & "[" & sSortCol & "]")
With tbl.Sort
.SortFields.Clear
If blDesc Then
.SortFields.Add Key:=Range(sTable & "[" & sSortCol & "]"), SortOn:=xlSortOnValues, Order:=xlDescending
Else
.SortFields.Add Key:=Range(sTable & "[" & sSortCol & "]"), SortOn:=xlSortOnValues, Order:=xlAscending
End If
.Header = xlYes
.Apply
End With
End If
arResults = tbl.DataBodyRange.SpecialCells(xlCellTypeVisible)
tbl.AutoFilter.ShowAllData
tbl.Sort.SortFields.Clear
QueryTable = arResults
If IsArray(arFields) Then
ReDim arReturn(LBound(arResults) To UBound(arResults), LBound(arFields) To UBound(arFields))
For iLoop1 = LBound(arResults) To UBound(arResults)
For iLoop2 = LBound(arFields) To UBound(arFields)
iCol = CInt(Application.Match(arFields(iLoop2), tbl.HeaderRowRange, 0))
arReturn(iLoop1, iLoop2) = arResults(iLoop1, iCol)
Next iLoop2
Next iLoop1
QueryTable = arReturn
End If
Exit Function
ERROR:
tbl.AutoFilter.ShowAllData
tbl.Sort.SortFields.Clear
QueryTable = Array("")
Call WriteLogFile("QueryTable: Table " & tbl.Name & " sCol = " & sCol & "Failed to lookup", True)
End Function