Excel VBA ByRef Function Argument
ByRef in VBA is a function called as by reference where we provide a reference to any arguments in our code. When we make custom functions and want to use the value of any variable defined earlier before the function, we use the ByRef function. The syntax is simple as Function-Name(ByRef Variable as Data Type).
Using ByRef, we can point to the original variable value without altering the variable value. It is like passing the variable value directly to the VBA subprocedureSUB in VBA is a procedure which contains all the code which automatically gives the statement of end sub and the middle portion is used for coding. Sub statement can be both public and private and the name of the subprocedure is mandatory in VBA.read more or VBA functionVBA functions serve the primary purpose to carry out specific calculations and to return a value. Therefore, in VBA, we use syntax to specify the parameters and data type while defining the function. Such functions are called user-defined functions.read more.
Table of contents
- Excel VBA ByRef Function Argument
- How to Pass Argument using VBA ByRef Argument?
- Example #1
- Example #2
- Recommended Articles
- How to Pass Argument using VBA ByRef Argument?
You are free to use this image on your website, templates, etc, Please provide us with an attribution linkArticle Link to be Hyperlinked
For eg:
Source: VBA ByRef (wallstreetmojo.com)
How to Pass Argument using VBA ByRef Argument?
You can download this VBA ByRef Excel Template here – VBA ByRef Excel Template
Example #1
Look at the VBA codeVBA code refers to a set of instructions written by the user in the Visual Basic Applications programming language on a Visual Basic Editor (VBE) to perform a specific task.read more below.
Code1:
Sub Procedure1() Dim k As Integer k = 50 Procedure2 k MsgBox k End Sub
Code2:
Sub Procedure2(ByRef k As Integer) k = k + 10 End Sub
In the first procedure, we have declared the variable “k” as “Integer.”
Then we have assigned the value to this variable as 50.
After that, we added a new line i.e.
Procedure2 k
It is the second procedure name. In this procedure, we have declared the variable within the parenthesis as String in VBAString functions in VBA do not replace the string; instead, this function creates a new string. There are numerous string functions in VBA, all of which are classified as string or text functions.read more, but we have used the word “ByRef.”
ByRef k As Integer
Here I have assigned the value of the variable “k” as
k = k + 10
We will run the code step by step by pressing the F8 key.
Press the F8 key two more times and place a cursor on variable “k” to see the value of the variable “k.”
Since we have assigned the value as 50, it shows the value as 50. Now, it has highlighted the line Procedure2 k, which is the second procedure name.
If we press the F8 key now, it will jump out of the current procedure and go to the second procedure.
Since we used the ByRef word, it carried the variable “k” value from the above procedure.
Press the F8 key twice. It will go back to the previous subprocedure. If you notice, in the second procedure, we have applied the formula as k = k + 10. i.e., the “k” value is 50, then adds 10 more to that, i.e., 60 in total.
Now, the code is running in the first procedure, and in this procedure, the variable “k” value is 50. But press the F8 key and see the result in a message box.
We got the result of 60 instead of the default value of 50 in this procedure.
We got 60 because, in the second procedure, we applied “ByRef, “so it carried the equation result (k = k + 10) to the current procedure.
Here, the first variable “k” value is 50, and in the second procedure, the variable “k” value is k + 10, i.e., 60, carried to the first procedure.
In the first procedure the original value of the variable “k” was 50, so By Ref has changed the original value from 50 to 60 by executing the equation k = k + 10 i.e., k = 50 +10 = 60.
Example #2
Take a look at one more example.
Code 1:
Sub P1() Dim MyNumber As Long MyNumber = 1 Call Change_ByRef(MyNumber) ' MyNumber is changed by the Change_ByRef procedure MsgBox "My Number is now: " & MyNumber End Sub
Code 2:
Sub Change_ByRef(ByRef NewNumber As Long) NewNumber = 14 End Sub
It works the same as the previous code.
Initially, the value of the variable “MyNumber” is 1. Then we call the procedure below by its name.
Call Change_ByRef(MyNumber)
In that procedure, the value of the variable is 14.
So, when it returns to the previous procedure, it will assign the new value to the variable as 14.
Recommended Articles
This article has been a guide to VBA ByRef. Here, we discuss passing an argument using the VBA ByRef function, examples, and a downloadable Excel template. You can learn more about VBA from the following articles: –
- VBA Exit Sub
- Excel VBA Operators
- Integer Data Type in VBA
- VBA Loop
Вступление
Модификаторы ByRef
и ByVal
являются частью сигнатуры процедуры и указывают, как передается аргумент процедуре. В VBA параметр передается ByRef
если не указано иное (т.е. ByRef
неявно, если отсутствует).
Примечание. Во многих других языках программирования (включая VB.NET) параметры неявно передаются по значению, если не указан модификатор: подумайте о том, чтобы указать модификаторы ByRef
явно, чтобы избежать возможной путаницы.
замечания
Передача массивов
Массивы должны передаваться по ссылке. Этот код компилируется, но вызывает ошибку времени выполнения 424 «Object Required»:
Public Sub Test()
DoSomething Array(1, 2, 3)
End Sub
Private Sub DoSomething(ByVal foo As Variant)
foo.Add 42
End Sub
Этот код не компилируется:
Private Sub DoSomething(ByVal foo() As Variant) 'ByVal is illegal for arrays
foo.Add 42
End Sub
Передача ByRef
или ByVal
указывает, ByVal
ли фактическое значение аргумента CalledProcedure
CallingProcedure
, или же ссылка (называемая указателем на некоторых других языках) передается CalledProcedure
.
Если аргумент передан ByRef
, адрес памяти аргумента передается в CalledProcedure
и любая модификация этого параметра CalledProcedure
выполняется в значение CallingProcedure
.
Если аргумент передается ByVal
, фактическое значение, а не ссылка на переменную, передается в CalledProcedure
.
Простой пример будет ясно иллюстрировать это:
Sub CalledProcedure(ByRef X As Long, ByVal Y As Long)
X = 321
Y = 654
End Sub
Sub CallingProcedure()
Dim A As Long
Dim B As Long
A = 123
B = 456
Debug.Print "BEFORE CALL => A: " & CStr(A), "B: " & CStr(B)
''Result : BEFORE CALL => A: 123 B: 456
CalledProcedure X:=A, Y:=B
Debug.Print "AFTER CALL = A: " & CStr(A), "B: " & CStr(B)
''Result : AFTER CALL => A: 321 B: 456
End Sub
Другой пример:
Sub Main()
Dim IntVarByVal As Integer
Dim IntVarByRef As Integer
IntVarByVal = 5
IntVarByRef = 10
SubChangeArguments IntVarByVal, IntVarByRef '5 goes in as a "copy". 10 goes in as a reference
Debug.Print "IntVarByVal: " & IntVarByVal 'prints 5 (no change made by SubChangeArguments)
Debug.Print "IntVarByRef: " & IntVarByRef 'prints 99 (the variable was changed in SubChangeArguments)
End Sub
Sub SubChangeArguments(ByVal ParameterByVal As Integer, ByRef ParameterByRef As Integer)
ParameterByVal = ParameterByVal + 2 ' 5 + 2 = 7 (changed only inside this Sub)
ParameterByRef = ParameterByRef + 89 ' 10 + 89 = 99 (changes the IntVarByRef itself - in the Main Sub)
End Sub
ByRef
Модификатор по умолчанию
Если для параметра не указан модификатор, этот параметр неявно передается по ссылке.
Public Sub DoSomething1(foo As Long)
End Sub
Public Sub DoSomething2(ByRef foo As Long)
End Sub
Параметр foo
передается ByRef
как в DoSomething1
и DoSomething2
.
Осторожно! Если вы приходите в VBA с опытом работы на других языках, это, скорее всего, совершенно противоположное поведение с тем, к которому вы привыкли. Во многих других языках программирования (включая VB.NET) неявный / по умолчанию модификатор передает параметры по значению.
Передача по ссылке
-
Когда значение передается
ByRef
, процедура получает ссылку на значение.Public Sub Test() Dim foo As Long foo = 42 DoSomething foo Debug.Print foo End Sub Private Sub DoSomething(ByRef foo As Long) foo = foo * 2 End Sub
Вызов вышеуказанных выходов
Test
процедуры 84.DoSomething
присваиваетсяfoo
и получает ссылку на значение, и поэтому работает с тем же адресом памяти, что и вызывающий. -
Когда ссылка передается
ByRef
, процедура получает ссылку на указатель.Public Sub Test() Dim foo As Collection Set foo = New Collection DoSomething foo Debug.Print foo.Count End Sub Private Sub DoSomething(ByRef foo As Collection) foo.Add 42 Set foo = Nothing End Sub
Вышеприведенный код повышает ошибку 91 во время выполнения , поскольку вызывающий абонент вызывает член
Count
объекта, который больше не существует, посколькуDoSomething
получил ссылку на указатель объекта и назначил егоNothing
перед возвратом.
Принуждение ByVal на сайте вызова
Используя круглые скобки на сайте вызова, вы можете переопределить ByRef
и принудительно передать аргумент ByVal
:
Public Sub Test()
Dim foo As Long
foo = 42
DoSomething (foo)
Debug.Print foo
End Sub
Private Sub DoSomething(ByRef foo As Long)
foo = foo * 2
End Sub
Вышеуказанные выходы кода 42, независимо от того, указан ли ByRef
неявно или явно.
Осторожно! Из-за этого, используя посторонние круглые скобки в процедурных вызовах, можно легко ввести ошибки. Обратите внимание на пробелы между именем процедуры и списком аргументов:
bar = DoSomething(foo) 'function call, no whitespace; parens are part of args list DoSomething (foo) 'procedure call, notice whitespace; parens are NOT part of args list DoSomething foo 'procedure call does not force the foo parameter to be ByVal
ByVal
Передача по значению
-
Когда значение передается
ByVal
, процедура получает копию значения.Public Sub Test() Dim foo As Long foo = 42 DoSomething foo Debug.Print foo End Sub Private Sub DoSomething(ByVal foo As Long) foo = foo * 2 End Sub
Вызов вышеуказанных выходов
Test
процедуры 42.DoSomething
присваиваетсяfoo
и получает копию значения. Копия умножается на 2, а затем отменяется, когда процедура завершается; копия вызывающего абонента никогда не изменялась. -
Когда ссылка передается
ByVal
, процедура получает копию указателя.Public Sub Test() Dim foo As Collection Set foo = New Collection DoSomething foo Debug.Print foo.Count End Sub Private Sub DoSomething(ByVal foo As Collection) foo.Add 42 Set foo = Nothing End Sub
Вызов вышеуказанных результатов
Test
процедуры 1.DoSomething
предоставляетсяfoo
и получает копию указателя на объектCollection
. Поскольку переменная объектаfoo
в областиTest
указывает на один и тот же объект, добавление элемента вDoSomething
добавляет элемент к одному и тому же объекту. Поскольку это копия указателя, установка ссылки наNothing
не влияет на собственную копию вызывающего абонента.
What is ByRef in VBA?
Byref in VBA stands for “By Reference”. With the help of VBA Byref, we can target the original value without changing the value stored in variables. In other words, we will directly be passing the value to Sub procedures instead of going through the regular methods of defining and assigning the values to variables.
In VBA ByRef, we define the sub-procedure after we set the rule for ByRef. This could be done below the sub-procedure where we want to write the code. In ByRef, we redefine the variable which is used in Sub procedure. And it only works properly when we call the ByRef condition in our subprocedure.
How to Use the ByRef Function in Excel VBA?
Below are the different examples to use ByRef Function in Excel using VBA Code.
You can download this VBA ByRef Excel Template here – VBA ByRef Excel Template
Excel VBA ByRef – Example #1
First, let us learn how to insert a ByRef in VBA, for this follow the below steps. In this example, we will see how to use VBA ByRef for a simple mathematical subtraction work. For this, we would need a module.
Step 1: So, go to VBA and open a module from the Insert menu option as shown below.
Step 2: In the newly opened module, write the subcategory of VBA ByRef as shown below.
Code:
Sub VBA_ByRef1() End Sub
Step 3: Now define a variable let’s say it is an A as Integer.
Code:
Sub VBA_ByRef1() Dim A As Integer End Sub
Step 4: Give any number to variable A. Let that number be 1000.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 End Sub
Step 5: To print the value stored in variable A, we would use Msgbox.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 MsgBox A End Sub
Step 6: Now we compile and run this code by clicking on the Play button as shown below. We will get a message box with the value stored in variable A as 1000.
Now apply VBA ByRef, create another sub-category below the first one and assign the defined variable from the first subcategory with ByRef.
Step 7: By this, we will allow the second subcategory to use the values stored in variable A.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 MsgBox A End Sub Sub VBA_ByRef2(ByRef A As Integer) End Sub
Step 8: Now call the variable A here again and subtract any value from variable A, to get the output value in the same variable. Let’s subtract 100 from the value of variable A so that we would get a measurable number.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 MsgBox A End Sub Sub VBA_ByRef2(ByRef A As Integer) A = A - 100 End Sub
Step 9: Now if we compile each step of the code, we will notice that when the cursor reached variable A, we will see it has only 0 stored in it.
Step 10: When the cursor reached End Sub, the output we will get as 1000 in the message box.
Step 11: It is because we haven’t assigned the ByRef to the first subcategory. Now we will assign subcategory name before the message box function of the first subcategory and see what will happen.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 VBA_ByRef2 A MsgBox A End Sub Sub VBA_ByRef2(ByRef A As Integer) A = A - 100 End Sub
Step 12: And now, run the complete code again. We will see, the second value which is stored in variable A as 100 got subtracted from the first value 1000. As a result, we got the output message as 900.
Step 13: This is the main advantage of using ByRef. We don’t need to define multiple variables for a single job. Just one variable is enough to perform the whole task in different ways. We can use more than one ByRef in a single module.
To justify, what we have understood, let’s add another ByRef in the same Module.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 VBA_ByRef2 A MsgBox A End Sub Sub VBA_ByRef2(ByRef A As Integer) A = A - 100 End Sub Sub VBA_ByRef3(ByRef A As Integer) End Sub
Step 14: In this subcategory, let’s use multiplication.
Code:
Sub VBA_ByRef1() Dim A As Integer A = 1000 VBA_ByRef2 A MsgBox A End Sub Sub VBA_ByRef2(ByRef A As Integer) A = A - 100 End Sub Sub VBA_ByRef3(ByRef A As Integer) A = A * 2 End Sub
Step 15: Again compile and run the code again. We will see that value obtained from the above steps as 900 is now multiplied by 2 to get 1800 as output.
Excel VBA ByRef – Example #2
In this example, we will see, how ByRef works with other kind of integers.
Step 1: Open a module and write the subcategory as shown below.
Code:
Sub VBA_ByRef4() End Sub
Step 2: Now define a variable A as Double. This will allow us to use decimal values.
Code:
Sub VBA_ByRef4() Dim A As Double End Sub
Step 3: Assign any decimal value to variable A.
Code:
Sub VBA_ByRef4() Dim A As Double A = 1.23 End Sub
Step 4: Now again use the message box to see the value stored in variable A.
Code:
Sub VBA_ByRef4() Dim A As Double A = 1.23 MsgBox A End Sub
Now if we run the code, we would get 1.23 as output.
Step 5: In a different manner, we will use Function to define ByRef as Double with variable A.
Code:
Sub VBA_ByRef4() Dim A As Double A = 1.23 MsgBox A End Sub Function AddTwo(ByRef A As Double) As Double End Function
Step 6: Now add any number to variable A. Let’s say it is 10.
Code:
Sub VBA_ByRef4() Dim A As Double A = 1.23 MsgBox A End Sub Function AddTwo(ByRef A As Double) As Double A = A + 10 End Function
Step 7: And again use this defined ByRef function in the first subcategory. Here we will be seeing two message box, one for variable A and other for ByRef.
Code:
Sub VBA_ByRef4() Dim A As Double A = 1.23 MsgBox AddTwo(A) MsgBox A End Sub Function AddTwo(ByRef A As Double) As Double A = A + 10 End Function
Step 8: Same would be reflected in the message box as well.
Step 9: And in the next run it will give the added value of 10 into the original variable value of 1.23 as shown below.
This is how VBA Byref takes the reference of the value defined once and then populate the output as per the new condition.
Pros and Cons of VBA ByRef
- When writing big codes, it saves a lot of time by considering the already defined variable, so that its value can be used again and again.
- We don’t have to define many variables as per formula we want to apply.
- We can apply many ByRef conditions in a single module without even disturbing the process.
- We cannot use VBA Byref in complex code structure.
Things to Remember
- When considering more than one ByRef conditions, the output will be based on the last sub procedure ByRef we defined, but it also considers all the ByRef conditions used previously.
- Final output will have sequential processed output. Not only the latest one.
- This process cannot be done by recording the macro.
- We can see the value stored in each stage of the variable by compiling the code.
- Once done, save the excel file as Macro Enabled excel format, so that we will not lose code in future.
Recommended Articles
This is a guide to VBA ByRef. Here we discuss how to use ByRef function in Excel using VBA code along with practical examples and downloadable excel template. You may also look at the following articles to learn more –
- VBA UBound
- VBA Get Cell Value
- VBA XML
- VBA IsError
You can pass arguments to a procedure (function or sub) by reference or by value. By default, Excel VBA passes arguments by reference. As always, we will use an easy example to make things more clear.
Place a command button on your worksheet and add the following code lines:
Dim x As Integer
x = 10
MsgBox Triple(x)
MsgBox x
The code calls the function Triple. It’s the result of the second MsgBox we are interested in. Functions need to be placed into a module.
1. Open the Visual Basic Editor and click Insert, Module.
2. Add the following code lines:
Function Triple(ByRef x As Integer) As Integer
x = x * 3
Triple = x
End Function
Result when you click the command button on the sheet:
3. Replace ByRef with ByVal.
Function Triple(ByVal x As Integer) As Integer
x = x * 3
Triple = x
End Function
Result when you click the command button on the sheet:
Explanation: When passing arguments by reference we are referencing the original value. The value of x (the original value) is changed in the function. As a result the second MsgBox displays a value of 30. When passing arguments by value we are passing a copy to the function. The original value is not changed. As a result the second MsgBox displays a value of 10 (the original value).