在Sub VBA中调用用户定义的函数

时间:2019-03-07 19:33:51

标签: excel vba

我是VBA的新手。我目前正在尝试在用户定义的函数上应用循环。 定义的函数如下。

fetch

我正在尝试在Sub中使用此功能CountColor。但这会引发运行时424错误。

  Function CountColor(InRange As range, ColorIndex As Long, _
    Optional OfText As Boolean = False) As Long
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' CountColor
' This function counts the cells in InRange whose ColorIndex
' is equal to the ColorIndex parameter. The ColorIndex of the
' Font is tested if OfText is True, or the Interior property
' if OfText is omitted or False. If ColorIndex is not a valid
' ColorIndex (1 -> 56, xlColorIndexNone, xlColorIndexAutomatic)
' 0 is returned. If ColorIndex is 0, then xlColorIndexNone is
' used if OfText is Fasle or xlColorIndexAutomatic if OfText
' is True. This allows the caller to use a value of 0 to indicate
' no color for either the Interior or the Font.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Dim R As range
Dim N As Long
Dim CI As Long

If ColorIndex = 0 Then
    If OfText = False Then
        CI = xlColorIndexNone
    Else
        CI = xlColorIndexAutomatic
    End If
Else
    CI = ColorIndex
End If


Application.Volatile True
Select Case ColorIndex
    Case 0, xlColorIndexNone, xlColorIndexAutomatic
        ' OK
    Case Else
        If IsValidColorIndex(ColorIndex) = False Then
            CountColor = 0
            Exit Function
        End If
End Select

For Each R In InRange.Cells
    If OfText = True Then
        If R.Font.ColorIndex = CI Then
            N = N + 1
        End If
    Else
        If R.Interior.ColorIndex = CI Then
            N = N + 1
        End If
    End If
Next R

CountColor = N


End Function

能否请您帮我找出问题所在?任何帮助将不胜感激。 谢谢

2 个答案:

答案 0 :(得分:1)

调用函数的方式多了一个“(”,因此无法获取正确的参数。请尝试以下操作:

CountColor(Range(Cells(i, 4), Cells(i, LastColumn)), 38)

为确保传递期望的参数,请在在线时按 Ctrl + I 。 VBEditor将帮助:

enter image description here

通常,每当使用Range()Cells()对象时,请确保引用其工作表和工作簿to avoid 1004 errors。在该示例的情况下,应如下所示:

With ThisWorkbook.Worksheets(1)
    For i = 2 To LastRow
        TOTALFAILS = CountColor(.Range(.Cells(i, 4), .Cells(i, LastColumn)), 38)
        .Cells(i, LastColumn + 8) = TOTALFAILS
    Next i
End With

答案 1 :(得分:1)

您的CountColor函数期望第一个参数使用Range对象引用,但这不是您要提供的:

TOTALFAILS = CountColor((range(Cells(i, 4), Cells(i, LastColumn))), 38)

第一个参数是该表达式的结果:

(range(Cells(i, 4), Cells(i, LastColumn)))

当您在括号之间放置一个参数时,您传递的是表达式的计算结果,并传递了ByVal(无论函数签名是否指定ByRef。)

那为什么“需要对象”呢?表达式不等于Range对象吗?

Range类具有隐藏的默认成员,您可以在对象浏览器(F2)中显示该成员:

Members of 'Range'

通知隐藏/阴影的_Default成员。

如果您熟悉Collection类,您可能会知道其Item成员是该类的默认成员:

Members of 'Collection'

可以隐式调用默认成员。这样便可以myCollection("someKey")来检索项目,并且它完全等同于myCollection.Item("someKey")

Range.[_Default]成员有点不同,因为它的实现将根据上下文“重定向”到不同的成员:不带参数调用时,它返回Range.Value-对于单单元格范围,那就是单元格的价值。对于多单元格范围,这是一个包含所有值的2D变体数组。

因此,当您将(someRange)作为参数传递时,您隐式传递的是(someRange.[_Default])因为该类具有默认的无参数成员(嗯,这两个参数是可选的,因此无参数调用是合法的。

换句话说,您是将2D变体数组传递给CountColor-而不是Range对象引用。

这就是为什么VBA抛出运行时错误424“需要对象”的原因-因为调用需要一个对象,但是没有提供对象。

As Vityata already answered,删除多余的括号将解决此问题,因为如果没有多余的括号,您将不再强制对ByVal对象/表达式进行Range评估。