传递对象时 byval vs byref

byval vs byref when passing object

我想检查是否存在具有特定名称的工作表,所以我在下面生成了 shtexist 函数。 但是,对于 shtexist 中的第二个参数。当我首先通过 byref 传递它时, shtexist(name,thisworkbook) 运行良好,而 shtexist(name,rwb) 则没有,它显示 byref 错误。 然后我通过它 byval,问题解决了。 我的问题是为什么 byref/byval 在这种情况下很重要?

Sub update_Click()
Dim updatelist
Dim relname, salname, insname, sname As String
Dim rwb, swb, iwb As Workbook
Dim year, month As Integer
updatelist = ThisWorkbook.Sheets("FrontPage").Range("u2", Range("u2").End(xlDown))
relname = Dir(ThisWorkbook.Path & "/" & "*关系表*.xls?")
Set rwb = Workbooks.Open(ThisWorkbook.Path & "/" & relname)
MsgBox (VarType(ThisWorkbook))
For Each i In updatelist
    sname = CStr(i)
    year = CInt(Left(sname, InStr(sname, ".") - 1))
    month = CInt(Mid(sname, InStr(sname, ".") + 1, 2))
    MsgBox (year & " " & month)
    If shtexist(sname, rwb) Then
        MsgBox ("yes")
    Else
        MsgBox ("no")
    End If
Next

End Sub

Function shtexist(name As String, Optional ByVal wb As Workbook) As Boolean
Dim sht As Worksheet
If wb Is Nothing Then
    Set wb = ThisWorkbook
End If
On Error Resume Next
    Set sht = wb.Sheets(name)
On Error GoTo 0
If sht Is Nothing Then
    shtexist = False
Else
    shtexist = True
End If
End Function

http://www.cpearson.com/excel/byrefbyval.aspx 解释传递对象时的 ByRefByVal。但是,如果您传递 ThisWorkbookrwb (只要它被分配给某物) ByVal/ByRef 应该没有任何区别 - 在任何一种情况下都没有分配给 wbshtexist 里面,所以应该没有 side-effects 两种方式。

问题可能出在您的 rwb 声明(作为 Variant,因为每个变量都需要一个类型;您不只是将类型添加到行中的最后一个)

Dim rwb As Workbook, swb As Workbook, iwb As Workbook

在 VBA 中声明变量:https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/declaring-variables#:~:text=You%20can%20declare%20several%20variables%20in%20one%20statement.%20To%20specify%20a%20data%20type%2C%20you%20must%20include%20the%20data%20type%20for%20each%20variable.