These solutions overcome some limitations of redimming a 2-dimensional array:
1. Simple (formula) alternative using dynamic arrays in ►Office 365 // (First post)
Write this formula to your target cell (e.g. C2
, assuming target in Sheet2):
Sheet2.Range("C2").Formula2 = "=FILTER(Sheet1!B:C,Sheet1!A:A=""USA"")"
If you want to include the repeated "USA" text, simply change to
Sheet2.Range("C2").Formula2 = "=FILTER(Sheet1!A:C,Sheet1!A:A=""USA"")"
Once written to target, results get adapted after changes in the referred columns of the source worksheet (Sheet1
).
2. Array approach for ►prior Office versions // (Edit 2020-11-06)
In order to complete above solutions I demonstrate an array approach filtering data (passed by reference) via help procedure ResizeData
:
Sub Example call()
' [0] define range
Dim lastRow As Long: lastRow = Tabelle1.Cells(Cells.Rows.Count, "A").End(xlUp).Row
Dim rng As Range
Set rng = Sheet1.Range("A2:C" & lastRow) ' << change to entire data range
' [1a] create 2-dim data field array (1-based)
Dim data: data = rng.Value2
' [1b] filter data rows where items in 1st column equal "USA"
ResizeData data ' or: ResizeData data, 1, "USA"
' [2] write filtered data field to any target
Sheet2.Range("B2").Resize(UBound(data), UBound(data, 2)) = data
End Sub
Help procedure ResizeData
Using the rearranging possibilities of the Application.Index()
function (and assuming to return only columns 2:3 as indicated in Evaluate()
to avoid repeated "USA" fields of column 1)
Sub ResizeData(data, Optional colNo As Long = 1, Optional criteria As String = "USA")
'Purpose: filter data field array based on criteria in given column
data = Application.Transpose(Application.Index( _
data, _
getRowNums(data, colNo, criteria), _
Evaluate("row(2:" & UBound(data, 2) & ")")))
End Sub
Function getRowNums(v, ByVal colNo As Long, criteria As String) As Variant()
' Purpose: collect row numbers meeting criteria (default ="USA" in 1st column)
' Note: called by above procedure DelRows
Dim tmp: ReDim tmp(0 To UBound(v) - 1)
Dim i As Long, n As Long
For i = 1 To UBound(v)
If UCase$(v(i, colNo)) = criteria Then ' check array items
tmp(n) = i ' collect valid row numbers
n = n + 1 ' increment results counter
End If
Next i
ReDim Preserve tmp(0 To n - 1) ' resize row numbers array
'return function result
getRowNums = tmp
End Function