简体   繁体   English

在Excel VBA中过滤数组

[英]Filter Array in Excel VBA

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. 将myArray条目过滤到myArray2中,但仅过滤第1、4和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. 我用谷歌搜索并发现Excel中的数组似乎是非常僵化的东西,不好用。 People usually give up on VBA Arrays and use AutoFilter methods instead. 人们通常会放弃使用VBA数组,而使用自动筛选方法。 I wounder whether there really isn't a good way. 我为是否真的没有一个好方法而烦恼。 It would be so neat to have! 拥有它真是太好了!

If all you need is to store the columns 1, 4 and 6 into myArray2 , give this a try... 如果您只需要将第1、4和6列存储到myArray2 ,请尝试一下...

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)

Arrays are not very flexible: in particular not easy to resize (though you can do so using Redim Preserve . 数组不是很灵活:特别是不容易调整大小(尽管您可以使用Redim Preserve来调整大小)。

Personally I would use a Collection if you want a variable number of items and or want to filter items in VBA. 就个人而言,如果您想要可变数量的项目,或者想要在VBA中过滤项目,我会使用Collection。

First define a Class Module with properties or fields that represent the columns of your 2D array. 首先定义一个具有表示2D数组列的属性或字段的类模块。 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: 然后,您可以创建一个Collection并将类的实例添加到它,如下所示:

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, eg: 然后,您可以进一步过滤它,例如:

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: 最后将其复制回2D数组,以便可以将其写回到Excel工作表:

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. 您甚至可以编写类模块,它是MyClass对象的强类型集合 ,如链接的博客文章中所述,是类模块MyClassCollection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM