我对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