Excel VBA ByVal Function Argument
ByVal is a statement in VBA. ByVal stands for “By Value,” i.e., when the subprocedure calls in from the procedure, the value of the variables is reset to the new value from the new procedure called in.
In VBA, when we work with functions that call in different functions, there are certain circumstances that the value for the original argument is changed when calls the function. The ByVal statement prohibits the procedure or the code from changing the value for the argument.
By reading the explanation, we know it is not easy to understand. But with practical examples of function, we can understand it better.
Table of contents
- Excel VBA ByVal Function Argument
- How to use ByVal Argument in VBA?
- Example #1
- Example #2
- Things to Remember
- Recommended Articles
- How to use ByVal Argument in VBA?
How to use ByVal Argument in VBA?
You can download this VBA ByVal Excel Template here – VBA ByVal Excel Template
Example #1
Look at the VBA codesVBA 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.
Code:
Sub Macro1() Dim k As Integer k = 50 Macro2 k MsgBox k End Sub
Sub Macro2(ByVal k As Integer) k = k + 5 End Sub
The above two macro procedures have a common variable, “k,” across procedures. Let me explain this in detail before we see the result.
In the first Macro, we have assigned the value of 50 to the variable “k.”
Dim k As Integer k = 50
Next, we have called the second macro procedure from the first Macro.
Macro2 k
In Macro2, we have reset the variable’s value to k = k + 5. In this macro, we have used the ByVal argument to assign the value to the variable “k.”
Now, to understand “ByVal,” let’s run the VBA code by pressing the F8 key.
#1 – Upon pressing the F8 key first, it will highlight the first line of the Macro1.
At this point, place a cursor on the variable “k.” It should show the value of the variable “k.”
At the moment, the value of “k” is zero.
#2 – Press the F8 key again, and it will jump to the third line.
Even now, the value of “k” is still zero.
#3 – Press the F8 key now. See the value of the k.
Since the “k” value sets to 50 and the code executes, the value shows as 50.
#4 – The highlighted line is “Macro2 k,” i.e., pressing the F8 key will jump to the second procedure, Macro2.
#5 – Even now, the value of variable “k” in this procedure also shows as 50. But inside this macro, we are resetting the value of the variable “k” as k = k + 5, i.e., 55. So, now press the F8 key two more times.
As you can see above, the “k” value is 55 now.
#6 – Press the F8 key. It will jump back to the Macro1 procedure.
When the macro jumps back to the original procedure Macro1, our variable “k” value is no longer 55 but rather the original value in this procedure, i.e., 50.
When you press the F8 key, we can see only 50 in the message box in VBAVBA MsgBox function is an output function which displays the generalized message provided by the developer. This statement has no arguments and the personalized messages in this function are written under the double quotes while for the values the variable reference is provided.read more.
As we have told at the beginning of the article “ByVal,” the argument does not carry values from one procedure to another even though it carries the variable’s value from the first macro to the second by the moment. It encounters the line “ByVal” when it returns to the original macro. It resets the value to the original value in the procedure only.
Example #2
Now, take a look at the below two macros.
Code:
Sub P1() Dim k As Integer: k = 10 Call P2(k) MsgBox k End Sub
Sub P2(ByVal k As Integer) k = 15 End Sub
- It is similar to the first example. In the macro “P1,” we have assigned the value of 10 to the variable “k,” and in the same macro “P1,” we have called the second macro “P2” with variable “k.”
- In the second macro, “P2,” we have used the ByVal argument. This time, the value of variable “k” is 15.
This macro carries the value of variable “k” as ten from macro “P1” to macro “P2.” So, this macro will reset the value to 15, but the moment it comes back to finish the macro to the first macro, “P1,” the value of “k” back to 10, not 15.
Things to Remember
The ByVal argument does not affect the variable value even after running the macro. Still, we can carry the variable’s value from one macro to the other with the By Ref argument.
Recommended Articles
This article has been a guide to VBA Byval. Here, we discuss using the ByVal argument in VBA along with the examples and downloadable Excel template. You can learn more about VBA from the following articles: –
- VBA ByRef Argument Type Mismatch
- VBA Split String into Array
- Set Range in VBA
- VBA Examples
Excel VBA ByVal
In VBA, we have a statement called ByVal which is used for calling the value from the subprocedure when the main procedure value is down to 0 or in other words when the value is reset. Where ByVal stands for By Value, which means replacing the main value by the value of another subprocedure. Excel VBA ByVal is the reference of linking once sub procedure with others so that we can use the linked sub procedure’s value by calling it using By Val. We can also give the reference of the value using ByRef. ByVal is used when we want to call a value from another sub procedure, but we do not want to change the value of argument whereas ByRef is used when we want to change the value using subprocedure.
VBA ByVal does not have any specific syntax which we need to follow. But the correct position of ByVal in VBA code will definitely make complete sense out of it. The above explanation would be much clear using the example shown below.
How to Use ByVal Statement in VBA Excel?
We will learn how to use a ByVal Statement in Excel by using the VBA Code.
You can download this VBA ByVal Excel Template here – VBA ByVal Excel Template
Example #1
To know the values from other subprocedures, when the main procedure value is down to 0 or in other words when the value is reset. For this, follow the below steps:
Step 1: Insert a new module inside Visual Basic Editor (VBE). Click on Insert tab > select Module.
Step 2: Write the subprocedure in the name of the performed operations or any name.
Code:
Sub VBA_ByVal() End Sub
Step 3: Define a variable as Integer using DIM as shown below.
Code:
Sub VBA_ByVal() Dim A As Integer End Sub
Step 4: Assign a number to defined variable A. We are choosing number 10.
Code:
Sub VBA_ByVal() Dim A As Integer A = 10 End Sub
Step 5: Use the message box to see the value stored in variable A.
Code:
Sub VBA_ByVal() Dim A As Integer A = 10 MsgBox A End Sub
Step 6: Now after that, we will be writing another sub procedure, by that we will be calling another value for the same variable.
Code:
Sub VBA_ByVal() Dim A As Integer A = 10 MsgBox A End Sub Sub Val_Section(ByVal A As Integer) End Sub
Step 7: Then we will use the same variable A and add any number to see the change in value from the main procedure.
Code:
Sub VBA_ByVal() Dim A As Integer A = 10 MsgBox A End Sub Sub Val_Section(ByVal A As Integer) A = A + 12 End Sub
Step 8: Now we will compile the code by pressing the F8 function key. We will see, as the compiler reaches the variable A, hovering the cursor there will reflect the value as 0 which is the initial value.
Step 9: And once the cursor reaches at message box, then the value will be changed to 10 as now code has compiled till that.
Step 10: Now run the code by pressing function key F5 and to run the code, click on the Play button located below the menu bar, the message box will give us the value as 10.
Step 11: Now to call the value from below written sub procedure to the main procedure, use Val_Section which is our 2nd subprocedure name with variable A.
Code:
Sub VBA_ByVal() Dim A As Integer A = 10 MsgBox A Val_Section A End Sub Sub Val_Section(ByVal A As Integer) A = A + 12 End Sub
Step 12: Now if again compile the code using the F8 key and we will notice once the compiler reaches End Sub of 2nd sub procedure, on hovering the cursor there we will see the variable A has now the summed value as 22 adding the number from both the subprocedures.
Example #2
There is another method to call the value from other sub procedure to the main procedure. For this, follow the below steps:
Step 1: For this, we will be using the same first half of the code as shown below.
Code:
Sub VBA_Byval2() Dim A As Integer A = 10 MsgBox A End Sub
Step 2: Now continuing the code, start the subprocedure for ByVal again as Integer.
Code:
Sub VBA_Byval2() Dim A As Integer A = 10 MsgBox A End Sub Sub Val_Section(ByVal A As Integer) End Sub
Step 3: Here we will choose a different value which we want to call in the same variable A as 15.
Code:
Sub VBA_Byval2() Dim A As Integer A = 10 MsgBox A End Sub Sub Val_Section(ByVal A As Integer) A = 15 End Sub
Step 4: Now to call the value mentioned in 2nd sub procedure, we will use word CALL with the name of 2nd sub procedure with variable A as shown below in the first part of the code.
Code:
Sub VBA_Byval2() Dim A As Integer A = 10 MsgBox A Call Val_Section(A) End Sub Sub Val_Section(ByVal A As Integer) A = 15 End Sub
Step 5: Similar to the procedure shown in example-1, compile the code using F8 step by step. We will see, as the compiler compiles the first subprocedure, we will get the message box with number 10 which we have used in variable A.
Continuing the compiling, as we reach at value 15 of variable A from the 2nd sub procedure, then hovering the cursor will reflect the value as 10 which is the same as 1st subprocedure.
And at last when our compiler reaches at End Sub then it will reflect the value as 15 after hovering the cursor, which is now called by using ByVal operation in the first subprocedure. But the message will only reflect the value as 10.
Pros & Cons of VBA ByVal
Below are the pros and cons of VBA ByVal:
- It is very easy to implement the ByVal even using the simple code of storing any number.
- We can pass any number as per the data type used with the limit range.
- VBA ByVal doesn’t reflect the updated or called value from the other sub procedure through the message box. It carries the same value even the message box pops up multiple times.
Things to Remember
- VBA ByVal and ByRef both are used for giving the reference. But the ByRef is only used for giving the reference whereas ByVal is used for calling the values stored in a different subprocedure.
- Hover the cursor at the variable name only to see the current position of value. Even after the compiler passes from there, the updated value will be seen only by hovering the cursor at the exact position.
- VBA ByVal carries the same value there in the first subprocedure once the code is run. And whatever changes happen when we call the value using ByVal, it will again reset to the previous value only.
- Once we are done with writing the code, always remember to save the code in Macro enabled excel format which is used for saving VBA Code.
Recommended Articles
This is a guide to the VBA ByVal. Here we discuss how to use ByVal Statement in excel VBA along with practical examples and downloadable excel template. You can also go through our other suggested articles –
- How to Use VBA Login?
- VBA Month | Examples With Excel Template
- How to Use Create Object Function in VBA Excel?
- How to Use VBA IsError Function?
Using the ByVal argument in VBA is a way to pass values to a function in VBA while retaining the original value of the variable.
For example, you may have a list of names and dates of birth in your Excel sheet, and you wish to loop through this list of names, and calculate the age of each person based on the date of birth of that person. You need to pass the date of birth of each person to a function, and return the correct age of that person.
In Excel VBA, we can write a function that will use the date of birth as a value to calculate the age of the person
Function GetAge(ByVal DOB As Date) As Integer 'use the DOB to calculate the age GetAge = (Now() - DOB) / 365.25 End Function
In the above example, I am sending the date of birth as a date variable to the GetAge Function in Excel. This is then used to calculated the age of the person by using the built-in Now()
function that Excel has (which returns todays date) – and then dividing the number returned by the number of days in a year.
HOT TIP: According to Excel, day 1 is the 1st of January 1900 so the date functionality in Excel is calculated using this – therefore the calculation will work out how many days there are between Now() and the DOB variable – each of these – although shown as a date in Excel, actually represents a number calculating the number of days since the 1st of January 1900.
You then use the function in Excel to calculate the date of birth for the first person in your list.
You can then use the little handle in the bottom right hand corner of your cell to double-click and copy the formula down to the remaining people in the list. The ByVal variable will pick up each individual date of birth and will use that variable to calculate each person’s own date of birth.
You can also use the ByVal variable syntax when you are using VBA forms. For example, you might want to enter information into the forms that will then be used at a later stage in a calculation. Say you want to buy a product –a bar of soap, for example – and the bar of soap is $1.30. Now you want to buy 4 bars or soap, or you want to buy 6 bars of soap – and you want VBA to work out the cost of the transaction – ie the total cost for the bars of soap.
To do this, you need to pass a value to the VBA code in order for the VBA code to do the calculation. Many VBA programs that are written use forms in which the user can type in the information, and then they use the code behind these forms to perform the calculations that are required.
For example, I run a shop and I am selecting a product to sell to my client.
When I click on Calculate, the Price and Quantity of the product will be passed to the event behind the calculate button, and will then in turn be passed to a function to calculate the total price.
The click event of the calculate button:
Private Sub cmdCalculate_Click() Dim dblPrice As Double Dim dblQty As Double 'get the values from the form dblPrice = Me.txtPrice dblQty = Me.txtQty 'pass the values to the CalculatePrice function and return the result MsgBox CalculatePrice(dblPrice, dblQty), vbInformation, "RESULT" End Sub
Which in turn requires the Calculate Price function to return the value
Function CalculatePrice(ByVal dP As Double, ByVal dQ As Double) As Double CalculatePrice = Round(dP * dQ, 2) End Function
When I click on Calculate, the following message box is returned.
I am returning the result in a message box for the purpose of thie overview. However, once you have obtained the price, you could of course return the price to an excel sheet, or use it further on in your code. You could also use the calculate price function directly in an Excel sheet, rather than using an VBA form.
Where B2 is the ByVal dP as double in the function, and C2 is the ByVal dQ as double in the formula – you can then add to your list of products, enter the prices and quantities ordered and the total formula and populate your sheet.
Should the order quantity change for some reason, the Total will automatically update based on the values entered as the function will re-calculate.
A third way of using the ByVal argument is when you are writing quite complicated code which requires you to loop through a list of data, and then return and perhaps update the data based on what is returned from your function. This is more common in VBA when you are programming in Access databases.
For example, you may need to loop through a list of products in your Access table, obtain the Price and Quantity from the table, and then for each record in the table, you need to update the total column in the table.
Say you have this table in Access:
You then need some code to update the price automatically.
NOTE: Yes, we can do this in a query for those of us who use Access and I will show that below, but for the sake of this example, I am going to use code to update a table.
You can then write this code in an Access module:
Sub UpdatePricing() Dim dbs As Database Dim rst As Recordset Dim dblPrice As Double Dim dblQty As Double Set dbs = CurrentDb Set rst = dbs.OpenRecordset("Orders", dbOpenDynaset) With rst .MoveLast .MoveFirst Do Until .EOF = True dblPrice = rst.Fields("ProductPrice") dblQty = rst.Fields("ProductQty") .Edit rst.Fields("TotalPrice") = CalculatePrice(dblPrice, dblQty) .Update .MoveNext Loop End With rst.Close End Sub Function CalculatePrice(ByVal dblP As Double, ByVal dblQ As Double) As Double CalculatePrice = Round(dblP * dblQ, 2) End Function
If you then click in the UpdatePricing
routine, and click Run (F5), the code will open the Orders table, loop through each record, and update the total price accordingly.
As I mentioned in my note, if you have created your table without the total price column, you can then use a query to calculate the total price, and use the CalculatePrice
function to return the same information dynamically into the query.
The result of which would be:
In conclusion, this general overview of the ByVal argument in VBA has just introduced you to the tip of the iceberg in using this very useful variable functionality in VBA – it can be used directly in Excel sheets, in both Excel and Word VBA forms and of course in Access VBA modules and queries. It can be used to store all type of variables (strings, dates, numbers etc) and adds a huge amount of flexibility to your code.