Excel UDF返回True但不是False?

时间:2011-11-14 18:13:09

标签: excel vba excel-vba

我试图将工作表函数的组合保存为UDF,因为我倾向于忘记它的确切方式。我使用这个组合来比较列表:

=IF(ISNA(MATCH([value], [range], [match_type])),False,True) 

但是在我尝试修改一个简单的两行宏时遇到了一些问题。似乎我写的模仿工作表组合的VBA代码将返回true,但不是假的。相反,对于不在给定范围内的值,它返回#value!错误。据我所知,这是数据类型不匹配的操作,但我不明白为什么。

作为旁注,上述工作表组合中的IF用于反转ISNA功能的输出。如果您的搜索返回false以获得肯定结果,则会有点混乱。

如果您有更好的方式让我知道,感谢您的帮助。这是我的代码。

Public Function CompareLists(variable As Variant, list As Range, match_type As String)  As Boolean

    If Application.WorksheetFunction.IsNA(Application.WorksheetFunction.Match(variable,     list, match_type)) = False Then

    CompareLists = True

    Else
        CompareLists = False  
    End If

End Function

* * 对于那些要求输入的人来说,它可以是任何东西。我通常使用它来比较数百个事物的id号。它们有时包含字母和数字。

一个例子是试图找到列表1,2,3,4,5,6,7,8中的数字3,其中3在一张纸上,列表在另一张纸上。

2 个答案:

答案 0 :(得分:2)

试试这个版本:

Public Function CompareLists(variable As Variant, list As Range, match_type As Long) As Boolean
    CompareLists = WorksheetFunction.IsNA(Application.Match(variable, list, match_type))
End Function

名称“CompareLists”似乎让我很困惑。更准确的名称是:

Public Function NotInList(variable As Variant, list As Range, match_type As Long) As Boolean
  NotInList = WorksheetFunction.IsNA(Application.Match(variable, list, match_type))
End Function

这使内联更具可读性:

If NotInList(3, Range("A1:A8"), 0) Then
' rest of code

答案 1 :(得分:1)

如果您坚持使用循环(如您的评论中所示),那么我强烈建议您先将范围转储到变量数组。

这是一个带循环的示例函数。请注意,我称之为IsMissing,因为当用户断言某些事情时,感觉更自然,而不是个案(个人偏好)。

Function IsMissing(ByVal search_value As Variant, _
                   ByVal search_range As range) As Boolean

Dim varray As Variant
Dim i As Long, j As Long
Dim found As Boolean

varray = search_range.value

For i = 1 To UBound(varray, 1)
    For j = 1 To UBound(varray, 2)
        If Len(varray(i, j)) <> 0 Then
            If varray(i, j) = search_value Then
                found = True
            End If
        End If
    Next
Next

IsMissing = found

End Function

P.S。这仍然可以优化,但我想保持简单。我确实添加了一个细胞长度检查,所以你不要浪费时间和空白细胞。