Most of the time you can discover the properties and methods of an object at design time and write code to handle them. In a few cases, however, you may not know about an object’s properties and methods in advance, or you may simply want the flexibility of allowing an end user to specify properties or execute methods at run time.
Consider, for example, a client application that evaluates expressions entered by the user by passing an operator to a server application. Now suppose that you are constantly adding new functions to the server that require new operators. Unfortunately, you would need to recompile and redistribute the client application before it would be able to use the new operators. In order to avoid this, you can use the CallByName function to pass the new operators as strings, without changing the application.
The CallByName function allows you to use a string to specify a property or method at run time. The signature for the CallByName function looks like this:
Result = CallByName(Object, ProcedureName, CallType, Arguments())
The first argument to CallByName takes the name of the object that you want to act upon. The second argument, ProcedureName, takes a string containing the name of the method or property procedure to be invoked. The CallType argument takes a constant representing the type of procedure to invoke: a method (vbMethod), a property let (vbLet), a property get (vbGet), or a property set (vbSet). The final argument is optional, it takes a variant array containing any arguments to the procedure.
Suppose you had a server application, MathServer, with a new SquareRoot function. Your application has two TextBox controls: Text1 contains the expression to be evaluated upon; Text2 is used to enter the name of the function. You could use the following code in the Click event of a command button to invoke the SquareRoot function on the expression in Text1:
Private Sub Command1_Click()
Text1.Text = CallByName(MathServer, Text2.Text, vbMethod, Text1.Text)
End Sub
If the user enters "64 / 4" in Text1 and "SquareRoot" in Text 2, the above code would invoke the SquareRoot function (which takes a string containing the expression to be evaluated as a required argument) and return "4" in Text1 (the square root of 16, or 64 divided by 4). Of course, if the user entered an invalid string in Text2, or if the string contained the name of a property instead of a method, or if the method had an additional required argument, a run-time error would occur. As you might guess, you’ll need to add robust error handling code when you use CallByName to anticipate these or any other errors.
While the CallByName function may be useful in some situations, you need to weigh its usefulness against the performance implications — using CallByName to invoke a procedure is slightly slower than late-bound calls. If you’re invoking a function that will be called repeatedly, such as inside a loop, CallByName could have a severe effect on performance.