检查数组中是否存在值

时间:2015-12-26 05:34:55

标签: arrays vba

我修改了找到的VBA代码 checking if value present in array代码如下。用户将选择一个字段名称,我希望代码找到列出该字段的列,并创建该列中所有项目的数组,但我希望每个非空值在数组中只显示一次。我不想要任何重复。

例如,如果列具有值A,B,A,C,D,我希望代码将数组返回为A,B,C,D。

我得到运行时错误13 - 在代码的这一行输入不匹配:

If cell.Value <> "" And IsError(WorksheetFunction.Match(cell.Value, MyArray, 0)) Then

我很困惑,因为看起来我的所有数据类型都是正确的。任何人都可以提供任何帮助吗?

Sub ChangeBlock()

Dim MyArray() As String
Dim cell As Range
Dim ColNum As Integer
Dim i As Integer

If Not Intersect(ActiveCell, Range("Block1")) Is Nothing Then
    If ActiveCell.Value = "" Then Exit Sub

ColNum = WorksheetFunction.Match(ActiveCell.Value, Sheets("Budget Table").Range("A1:AG1"), 0)

    For Each cell In Sheets("Budget Table").Columns(ColNum)
        If cell.Value <> "" And IsError(WorksheetFunction.Match(cell.Value, MyArray, 0)) Then
            ReDim Preserve MyArray(i)
            MyArray(i) = cell.Value
            i = i + 1
        End If
    Next
End If

MsgBox (MyArray)

End Sub

2 个答案:

答案 0 :(得分:2)

要使用IsError,请使用Application.Match代替WorksheetFunction.Match

尽管这两种方法相似,但它们处理错误的方式略有不同。前者返回一个错误变体,您可以使用IsError进行测试,而后者只是throws一个错误,您只能通过错误处理机制来捕获。

最后,如果您的数据很大,这不是检查重复数据的最佳方式;你应该考虑使用Dictionary

答案 1 :(得分:1)

错误13类型不匹配是由此引起的:

cell.Value <> ""

这里的Value是二维数组(如1到1048576,1到1),并且无法将此数组与字符串进行比较,因此类型不匹配。

编辑:

实际上,变量cell 是一列,因此为了正确比较,有必要说明比较哪个数组元素,例如对于第一个元素:

cell.Value()(1, 1) = ""

更正确的是将变量cell重命名为例如oneColumn因为变量cell实际上包含对列的引用,例如像这样:

Dim myColumns As Range
Set myColumns = Sheets("Budget Table").Columns(ColNum)

Dim oneColumn As Range

For Each oneColumn In myColumns
    ' ...
Next oneColumn

注意:此处for-each没有意义,因为myColumns仅引用一列而myColumns.Columns.Count返回1。所以你想要的只是myColumns.Cells,它返回列的所有单元格。

oneColumn的值是2D数组,说实话,我不知道为什么它是2D而不仅仅是1D。当您检查例如ValueRange("A1:C3")然后你看到它返回2D数组,这是可以理解的。但是为什么一列的列也会返回2D?对我来说似乎也很奇怪:)。 1D阵列的示例是Dim oneDArray: oneDArray = Array("A", "B", "C")。据我所知,1D-array永远不会从Range.Value属性返回。 Here有趣的文章介绍了VBA中的数组维度。

但这不是必需的,因为每个Range都有一个属性Cells。所以这里应该使用Columns(ColNum).Cells

完整的代码看起来像下面这样但有点太复杂了。首先,数组有很多空元素,因为使用了整个列,然后考虑使用像@ A.S.H这样的字典提出的解决方案。 HTH

Dim MyArray() As String
Dim cell As Range
Dim ColNum As Integer
Dim i As Integer

ReDim MyArray(0 To 0)

With Sheets("Budget Table")

    If Intersect(ActiveCell, .Range("Block1")) Is Nothing Then _
        Exit Sub

    If ActiveCell.Value = "" Then _
        Exit Sub

    ColNum = Application.Match(ActiveCell.Value, .Range("A1:AG1"), 0)

    For Each cell In .Columns(ColNum).Cells
        If cell.Value = "" Then _
            GoTo continue

        If IsError(Application.Match(cell.Value, MyArray, 0)) Then
            If i > 0 Then
                ReDim Preserve MyArray(i)
            End If

            MyArray(i) = cell.Value
            i = i + 1

        End If
continue:
    Next cell

End With