VBScript ByRef ByVal

In VBScript, there are 2 ways to pass arguments: ByVal or ByRef. Using ByVal, a copy of the argument is passed whereas with ByRef, the passed parameter becomes a reference. This is the obvious bit, but, how do these 2 differ in practice?

ByVal

Consider the following code snippet:

Function GetValue( ByVal var )
    var = var + 1
End Function
 
'Pass the variable x to the GetValue function ByVal
Dim x: x = 5
Call GetValue(x)
 
MsgBox "x = " & x

In other words, when we passed the variable x to GetValue, we were simply passing a copy. When GetValue executes, var stores a copy of the variable x and increments itself by 1. Because a copy of x has been passed, it cannot be modified.

ByRef

Consider the following code snippet:

Function GetReference( ByRef var )
    var = var + 1
End Function
 
'Pass the variable x to the GetReference function ByRef
Dim x: x = 5
Call GetReference(x)
 
MsgBox x

Passing Parameter By Reference

Variable x was increment by 1. But why was x incremented instead of only var? When the function GetReference executes, var becomes a reference of x so any changes made to var would also impact x. Another quick example:.

Function GetReference( ByRef arrArray )
    ReDim Preserve arrArray(UBound(arrArray)+1)
    arrArray(UBound(arrArray)) = 2
End Function
 
Dim newArray: newArray = Array(0, 1)
Call GetReference(newArray)

Will the size of newArray increase? Let’s see:

' new size: 2
MsgBox UBound(newArray)
 
' new elements: 0, 1, 2
For x = LBound(newArray) To UBound(newArray)
    MsgBox newArray(x)
Next

Since newArray was passed as a reference to the GetReference function, the change made to arrArray was reflected upon newArray as well. Thus, sizes of both arrays incremented by 1.

Is there a way to pass variables ByRef and still avoid this? Yes, by using temporary variables.

ByRef & Temporary Variables

The advantage of using this approach is that you can pass temporary variables to n number of functions accepting arguments as reference, without having the original variables modified.

Function GetReference( ByRef var )
    var = var + 1
End Function
 
Dim x: x = 5
Dim y: y = x
 
Call GetReference(y)
 
MsgBox x   'Returns 5 (x remains unchanged)
MsgBox y   'Returns 6

Summary

  • (ByVal) Arguments do not change when passed by value.
  • (ByRef) If the function parameter is modified, it will have the same impact on the parameter that was passed by reference.
  • (ByRef) Because the passed parameters can be changed, we can pass multiple values from functions.
  • (ByRef) In a huge function library, it can be hard to tell where the value was changed and what function the variable was supposed to perform.
Subscribe for Relevant Codes newsletter to get awesome updates and articles delivered straight to your inbox.

Leave a Comment

{ 21 comments… add one }

  • Ramaniranjan Das February 15, 2014, 11:11 am

    In case of By ValWhen GetValue executes, var stores a copy of the variable x and increments itself by 1 then why it is not modified

    Reply
  • Megha September 6, 2013, 9:33 am

    How to return more than one value using a single function?

    Reply
  • Navnath Patil January 21, 2013, 10:37 am

    Hi Anshoo,

    How are you?

    I have a question regarding passing *object* as a parameter to a function using both ByRef and ByVal. How does it work in case of objects? Does it work in the same way as variables?(by default ByRef) It would be great if you give me an example of passing an object to the function using both ByRef and ByVal

    Thanks in advance,

    Thanks,
    Navnath Patil.

    Reply
  • Veeranki Naveen January 4, 2013, 2:25 pm

    Hi Anshu,

    The above examples of byref holds true when the Function “Definition” and Function “Call” are in the same Action.
    But when you define the same Function in a function library file and call that function from the main Action then the above example doesn’t fit true. Can you please explain why is it so ?

    For Example :

    I have created a Function “ad” in Function Library as below and also declared the variables p, q globally and I associated the function library “Globally” from Test settings Resource tab:

    FUNCTION LIBRARY

    Dim p , q

    Function ad (byref a , byref b)
    msgbox p
    p = (p+1)
    msgbox a ‘ OUT PUT 3
    c = (a+b)
    a = (a+1)
    msgbox c
    End Function

    Now I assigned the values to variable p and q in the main Action and also called the function “ad” as below .

    ACTION1

    p = 3
    q = 5
    Call (p,q)
    msgbox p

    QUESTION 1 :
    Now when I am incrementig ‘p’ by 1 inside the function it is not reflecting in ‘a’ even though ‘a’ is a reference of ‘p’ but the otherway is happening i.e ‘p’ is reflecting the changes done in ‘a’.

    Can you please explain why is it so ?

    QUESTION 2 :
    What if I declare the variables in an Action rather than declaring them inside a FUNCTION LIBRARY ?

    Please elaborate the same.

    Reply
    • Veeranki Naveen January 5, 2013, 2:53 am

      Beg Pardon QUESTION 1 below is modified, please ignore the below QUESTION 1 and treat this as final.

      QUESTION 1:

      Now when I am incrementig ‘p’ by 1 inside the function it is not reflecting in ‘a’ even though ‘a’ is a reference of ‘p’ also otherway is also not happening i.e ‘p’ is also not reflecting the changes done in ‘a’.

  • arun September 11, 2012, 7:57 am

    thanks for nice article

    Reply
  • rasikraj February 23, 2012, 5:26 am

    the examples u given r great.i got an clear idea about by val & by ref.thank u very much………..

    Reply
  • Kevin Abel November 14, 2010, 7:13 pm

    I did know how QTP and VBScript is supposed to work with ByRef and ByVal. For some unknown reason ByRef did not work either in the default mode or when parameters are specified to be ByRef in the called function. The values going into the funciton calls, but were not returning with the new values.

    At first I thought I may be doing something wrong so I showed my finding to a VB programmer and said I was not making a mistake. I tried it on a second machine with another QTP 10.00 developer and we ran into the same issue.

    The solution was to put a CALL in front of the funciton call. Then the functions did pass by reference. I did see another article on line where the variable did not get sent back to the calling function and they also used the CALL statement. The article was talking about dictionary objects being passed by reference and how the CALL statement made the ByRef work differenty that gave me the idea of trying:
    CALL DoSomething param1
    and it did return the updated value through param1

    I take away the CALL and the ByRef value did not return anything and the value became undefined which is even a step worse than by val because it lost the original value.

    I do not know why the parameters pass on some PCs and not others.

    Thanks,

    Kevin

    Reply
    • Anshoo Arora December 5, 2010, 9:35 pm

      I have a friend who was searching for some information on this topic and landed on this page + read your comments. Thanks for sharing such wonderful information with us, Kevin.

  • Tarun November 4, 2010, 3:50 pm

    The problem is in your call. It should be

    call do_it(parm1)

    and NOT

    do_it(parm1)

    In the later the brackets enforce pass by value instead of reference

    Reply
  • Kevin Abel November 4, 2010, 1:16 pm

    I have used byRef in previous versions of QTP and many other languages. For some reason it is not working in QTP 10.0. I am also using QTP patch QTP_00626 in case this matters.

    I call like this:

    do_it(parm1) ‘ Parm 1 is undefined at the end of run.
    x = 1 ‘ used as a breakpoint line.
    The function looks like

    Function do_it(by Ref parm1)
    parm1 = “hello”
    End Function

    What is wrong?

    Reply
    • Anshoo Arora November 14, 2010, 5:29 pm

      Kevin,

      Does this work for you?

      Dim var : var = ""
      
      Function do_It(ByRef arg)
      	arg = "hello"
      End Function
      
      do_It var
      
      MsgBox var
      

      I have tried this code with QTP 10 and it works as expected. Also tried it on QTP 11 and the same result..

  • Tarun Lalwani July 4, 2010, 1:44 am

    I hope you meant Anshoo and not Ankur?

    By default it is ByRef

    Reply
    • VK July 4, 2010, 3:52 pm

      oops..sorry. I meant Anshoo :(
      thanks for the prompt reply.

  • VK July 3, 2010, 5:01 pm

    Ankur- You talked about two ways values can be passed: ByVal and ByRef.
    What is the default way through which values are passed? I mean if I don’t specify Byval or Byref with the parameters, does it pass by reference?

    Reply
  • Puneet February 5, 2010, 3:45 am

    Hi Anshoo,

    Below is a code I am working on which i cannot seem get one thing right within the code. When a user selects a username it should check to see if the message box appears and if it does then it should go to the datatable and select a different username. Right now the script is running and only detecting SSN and changing the SSN regardless of me duplicate username.

    NewUser ‘Selecting a new user from the functional library
    ‘Adding the profile
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).SwfComboBox(“cboUserType”).Select “PROVIDER”
    SwfWindow(“DHA – You are currently”).SwfWindow(“Add User”).SwfEdit(“txtLname”).Set “One”
    SwfWindow(“DHA – You are currently”).SwfWindow(“Add User”).SwfEdit(“txtFname”).Set “Provider”
    username = SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).SwfEdit(“txtUsername”).GetROProperty(“text”)

    ‘If the SSN is duplicate then select the next one in the datatable
    For i = 1 to 10
    datatable.SetCurrerntRow(i)
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).SwfEdit(“txtSSN”).Set DataTable(“SSN”, dtLocalSheet)
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).SwfComboBox(“cmbCountry”).Select “US”
    SwfWindow(“DHA – You are currently”).SwfWindow(“Add User”).SwfButton(“btnAddUser”).Click

    If SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Static(“User with same SSN already”).Exist Then
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Static(“User with same SSN already”).Check CheckPoint(“User with same SSN already exists in the database.”)
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Activate
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).WinButton(“OK”).Click
    Exit For

    Elseif SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Static(“Another record with the”).Exist Then
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Static(“Another record with the”).Check CheckPoint(“Another record with the same user name already exists in the database.”)
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).Activate
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Alert]“).WinButton(“OK”).Click
    ‘Reporter.ReportEvent micFail, “Verify the user has been added”, “The” &username& “already exist”

    If SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Acknowledgement]“).Exist Then
    Reporter.ReportEvent micPass, “<Verify the user has been added;&gt”, “The ” &username& ” successfully has been added”
    SwfWindow(“HA – You are currently”).SwfWindow(“Add User”).Dialog(“HA – [Acknowledgement]“).WinButton(“OK”).Click
    end if
    end if
    next

    Reply
    • Anshoo Arora February 10, 2010, 2:15 pm

      Hi Puneet,

      Which part of the code is causing this issue? I think you would need to branch your code so that it does one complete iteration with the help of conditional statements. For example, if the userName is still the same as the previous, re-run the code and loop the code until the userName is different..

  • Tarun Lalwani December 15, 2009, 7:27 am

    You can also add about the forcing of passing by value for byRef params as explained in my comment in below article

    http://www.sqaforums.com/showflat.php?Number=606036

    Reply
    • Anshoo Arora December 16, 2009, 10:09 am

      Thanks for the link Tarun. I read the thread and will update the post soon. I have updated the article on RegisterUserFuncX, which its limitations. Thanks :)

  • nidhi November 5, 2009, 3:52 pm

    wow ! very neatly put. I am a newbie and i got a very clear idea. your examples are great !

    Reply
    • Anshoo Arora November 5, 2009, 5:41 pm

      Thank you, Nidhi. If you have any question with any of the material here, please feel free to ask. :)