【问题标题】:Excel UDF returns True but not False?Excel UDF 返回 True 但不返回 False?
【发布时间】:2011-11-17 12:42:27
【问题描述】:

我试图将工作表函数的组合保存为 UDF,因为我往往会忘记它是如何进行的。我使用这个组合来比较列表:

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

但是在我尝试纠正一个简单的两行宏时遇到了一点问题。似乎我为模仿工作表组合而编写的 VBA 代码将返回 true 但不会返回 false。相反,对于不在给定范围内的值,它返回#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 在一张纸上,而列表在另一张纸上。

【问题讨论】:

  • 数据输入的例子是什么,比如variable=????,list例子,match_type例子?
  • 我们所说的示例是指提供示例输入、用于函数的示例参数以及这些输入的预期和实际输出的测试用例或演练。

标签: vba excel


【解决方案1】:

试试这个版本:

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

【讨论】:

  • 应该考虑一下而不是使用愚蠢的工作表函数。这是循环很好的确切情况......呃。只是使用了一个带有 if 语句的 for 循环。看看当你尝试使用你的化学学位来编程时会发生什么:P
  • 如果这解决了问题,请单击答案左上角的箭头“接受”。 :)
  • 我的函数对我有用,但如果你想循环,请成为我的客人!
【解决方案2】:

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

这是一个带有循环的示例函数。请注意,我将其称为 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

附:这仍然可以优化,但我想保持简单。不过,我确实添加了对单元格长度的检查,这样您就不会在空白单元格上浪费时间了。

【讨论】:

  • +1 表示函数名称,但在最后一个 If 语句中,“IsMissing = Not found”不是一回事吗?
  • 我的意思是,在你的函数末尾,IsMissing 的值总是与 found 相反。因此,您可以只输入“IsMissing = Not found”而不是 If-Else-End If 语句
  • 你完全正确。我一定是从第一版离开的。我写下代码时的代码 - 谢谢你抓住它:)
猜你喜欢
  • 2012-06-29
  • 2013-02-26
  • 2014-10-21
  • 2018-06-30
  • 2013-02-23
  • 2020-02-12
  • 2011-03-02
  • 2021-07-25
  • 2016-04-16
相关资源
最近更新 更多