Results 1 to 4 of 4

Thread: when to use () and when not in vba functions

  1. #1
    Board Regular
    Join Date
    Mar 2016
    Posts
    1,383
    Post Thanks / Like
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default when to use () and when not in vba functions

    Hi
    I am reading a article about when I should user ( ) and when not. I wrote a code below but not sure why Y =1

    Code:
    Sub myfoo()
        Dim x As Integer
        Dim y As Integer
        x = InputBox("enter number")
        y = MsgBox(2 * x)
        MsgBox y
    End Sub
    Also, do you know where I can read about this topic, when I call a function without () and when I need (). This article https://docs.microsoft.com/en-us/off...ion-procedures
    is good but I need to read more and simpler methods to understand. Thank you very much

  2. #2
    Board Regular
    Join Date
    Mar 2015
    Posts
    3,893
    Post Thanks / Like
    Mentioned
    72 Post(s)
    Tagged
    7 Thread(s)

    Default Re: when to use () and when not in vba functions

    Run this code and you will understand why the 2nd message box returns 1
    - it is NOTHING to do with "y"
    - it is dependant on what you clicked to close the message box (try abort, retry and ignore)
    Code:
    Sub Test1()
        Dim y
        y = MsgBox("text", vbAbortRetryIgnore)
        MsgBox y
    End Sub
    This is the same as above
    Code:
    Sub Test2()
        MsgBox MsgBox("text", vbAbortRetryIgnore)
    End Sub

    Is this what you want?

    Code:
    Sub myfoo()
        Dim x As Integer
        Dim y As Integer
        x = InputBox("enter number")
        y = 2 * x
        MsgBox y
    End Sub
    Last edited by Yongle; Mar 26th, 2019 at 12:05 PM.

  3. #3
    MrExcel MVP shg's Avatar
    Join Date
    May 2008
    Location
    The Great State of Texas
    Posts
    21,611
    Post Thanks / Like
    Mentioned
    0 Post(s)
    Tagged
    14 Thread(s)

    Default Re: when to use () and when not in vba functions

    When you invoke a Sub with Call, you must use parens around the arguments:

    Code:
    Call MySub(arg1, arg2)
    When you assign the result of a function to a variable, you must use parens around the arguments:

    Code:
    myResult = MyFunc(arg1, arg2)
    If you are not using Call, and want to pass arguments ByVal (by value, a copy of the variable) or ByRef (by reference, a pointer to the variable), according to the procedure's signature, you don't include parens:

    Code:
    MySub arg1, arg2
    MyFunc arg1, arg2
    If you want to pass arguments ByVal, irrespective of the procedure’s signature (which won't work for a procedure expecting an array (because arrays are always passed by reference) or an object), you enclose the argument in parens, or an extra set of parens. In the examples below, arg1 is passed by value, and arg2 according to the procedure’s signature:

    Code:
    Call MySub((arg1), arg2)
    myResult = MyFunc((arg1), arg2)
    MySub (arg1), arg2
    MyFunc (arg1), arg2
    That’s because when you add parens around an argument that doesn't require them, the argument is evaluated …

    StringExpression -> String
    NumericExpression -> Number
    Range -> Variant for single cell, 2D Variant array for multi-cell
    Object other than Range -> Error

    …, and the result of the evaluation is passed to the procedure. It means the argument is passed by value regardless of how the procedure requested it.

    That also explains why you can't use parens around two or more arguments when they are not required; the evaluation of (arg1) may be meaningful, but the evaluation of (arg1, arg2) is not. That's why this generates an error:

    Code:
    Msgbox (Prompt:=arg1, Title:=arg2, Buttons:=arg3)
    That also explains why if you call a procedure expecting a range with parens where none are required, you get a type mismatch error; because the evaluation of a range is a Variant, or Variant/Array.

    You can't pass a Variant ByRef as a static type (Long, String, ...).

    You can pass a statically-typed variable ByRef as a Variant, and the called procedure can modify its value with data of the appropriate (or coercible) type.

    So: Parens means completely different things according to context. VBA might have used some other bookends (curly braces, square brackets, whatever) to indicate enclosing a list of arguments versus a call for evaluation, but it didn't.

    Since objects other than Range object are always passed ByRef, you can never put unnecessary parens around an object variable. Chip Pearson (http://www.cpearson.com/excel/byrefbyval.aspx) explains the meaning of ByRef and ByVal for an object variable:

    The ByRef and ByVal modifiers indicate how the reference is passed to the called procedure. When you pass an object type variable to a procedure, the reference or address to the object is passed -- you never really pass the object itself. When you pass an object ByRef, the reference is passed by reference and the called procedure can change the object to which that reference refers to. When an object is passed ByVal, a copy of the reference (address) of the object is passed.

  4. #4
    Board Regular
    Join Date
    Mar 2016
    Posts
    1,383
    Post Thanks / Like
    Mentioned
    6 Post(s)
    Tagged
    0 Thread(s)

    Default Re: when to use () and when not in vba functions

    This is very great. Thank you so much. I will read it carefully. Thanks a lot all.

Some videos you may like

User Tag List

Tags for this Thread

Like this thread? Share it with others

Like this thread? Share it with others

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •