Либо будет работать, но семантически правильный код, предпочитают передать его по значению (ByVal
).
Когда вы передаете переменный объект по значению, вы передаете копию из указателя к объекту.
Так что процедура работы с является тот же объект (т.е. изменено свойство значения будет видно вызывающим), за исключением того, что это не разрешено Set
указатель на что-то другое - ну может, но он сделает это на свою собственную копию, и поэтому вызывающий объект не будет затронут.
Public Sub DoSomething()
Dim target As Worksheet
Set target = ActiveSheet
Debug.Print ObjPtr(target)
DoSomethingElse target
Debug.Print ObjPtr(target)
End Sub
Private Sub DoSomethingElse(ByVal target As Worksheet)
Debug.Print ObjPtr(target)
Set target = Worksheets("Sheet12")
Debug.Print ObjPtr(target)
'in DoSomething, target still refers to the ActiveSheet
End Sub
С другой стороны ...
Public Sub DoSomething()
Dim target As Worksheet
Set target = ActiveSheet
Debug.Print ObjPtr(target)
DoSomethingElse target
Debug.Print ObjPtr(target)
End Sub
Private Sub DoSomethingElse(ByRef target As Worksheet)
Debug.Print ObjPtr(target)
Set target = Worksheets("Sheet12")
Debug.Print ObjPtr(target)
'in DoSomething, target now refers to Worksheets("Sheet12")
End Sub
В общем, параметры должны быть переданы по значению. Это всего лишь неудачная языковая причуда, что ByRef
по умолчанию (исправлено VB.NET).
То же самое верно и для необъектных переменных:
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByVal foo As Long)
foo = 12
'in DoSomething, foo is still 42
End Sub
И ...
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByRef foo As Long)
foo = 12
'in DoSomething, foo is now 12
End Sub
Если переменная передается по ссылке, но никогда не переназначен в теле процедуры , то он может быть передан по значению.
Если переменная передается по ссылке, и переназначает его в теле процедуры, то, что процедура, вероятно, может быть записана в виде Function
, а на самом деле возврата измененное значение вместо этого.
Если переменная передается по значению и переназначается в теле процедуры, то вызывающий объект не увидит изменения - что делает код подозрительным; если процедура должна передать значение в ByVal
параметр, цель кода становится яснее, если она определяет свою собственную локальную переменную и присваивает , что вместо ByVal
параметра:
Public Sub DoSomething()
Dim foo As Long
foo = 42
DoSomethingElse foo
End Sub
Private Sub DoSomethingElse(ByVal foo As Long)
Dim bar As Long
bar = foo
'...
bar = 12
'...
End Sub
Это все фактические код проверки в Rubberduck, как VBE надстройку я принимал активное участие с того, что может анализировать код и увидеть эти вещи:
Параметр передается по значению, но ему присваивается новое значение/ссылка. Подумайте о создании локальной копии вместо этого, если вызывающий абонент не должен знать новое значение. Если вызывающий пользователь должен увидеть новое значение, вместо этого параметр должен быть принят ByRef, и у вас есть ошибка.
http://rubberduckvba.com/Inspections/Details/AssignedByValParameterInspection
Процедура, которая имеет только один параметр, передаваемый по ссылке, который назначается новое значение/ссылка перед процедурой выходов, использует параметр ByRef как возвращаемое значение: рассмотрим возможность сделать это функцией.
http://rubberduckvba.com/Inspections/Details/ProcedureCanBeWrittenAsFunctionInspection
Параметр, который передается по ссылке, и не назначается новое значение/ссылка, может быть передан по значению вместо этого.
http://rubberduckvba.com/Inspections/Details/ParameterCanBeByValInspection
Это случай wsReport
здесь:
это может помочь http://www.windowsdevcenter.com/pub/a/oreilly/windows/ ron/objects.html –