使用"在"内调用一个函数块?

时间:2018-05-14 01:18:27

标签: vba excel-vba excel

是否可以使用"来调用"中的函数?块?我一直收到错误"无效或不合格的参考"。我怎样才能引用"中的父对象"声明?谢谢!

Sub Test()
    Set wb = Workbooks.Open(“C:\Book1.xls", True, True)

    With wb.Worksheets("Sheet1")
        lRow = LastRow()
        msgbox(lRow)
    End With

    With wb.Worksheets("Sheet2")
        lRow = LastRow()
        msgbox(lRow)
    End With

    wb.Close False
End Sub

Function LastRow()
    LastRow =.Cells.Find(What:="*", _
            After:=Range("A1"), _
            LookAt:=xlPart, _
            LookIn:=xlFormulas, _
            SearchOrder:=xlByRows, _
            SearchDirection:=xlPrevious, _
            MatchCase:=False).Row
End Function

1 个答案:

答案 0 :(得分:6)

With块可以保存对象引用;该对象引用的范围限定为With块所在的过程,出现在With和死亡&隐藏在End WithWith块变量不会突然变为全局/瞬态。编译器具有更多语法代码视图,您要求的内容将需要只能在运行时存在的上下文。

但是,该函数可以从参数中轻松获取该上下文:

'...

With wb.Worksheets("Sheet1")
    lRow = LastRow(.Cells)
    MsgBox lRow
End With

'...

在调用Function(或Property Get)时,避免在VB6 / VBA中使用括号而不将其返回值捕获到局部变量中,或者在调用Sub过程时。这不是编码风格的问题,语法上多余的括号会改变代码的语义,并且不可避免地会导致问题(在编译和运行时)。

我添加了显式访问修饰符和显式返回类型,source参数以及一些验证:

Private Function LastRow(ByVal source As Range) As Long

    Dim result As Range
    Set result = source.Find(What:="*", _
                             After:=source.Range("A1"), _
                             LookAt:=xlPart, _
                             LookIn:=xlFormulas, _
                             SearchOrder:=xlByRows, _
                             SearchDirection:=xlPrevious, _
                             MatchCase:=False)

    If Not result Is Nothing Then
        LastRow = result.Row
    Else
        'source is empty
        LastRow = -1
    End If

End Function

Range.Find在找不到要查找内容时返回Nothing。在这种情况下,如果空source,则.Row会针对Nothing调用,这会在您的代码中引发运行时错误91:您可以从不假设Range.Find将返回有效的对象引用; - )

如果此函数是用标准代码模块(.bas)编写的,After:=Range("A1")也不一定与source.Range("A1")位于同一页上 - 不合格,Range将是隐式引用[_Global].Range,隐藏应用程序范围模块上的公共属性,返回ActiveSheet的引用。在这种情况下,这不是什么大问题,但在其他情况下,使用Excel对象模型中的其他函数,使用一个表来限定方法,并使用另一个表单中的范围进行参数化,可能意味着抛出一个神秘的运行时错误1004。