是否有像VBA函数HasFormula一样的IsNumeric范围版本?

时间:2017-04-23 01:49:46

标签: excel vba excel-vba

我知道range().HasFormula仅当范围中的每个单元格都有公式时才返回True,否则它可以返回False或Null(混合时)。但是没有像HasNumber这样的功能。因此,要检查范围是否只包含数字,我必须

Dim all_numeric As Boolean
all_numeric = True
For Each cell In Range()
    If (Not IsNumeric(cell)) Or IsEmpty(cell) Then 'I also want to get rid of empty cell
        all_numeric = False
        Exit For
    End If
Next cell

此外,有WorksheetFunction.IsNumber类似的东西,但仍然需要循环范围。 如果范围包含大量数字,我不确定这是否会非常慢。我想知道是否有更好的方法来检查VBA中范围对象的数值。< / p>

1 个答案:

答案 0 :(得分:8)

  

也许all_numeric = (r.Cells.Count - Application.Count(r)) = 0(其中rRange个对象)? - YowE3K 35 mins ago

确实是beautiful:它利用Excel自己的函数返回范围内的数值来确定结果:

  

<强> WorksheetFunction.Count

     

计算包含数字的单元格数量并计算参数列表中的数字。

     

<子> https://msdn.microsoft.com/en-us/library/office/ff840324.aspx

不计算错误单元格和空单元格,这满足了不计算空单元格的要求。

这使我在一个标准模块中公开了一个很好的UDF:

'@Description("Returns True if all cells in specified range have a numeric value.")
Public Function IsAllNumeric(ByVal target As Range) As Boolean
    IsAllNumeric = target.Cells.Count - Application.WorksheetFunction.Count(target) = 0
End Function

请注意,我使用的是Application.WorksheetFunction.Count,而不是Application.Count

  • 后者是一个后期绑定调用,它使VBA运行时工作比查找Count方法更加困难。您正在使用扩展COM接口,因此您没有编译时验证:Application.IDontExist编译完全正常,并且因运行时错误438而爆炸。任何其他后期成员调用,VBE的 IntelliSense 都无法帮助您处理这些参数:

    no intellisense

  • 前者是早期绑定函数调用,VBA在编译时解析。您正在直接使用WorksheetFunction界面,因此VBE为您提供自动完成 IntelliSense 参数。

    自动完成:

    autocomplete

    智能感知:

    intellisense

调用是早期绑定的事实意味着没有运行时开销,因此性能更好 - 即使它最终是完全相同的内部Excel函数执行。

缺点(如果它只是一个)是后期Application.SomeFunction的东西与Excel4Macros兼容,Excel4Macros是旧的传统的VBA前自动化Excel方式。因此,不是引发运行时错误,就像它们早期绑定的对应物一样,后期绑定函数返回错误,这样你可以 使用IsError对其进行测试,然后才能确定您实际获得的类型。

通过早期绑定WorksheetFunction.SomeFunction调用,如果Excel显示的结果为#REF!#VALUE!,或#N/A或其他任何可能的错误值,那么您'对于将错误值视为StringLong或任何其他非错误VBA类型,永远不会遇到类型不匹配运行时错误。相反,您只需处理运行时错误,就像处理任何其他VBA API函数一样。

后期绑定调用将错误值传播到您的代码中;早期绑定的调用提前失败:在读取单元格值的位置和使用假定没有错误值的方式使用该值的位置之间可能有20行代码,并且指令抛出类型不匹配 - 然后您需要调试以追溯到返回错误的函数。使用早期绑定代码,函数本身会抛出错误,因此您无需进行挖掘。