IsNumeric的范围版本就像VBA函数HasFormula一样吗?

我知道range().HasFormula只有当范围中的每个单元格都有公式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中的范围对象的数值。

也许all_numeric = (r.Cells.Count - Application.Count(r)) = 0 (其中r是一个Range对象)? – YowE3K 35分钟前

这真的很漂亮 :它利用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运行时工作比findCount方法要困难得多。 你正在使用一个扩展的COM接口 ,所以你没有编译时validation: Application.IDontExist编译得很好,并且出现运行时错误438.和其他任何迟到的成员调用一样, VBE的智能感知不能帮助您的参数:

    没有智能感

  • 前者是一个早期的函数调用,VBA在编译时parsing。 您正在直接使用WorksheetFunction接口,因此VBE会为您提供参数的自动完成智能感知

    自动完成:

    自动完成

    智能感知:

    智能感知

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

缺点是(如果它是一个的话)是后期绑定的Application.SomeFunction东西与Excel4Macros兼容,Excel4Macros是自动化Excel的旧VBA之前的传统方式。 因此,如果不像早期绑定的对象那样引发运行时错误,那么后期绑定的函数将返回错误 ,以便您可以使用IsErrortesting它们,然后才能确定实际获得的types。

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

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