Results 1 to 7 of 7

Thread: call a sub from another sub

  1. #1

    call a sub from another sub

    I'm new to VBA and I have this sub that calculates the perimeter and area of rectangle. It should pass the length, breadth and perimeter as parameters. Then I need to call this sub from another sub and use debug.print to display the result in immediate window. This is the code I have:
    [VBA]Sub Rectangle(ByVal Area As Double, ByVal Perimeter As Double, ByVal Length As Double, ByVal Breadth As Double)
    Area = Length * Breadth
    Perimeter = (Length + Breadth) * 2
    End Sub

    Sub ShowResult()
    Call Rectangle(Area, Perimeter, 3, 5)
    Debug.Print "Length=" & Length & "Breadth=" & Breadth & "Area=" & Area & "Perimeter=" & Perimeter
    End Sub[/VBA]
    It gives error, I can't figure out how to do it after a day of researching on the web.
    Can anyone pls help and give some hint, thanks.

  2. #2
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    Use ByRef rather than ByVal.

  3. #3
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,455
    Location
    Quote Originally Posted by Kenneth Hobs
    Use ByRef rather than ByVal.
    Only for Area and Perimeter ...
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  4. #4
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,743
    Location
    1. 'Option Explicit' is your friend

    2. ByRef puts the address of the variable on the stack when it calls the Sub or Function. That way the sub will be updating the original variable

    3. ByVal puts a copy of the variable or value on the stack, where it's used but does not update the original. So by using the ByVal calling convention on Rectangle(), Length and Breadth come in as 'numbers (as did Area and Perimeter), but Area and Perimeter from the calling routine (ShowResults) were never updated.


    [vba]
    Option Explicit
    Sub Rectangle(ByRef Area As Double, ByRef Perimeter As Double, Length As Double, Breadth As Double)
    Area = Length * Breadth
    Perimeter = (Length + Breadth) * 2
    End Sub

    Sub ShowResult()
    Dim Area As Double, Perimeter As Double, Length As Double, Breadth As Double

    Length = 3
    Breadth = 5

    Call Rectangle(Area, Perimeter, Length, Breadth)

    'or Call Rectangle(Area, Perimeter, 3, 5)

    Debug.Print "Length= " & Length & " Breadth= " & Breadth & " Area= " & Area & " Perimeter=" & Perimeter

    End Sub
    [/vba]

    Paul

  5. #5
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,743
    Location
    I had a thought that to avoid confusing the variables with the same names in the different routines, it might be a little clearer use A, P, L and B in one routine, instead of Area in both. That way the scope of the variables might be easier to follow

    [vba]
    Option Explicit
    Sub Rectangle(ByRef Area As Double, ByRef Perimeter As Double, Length As Double, Breadth As Double)
    Area = Length * Breadth
    Perimeter = (Length + Breadth) * 2
    End Sub

    Sub ShowResult()
    Dim A As Double, P As Double, L As Double, B As Double

    L = 3
    B = 5

    Call Rectangle(A, P, L, B)
    Debug.Print "Length= " & L & " Breadth= " & B & " Area= " & A & " Perimeter=" & P

    L = 300
    B = 500
    'Note 3 and 5 are passed, not L=300 and B=500
    'so the Area and Preimeter from Rectangle are based on 3 and 5, not 300 and 500
    'even though the Debug is still based on the values of L and B
    Call Rectangle(A, P, 3, 5)
    Debug.Print "Length= " & L & " Breadth= " & B & " Area= " & A & " Perimeter=" & P


    Call Rectangle(A, P, 2 * L, 0.5 * B)
    Debug.Print "Length= " & L & " Breadth= " & B & " Area= " & A & " Perimeter=" & P

    End Sub
    [/vba]

    Paul

  6. #6
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,455
    Location
    Paul,

    In

    [vba]Sub Rectangle(ByRef Area As Double, ByRef Perimeter As Double, Length As Double, Breadth As Double)[/vba]

    Length and Breadth are also passed ByRef, it is the default. Best to be explicit.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  7. #7
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,743
    Location
    You are correct Sir

    I was in the wrong language I think, at least as far as calling convention defaults are concerned

    Thanks for pointing that out

    Paul

Posting Permissions

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