允许完整列引用而不会受到惩罚

如果可以将完整列引用作为参数传入,则可以更轻松地在工作表上实现某些 UDF。然而,由于编码的明确性质,涉及这些范围的任何循环可能正在处理完全为空的数十万个单元。这会将你的 VBA 项目(和工作簿)减少到冻结的混乱,同时处理不必要的非值。

循环通过工作表的单元格是完成任务的最慢方法之一,但有时它是不可避免的。将执行的工作削减到实际需要的工作是完美的。

解决方案是使用 Intersect 方法截断 Worksheet.UsedRange 属性的完整列或完整行引用。下面的示例将松散的复制工作表的本地 SUMIF 函数,因此标准范围也将被调整到适合的 sum_range 因为在每个值加总范围必须由一个值陪伴标准范围 ** ** ** **

工作表上使用的 UDF 的 Application.Caller 是它所在的单元格。单元格的 .Parent 属性是工作表。这将用于定义 .UsedRange。

在模块代码表中:

Option Explicit

Function udfMySumIf(rngA As Range, rngB As Range, _
                    Optional crit As Variant = "yes")
    Dim c As Long, ttl As Double
    
    With Application.Caller.Parent
        Set rngA = Intersect(rngA, .UsedRange)
        Set rngB = rngB.Resize(rngA.Rows.Count, rngA.Columns.Count)
    End With
    
    For c = 1 To rngA.Cells.Count
        If IsNumeric(rngA.Cells(c).Value2) Then
            If LCase(rngB(c).Value2) = LCase(crit) Then
                ttl = ttl + rngA.Cells(c).Value2
            End If
        End If
    Next c
    
    udfMySumIf = ttl

End Function

语法:
=udfMySumIf(*sum_range*, *criteria_range*, [*criteria*])

StackOverflow 文档

虽然这是一个相当简单的示例,但它充分展示了传递两个完整的列引用(每个 1,048,576 行),但只处理了 15 行数据和条件。

由 Microsoft™提供的各种方法和属性的官方 MSDN 文档链接。