Coding ArgumentsVariables that are local to a procedure can only be used inside that procedure. Variables declared inside a modules general section are global to the module and available throughout the entire module. Variables declared with Public instead of Dim inside the general section are global to the entire project. Youve seen throughout the first part of this book that you should avoid global variables as much as possible and use only local variables. If, however, you only use local variables but you write lots of small procedures (as you should), how can the procedures share data? If all the data is local, a called procedure has no access to the calling procedures data. As you probably suspect, youll share data through argument lists. When one procedure must call another procedure, and the called procedure needs information from the calling procedure, the calling procedure can send that information inside the argument list. Suppose one procedure calculates a value and a second procedure must use that value in a different calculation before displaying a result on the form. You need to know how to pass local data from the procedure that defines the local variable to other procedures that need to work with that value. When you call a built-in function, you pass one or more arguments to the function so that the functions internal code has data to work with. When you call your own subroutine and function procedures, you also can pass arguments to them. The arguments are nothing more than the passing procedures local variables that the receiving procedure needs to work with. After you pass data, that data is still local to the original passing procedure, but the receiving procedure has the opportunity to work with those values for the time of the procedure execution. Depending on how you pass the arguments, the receiving procedure might even be able to change those values so that when the passing procedure regains control, its local variables have been modified by the called procedure.
You must declare the receiving argument lists datatypes for each argument. If you pass or receive more than one argument, separate the arguments with commas. The following statement passes the three values to a subroutine: Call RecProc(I, J, K) The following statement declares the RecProc() procedure: Public Sub RecProc (I As Integer, J As Integer, K As Single) The calling procedure already knows the datatypes of I, J, and K, but those values are unknown to RecProc(). Therefore, youll have to code the datatype of each received argument so that the receiving function knows the datatype of each sent argument. If a subroutine or function procedure is to receive arrays, dont indicate the array subscripts inside the argument list. The following Sub statement defines a general-purpose subroutine procedure that accepts four arrays as arguments: Public Sub WriteData (GNames() As String, CBalc() As Currency, ÂCDate() As Variant, CRegion() As Integer) The built-in UBound() function returns the highest subscript thats defined for any given array. The following statement, which might appear inside the WriteData() subroutine, stores the highest possible subscript for the CNames() array, so the subroutine wont attempt to access an array subscript outside the defined limit: intHighSub = UBound(CNames) Receiving by Reference and by ValueVisual Basic lets you pass arguments two ways: by reference and by value. The way you use them determines whether the receiving procedure can change the arguments so that those changes remain in effect after the calling procedure regains control. If you pass and receive by reference (the default method), the calling procedures passed local variables may be changed in the receiving procedure. If you pass and receive by value, the calling procedure can access and change its received arguments, but those changes dont retain their effects in the calling procedure.
When passing by reference, subroutines and functions can always use their received values and also change those arguments. If a receiving procedure changes one of its arguments, the corresponding variable in the calling procedure is also changed. Therefore, when the calling procedure regains control, the value (or values) that the calling procedure sent as an argument to the called subroutine may be different from the time before the call.
Arguments are passed by reference, meaning that the passed arguments can be changed by their receiving procedure. If you want to keep the receiving procedure from being able to change the calling procedures arguments, you must pass the arguments by value. To pass by value, precede any and all receiving argument lists with the ByVal keyword, or enclose the passed arguments in parentheses.
Its generally safer to receive arguments by value because the calling procedure can safely assume that its passed values wont be changed by the receiving procedure. Nevertheless, there may be times when you want the receiving procedure to permanently change values passed to it. In such cases, you'll need to receive those arguments by reference. Listing 13.3 shows two subroutine procedures. One, named Changes(), receives arguments by address. The second procedure, NoChanges(), receives its arguments by value. Even though both procedures multiply their arguments by two, those changes affect the calling procedures variables only when Changes() is called but not when NoChanges() is called. Listing 13.3. Some procedures can change the sending procedures arguments. 1: Sub Changes(N As Integer, S As Single) 2: ' Receives arguments by reference 3: N = N * 2 ' Double both 4: S = S * 2 ' arguments 5: ' When the calling routine regains control, 6: ' its two local variables will now be twice 7: ' as much as they were before calling this. 8: End Sub 9: 10: Sub NoChanges(ByVal N As Integer, ByVal S As Single) 11: ' Receives arguments by value 12: N = N * 2 ' Double both 13: S = S * 2 ' arguments 14: ' When the calling routine regains control, 15: ' its two local variables will not be 16: ' changed from their original values. 17: End Sub As you can see, Changes() receives its arguments by reference. (Remember that the default passing method is by reference, even if you omit ByRef.) Therefore, when the procedure doubles the arguments, the calling procedures argument variables change as well. In NoChanges(), the procedure receives its arguments by value. Therefore, nothing NoChanges() does can change those values in the calling procedure. |
|
![]() |
![]() |
|||