excel事件处理程序中的byval



我对excel的某些事件操纵器中的ByVal关键字有点困惑。

newsheet事件示例(从 Excel 2019用VBA ,Wiley复制(

Private Sub Workbook_NewSheet(ByVal Sh As Object)
    If TypeName(Sh) = "Worksheet" Then
        Sh.Cells.ColumnWidth = 35
        Sh.Range("A1") = "Sheet added " & Now()
    End If
End Sub

此代码如预期的那样起作用,这似乎是微不足道的。但是在某种程度上以为我变得越来越困惑。

基于我的理解,ByVal意味着Sh只是原始工作表对象的副本,而使用ByVal参数的过程不会导致对原始对象的更改。换句话说,代码所做的无效。

仅当引用传递给程序时,他们才能修改这些参考文献引用的对象。

我在那里错过了什么吗?谢谢

P.S。我对通过参考/值传递的大多数理解都来自其他编程语言,例如C#。我不知道的VBA可能有一些特殊性。

由于您传递了一个对象,因此Byval通过参考的副本(值(。参考的副本(值(仍然指向原始引用所指向的内容。因此,您的方法有效并更改原始参考指向的内容。

如果您知道java,这本质上与java相似,在那里可以说"通过价值传递",但是当您将对象作为参数传递时,您实际上在做的是传递参考的副本,而不是引用指向的副本。

byval在那些情况下阻止了原始参考本身中值的变化。

请参阅下一个:

Module Module1
    Sub Main()
        ' Declare an instance of the class and assign a value to its field.
        Dim c1 As New Class1()
        c1.Field = 5
        Console.WriteLine(c1.Field)
        ' Output: 5
        ' ByVal does not prevent changing the value of a field or property.
        ChangeFieldValue(c1)
        Console.WriteLine(c1.Field)
        ' Output: 500
        ' ByVal does prevent changing the value of c1 itself. 
        ChangeClassReference(c1)
        Console.WriteLine(c1.Field)
        ' Output: 500
        Console.ReadKey()
    End Sub
    Public Sub ChangeFieldValue(ByVal cls As Class1)
        cls.Field = 500
    End Sub
    Public Sub ChangeClassReference(ByVal cls As Class1)
        cls = New Class1()
        cls.Field = 1000
    End Sub
    Public Class Class1
        Public Field As Integer
    End Class
End Module

最新更新