从 Excel 与 VBA 调用时,VBA UDF 给出不同的答案

Posted

技术标签:

【中文标题】从 Excel 与 VBA 调用时,VBA UDF 给出不同的答案【英文标题】:VBA UDF gives different answer when called from Excel vs VBA 【发布时间】:2013-01-03 15:06:30 【问题描述】:

以下 VBA 函数计算给定范围内包含公式的单元格的数量。从 VBA 子调用时,它可以正常工作。从 Excel 调用时,它返回区域中的单元格总数。

来自 Excel 的调用是 =CountFormulas(A1:C7),即使范围内只有两个带有公式的单元格,它也会返回 21。

造成这种差异的原因是什么?

Public Function CountFormulas(ByRef rng As Range) As Long
    CountFormulas = rng.SpecialCells(xlCellTypeFormulas).Count
End Function

Public Sub CountFormulasFromSub()
    Dim rng As Range
    Dim res As Integer
    Set rng = Sheet1.Range("a1:c7")
    res = CountFormulas(rng)
End Sub

【问题讨论】:

【参考方案1】:

这是不可能的。以下链接包含在 UDF 中不起作用的内容。 这里-http://support.microsoft.com/kb/170787

编辑:手动计数方法虽然有效。

Public Function CountFormulas(rng As Range) As Integer
Dim i As Integer
Dim cell As Range

For Each cell In rng
    If cell.HasFormula Then
        i = i + 1
    End If
Next

CountFormulas = i
End Function

如果您认为它会超过 32767,请将 Integer 更改为 Long

【讨论】:

谢谢,有帮助。我仍然不明白为什么我的方法不起作用,因为我没有在 Excel 中更改任何内容,只是检索信息......另外,你知道如果我将整个工作表发送到我如何避免检查每 17 亿个单元格功能?也就是说,只检查内存中加载的单元格? 如何将工作表发送到 UDF?你能详细说明“只检查内存中加载的单元格吗?”?【参考方案2】:

如果我将 worksheet.cells 发送到函数,它会检查整个工作表中的所有单元格,数量很多而且速度很慢。尽管 Excel 2007+ 支持 16384*1048576 行,但只有实际使用过的单元格才会加载到内存中。无需检查所有其他 170 亿个细胞。我最接近识别这些的是使用 Worksheet.UsedRange 来限制任意范围输入。但是,在使用相距较远的单元格的情况下,它并不完美。例如。如果单元格 A1 和 XFD1048576 包含数据,则整个工作表将包含在 UsedRange 中。任何有关如何将范围限制为实际使用的单元格(上例中只有两个单元格)的提示将不胜感激。

利用 UsedRange 我构建了一个函数,我将分享它以防其他人可以使用它:

Public Function CountIfFormula(ByRef rng As Range, Optional ByVal matchStr As String) As Long
    'Counts the number of cells containing a formula and optionally a specific string (matchStr) in the formula itself.
    Dim i As Long
    Dim isect As Range

    'Restricts the range to used cells (checks only cells in memory)
    Set isect = Application.Intersect(rng, rng.Parent.UsedRange)

    For Each cell In isect
        If cell.HasFormula Then
            If InStr(1, cell.Formula, matchStr) Then i = i + 1
        End If
    Next
    CountIfFormula = i
End Function

函数的使用:

Sub GetNrOfCells()
    Dim i As Long
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        i = i + CountIfFormula(ws.Cells, "=SUM(")
    Next
    'i will now contain the number of cells using the SUM function
End Sub

最好的问候,并感谢您的回复。

佛西

【讨论】:

以上是关于从 Excel 与 VBA 调用时,VBA UDF 给出不同的答案的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA:不满足条件时如何让UDF返回0

自动计算与单元格属性相关的 Excel VBA UDF

Excel VBA UDF 自动完成参数

Excel VBA UDF Count Ifs 与数据转换

如何在 VBA Excel UDF 参数中使用比较运算符?

使用 VBA for Excel 在 UDF 中输入的名称无效