使用 Excel 和 VBA,我想要一些关于如何严格使用 VBA 最好地过滤数组中的数据(与使用数据透视表的方式相同)的建议。我正在创建一个用户窗体,它将根据当前现有的数据做出一些数据决策。我可以想象如何做得足够好,但我不太精通 VBA 编程。
这是一个例子
A B C
bob 12 Small
sam 16 Large
sally 1346 Large
sam 13 Small
sally 65 Medium
bob 1 Medium
要获取数组中的数据,我可以使用
Dim my_array As Variant
my_array = Range("A1").CurrentRegion
现在,我熟悉了循环遍历 2D 数组,但我想知道:过滤 2D 数组数据的最有效方法是什么(无需一次又一次循环遍历数组)?
例如,我如何获取就是说获取这种数据:
data_for_sally As Variant 'rows with sally as name in ColA
data_for_sally_less_than_ten As Variant ' all rows with sally's name in ColA and colB < 10
data_for_all_mediums as Variant ' all rows where ColC is Medium
建议?我可以用一堆自定义函数和循环来解决这个问题,但我认为一定有更好的方法。谢谢。
最佳答案
我假设您只想使用 VBA。
我认为这取决于几个参数,主要是:
- 您运行相同条件的频率 => 您会存储过滤器的结果还是每次都重新计算?
- 您需要多久过滤一次内容 => 如果经常,则值得拥有适当的代码结构,如果不是,那么一次性循环显然是最佳选择。
从面向对象的角度来看,假设性能(速度和内存)不是问题,我会采用以下设计(我不会详细介绍实现的细节,只给出总体思路)。创建一个可以像这样使用的类(我们想象中将其称为 ArrayFilter)。
设置过滤器
Dim filter As New ArrayFilter
With filter
.name = "sam"
.category = "Medium"
.maxValue = 10
End With
或者
filter.add(1, "sam") 'column 1
filter.add(3, "Medium") 'column 3
filter.addMax(2, 10) 'column 2
创建过滤后的数据集
filteredArray = getFilteredArray(originalArray, filter)
getFilteredArray 的编写相当简单:循环遍历数组,检查值是否与过滤器匹配,并将有效行放入新数组中:
If filter.isValidLine(originalArray, lineNumber) Then 'append to new array
优点
- 简洁的设计
- 可重复使用,尤其是在使用列号的第二个版本中。这确实可以用来过滤任何数组。
- 过滤代码位于一个可以测试的函数中
- 推论:避免重复代码
缺点
- 每次都会重新计算过滤,即使您使用同一过滤器两次也是如此。例如,您可以将结果存储在字典中 - 见下文。
- 内存:每次调用 getFilteredArray 都会创建一个新数组,但不确定如何避免这种情况
- 这会增加相当多的代码行,因此只有当它有助于使代码更易于阅读/维护时我才会这样做。
ps:如果需要缓存结果以提高性能,一种方法是将结果存储在字典中,并向 getFilteredArray 函数添加一些逻辑。请注意,除非您的数组非常大和/或您经常运行相同的过滤器,否则这可能不值得。
filters.add filter, filteredArray 'filters is a dictionary
这样,当你下次调用 getFilteredArray 时,你可以这样做:
For each f in filters
'Check if all conditions in f and newFilter are the same
'If they are:
getFilteredArray = filters(f)
Exit Function
Next
'Not found in cache: compute the result
关于arrays - 在 Excel VBA 中过滤二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10450645/