Thanks for the rep points YasserKhalil.
YasserKhalil wrote:
Is there an easy way to create UDF function that deal with arrays and we as beginner users use the UDF to have the results quickly? I imagine this : CreateFilteredArray(WholeRangeOfData,Column B,Column G)
=CreateFilteredArray(Range("A4:G92"),2,7)
The function you want can not be used in a formula (see the next post for reasons):
=CreateFilteredArray(Range("A4:G92"),2,7) 'This is NOT ALLOWED
Try the following function (a slight modification of function CreateStructureArrayOfFilteredData() in post #2 above, which can be used in other VBA code. All the code that follows can be tested using the data from the file in post #2 above.
Function CreateFilteredArray(myRange As Range, iColumn1 As Long, iColumn2 As Long) As Variant
'This returns a variant two dimensional array containing data from the input range, but
'only using data from the input columns (visible rows only)
Dim r1 As Range
Dim r2 As Range
Dim vArray As Variant
Dim v1 As Variant
Dim v2 As Variant
Dim iLastIndex As Long
Dim iRow As Long
Dim iFirstDataRow As Long
Dim iLastDataRow As Long
'Get the First and Last Data Rows
iFirstDataRow = myRange.Row
iLastDataRow = iFirstDataRow + myRange.Rows.Count - 1
'Verify that the input columns are in the Input Range
Set r1 = Intersect(myRange, Columns(iColumn1))
Set r2 = Intersect(myRange, Columns(iColumn2))
'Exit if 'iColumn1' is NOT in 'myRange'
If r1 Is Nothing Then
GoTo MYEXIT
End If
'Exit if 'iColumn2' is NOT in 'myRange'
If r2 Is Nothing Then
GoTo MYEXIT
End If
'Initialize the Variant array
ReDim vArray(1 To 2, 1 To 1)
iLastIndex = 0
'Create the Variant Array
For iRow = iFirstDataRow To iLastDataRow
'Get the address where the current row and the current column intersects
Set r1 = Intersect(myRange, Rows(iRow), Columns(iColumn1))
Set r2 = Intersect(myRange, Rows(iRow), Columns(iColumn2))
'Process the row if it is visible
If r1.EntireRow.Hidden = False Then
'Get the value for each column in the current row
v1 = r1.Value
v2 = r2.Value
'Add the value to the Variant array
iLastIndex = iLastIndex + 1
ReDim Preserve vArray(1 To 2, 1 To iLastIndex)
vArray(1, iLastIndex) = v1
vArray(2, iLastIndex) = v2
End If
Next iRow
'Clear object pointers
Set r1 = Nothing
Set r2 = Nothing
MYEXIT:
'Create the return array to be used by the calling routine
CreateFilteredArray = vArray
End Function
The following are a few ways to test the above function.
Sub TestCreateFilteredArray()
'Test Routine to Create a 2 dimensional Array of Variant data
Dim myRange As Range
Dim vArray As Variant
Dim i As Long
''''''''''''''''''''''''''''''''''''''''''''
'Bad Input Column Number Example
''''''''''''''''''''''''''''''''''''''''''''
vArray = CreateFilteredArray(Sheets("Store").Range("A4:G90"), 2, 22)
'Output the array contents in the Immediate Window (CTRL G in the debugger)
Debug.Print "vArray output created on " & Now()
If IsEmpty(vArray) = True Then
Debug.Print "CreateFilteredArray() had bad input data - vArray is EMPTY."
Else
For i = LBound(vArray, 2) To UBound(vArray, 2)
Debug.Print i, vArray(1, i), vArray(2, i)
Next i
End If
Debug.Print
''''''''''''''''''''''''''''''''''''''''''''
'Create an Array of Valid Filtered Data Example (Explicit Range as Formal Parameter)
''''''''''''''''''''''''''''''''''''''''''''
vArray = CreateFilteredArray(Sheets("Store").Range("A4:G90"), 2, 7)
'Output the array contents in the Immediate Window (CTRL G in the debugger)
Debug.Print "vArray output created on " & Now()
If IsEmpty(vArray) = True Then
Debug.Print "CreateFilteredArray() had bad input data - vArray is EMPTY."
Else
For i = LBound(vArray, 2) To UBound(vArray, 2)
Debug.Print i, vArray(1, i), vArray(2, i)
Next i
End If
Debug.Print
''''''''''''''''''''''''''''''''''''''''''''
'Create an Array of Valid Filtered Data Example (Range Object as Formal Parameter)
''''''''''''''''''''''''''''''''''''''''''''
Set myRange = Sheets("Store").Range("A4:G60")
vArray = CreateFilteredArray(myRange, 2, 7)
'Output the array contents in the Immediate Window (CTRL G in the debugger)
Debug.Print "vArray output created on " & Now()
If IsEmpty(vArray) = True Then
Debug.Print "CreateFilteredArray() had bad input data - vArray is EMPTY."
Else
For i = LBound(vArray, 2) To UBound(vArray, 2)
Debug.Print i, vArray(1, i), vArray(2, i)
Next i
End If
Debug.Print
'Clear object pointers
Set myRange = Nothing
End Sub
Lewis
Bookmarks