最近在VBA的工作中挣扎了一段时间,真是感觉确实没有做Java爽快。或许是我使用不熟的缘故吧,好多需求没法使用现成的函数去实现,这点在Java里做的就比较好。举个简单的例子,数组去重。这点Java里的set就实现了这个功能,set里是没有重复数值的。可以遍历一下放进set取出后就是唯一的数据了。然而在VBA里面我并没有搜索到类似的函数。
为此费劲脑汁写个类似的功能函数,它类似于SQL里面的distinct。原理如下:
遍历数组的时候,在第三层循环里去查询当前值前面的所有值有没有重复项,有重复项就忽略当前值,没有重复项就使用当前值,你可以去存储,去调用都可以。
下面是一段类似代码,表现这个去重过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Public Function SumNum(ByVal rt As Integer, ByVal i As Integer) As Integer 'i为上一层循环的index,此段代码是同级某一列相同主键的某列不同值的个数,这句话确实有些绕口。 Dim z As Integer Dim total As Integer total = 1 For z = 0 To N - 1 'N-1为数据的长度 If Sheet2.Range("B" & Result(z)).Value = Sheet2.Range("B" & rt).Value Then Dim tmp As Integer For tmp = i + 1 To z If Sheet2.Range("Y" & Result(tmp)).Value <> Sheet2.Range("Y" & Result(z)).Value Then total = total + 1 Else End If Next Else End If Next SumNum = total 'MsgBox total End Function |
上面代码存在一个非常严重的Bug,就是统计结果会不正确,往往数值会比正常的多。因为它每次比对都回增加,这造成了统计的冗余值。接下来是修改后的Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Public Function SumNum(ByVal rt As Integer, ByVal i As Integer) As Integer Dim z As Integer Dim total As Integer total = 1 Dim flag As Boolean flag = True For z = 0 To N - 1 If Sheet2.Range("B" & Result(z)).Value = Sheet2.Range("B" & rt).Value Then '这个IF依据不同情况可增减,目的是对目标数据进行数据筛选 Dim tmp As Integer For tmp = i + 1 To z If Sheet2.Range("Y" & Result(tmp)).Value <> Sheet2.Range("Y" & Result(z)).Value Then flag = False Else End If Next If flag = False Then total = total + 1 End If Else End If Next SumNum = total 'MsgBox total End Function |
上面加入Flag进行先判断,判断结束后在进行逻辑加法运算。这样统计结果就不会错了。肯定是数组内不一样值得总个数了。
其实还是有其他方法的,并且更简单。
例如用Set Keydict = CreateObject(“Scripting.Dictionary”)
Keydict.Add
Keydict.exists来判断是否存在重复值。
其实还是有其他方法的,并且更简单。
例如用Set Keydict = CreateObject(“Scripting.Dictionary”)
Keydict.Add
Keydict.exists来判断是否存在重复值。