0

How can I filter a multidimensional array?

My code does neither work nor does it seem neat:

Option Explicit
Sub CalcE()
Dim TotalRows As Long
Dim myArray, myArray2 As Variant
Dim i, a As Integer

Populate Array

TotalRows = Sheets("Data").Rows(Rows.Count).End(xlUp).Row
myArray = Sheets("Data").Range("A5:F" & TotalRows)
MsgBox "Array populated with " & UBound(myArray) & "entries."

Filter myArray entries into myArray2, but only the column 1, 4 and 6.

a = 0
For i = 0 To UBound(myArray)
    If myArray(i, 1) > 1 Then
        myArray2(a, 1) = myArray(i, 1)
        myArray2(a, 2) = myArray(i, 4)
        myArray2(a, 3) = myArray(i, 6)
        a = a + 1
    End If
Next i    
MsgBox "Array populated now with " & UBound(myArray2) & "entries."
End Sub

I googled and figured that arrays in Excel seem to be very inflexible things, not nice to work with. People usually give up on VBA Arrays and use AutoFilter methods instead. I wounder whether there really isn't a good way. It would be so neat to have!

2 Answers 2

3

If all you need is to store the columns 1, 4 and 6 into myArray2, give this a try...

Dim ws As Worksheet
Set ws = Sheets("Data")
TotalRows = ws.Rows(Rows.Count).End(xlUp).Row
myArray2 = Application.Index(ws.Cells, Evaluate("Row(5:" & TotalRows & ")"), Array(1, 4, 6))

Or you may tweak your code like this...

Dim ws As Worksheet
Set ws = Sheets("Data")
Dim cnt As Long, j As Long
TotalRows = ws.Rows(Rows.Count).End(xlUp).Row
myArray = ws.Range("A5:F" & TotalRows).Value
cnt = Application.CountIf(ws.Range("A5:A" & TotalRows), ">1")
If cnt = 0 Then Exit Sub
ReDim myArray2(1 To cnt, 1 To 3)
For i = 1 To UBound(myArray, 1)
    If myArray(i, 1) > 1 Then
        j = j + 1
        myArray2(j, 1) = myArray(i, 1)
        myArray2(j, 2) = myArray(i, 4)
        myArray2(j, 3) = myArray(i, 6)
    End If
Next i

MsgBox UBound(myArray2, 1)
Sign up to request clarification or add additional context in comments.

3 Comments

This works, thanks! But how can I filter? I want to get rid of all entries that, let's say, have a value of <1 in column 1.
In that case you may tweak your code as I have shown in the answer. See the edited answer.
This does solve my issue and ReDim within the loop is avoided. Thanks again.
1

Arrays are not very flexible: in particular not easy to resize (though you can do so using Redim Preserve.

Personally I would use a Collection if you want a variable number of items and or want to filter items in VBA.

First define a Class Module with properties or fields that represent the columns of your 2D array. You should give the class and it's properties meaningful names, and appropriate data types, but I don't know your application so I'll use:

Class Module "MyClass":

    Public Col1 As Variant
    Public Col4 As Variant
    Public Col6 As Variant

You can then create a Collection and add instances of your class to it as follows:

Dim col As Collection
Set col = New Collection
For i = LBound(myArray, 1) To UBound(myArray, 1)
    If myArray(i, 1) > 1 Then
        Dim c As MyClass
        Set c = New MyClass
        c.Col1 = myArray(i, 1)
        c.Col4 = myArray(i, 4)
        c.Col6 = myArray(i, 6)
        col.Add c
    End If
Next I

You can then filter it further, e.g.:

Dim col2 As Collection
Set col2 = New Collection
For Each c In col
    If c.Col1 = 5 Then
        col2.Add c
    End If
Next c

And finally copy it back to a 2D array so you can write it back to an Excel Sheet:

Dim myArray2() As Variant
Dim c As MyClass
ReDim myArray2(0 To col2.Count - 1, 0 To 6)
For i = 0 To col2.Count - 1
    Set c = col2(i + 1) ' Collection indexes are 1-based
    myArray2(i, 1) = c.Col1
    myArray2(i, 4) = c.Col4
    myArray2(i, 6) = c.Col6
Next i

You could even write a Class Module that is a strongly-typed collection of MyClass objects, a class module MyClassCollection as described in the linked blog article.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.