Named Arguments No
CallByName(object, procedurename, calltype, _ [ argument1,..., argumentn])
Use: Required Data Type: Object
A reference to the object containing the procedure being called.
procedurename Use: Required
Data Type: String
The name of the procedure to call.
Data Type: vbCallType constant
A constant that indicates the type of procedure being called. vbCallType constants are listed in the next table.
142 Chapter 7- The Language Reference arguments
Data Type: Variant
Any number of variant arguments, depending on the argument list of the procedure to call.
The called procedure is a Property Get
The called procedure is a Property Let
The called procedure is a method; this can be a Sub or a Function within object
The called procedure is a Property Set
Depends on the return value (if any) of the called procedure. Description
Provides a flexible method for calling a public procedure in a VB object module. Since procedurename is a string expression, rather than the hard-coded name of a routine, it's possible to call routines dynamically at runtime with a minimum of coding.
Rules at a Glance
• The return type of CallByName is the return type of the called procedure.
• procedurenamie isn't case sensitive.
Programming Tips & Gotchas
• At last, VB allows you to create a call to a procedure using a string. This means that the call can be flexible at runtime.
• The only drawback to the current implementation of CallByName is that the parameters to pass to the called function must be entered individually. This means that, when coding the CallByName function, you need to know in advance how many parameters are needed. You could work around this by coding your functions to accept only Variant arrays so that you only need to pass a single parameter.
• Late binding is necessarily used to instantiate objects whose procedures are invoked by the CallByName function. Consequently, the performance of Call-ByName is inferior to that of method invocations in early bound objects. This degradation of performance is especially acute if CallByName is invoked repeatedly inside a looping structure.
The following example takes CallByName and the amendments to CreateObject to their logical conclusion: a variable procedure call to a variable ActiveX server in a variable location. In this example, the SQL Server pubs database is used as the
CallByName Function (VB6) 143
source of the data. Two ActiveX objects on two separate machines are used to create two different recordsets: one from the Authors table, the other from the Titles table. However, nowhere in the program are the names of the ActiveX DLLs, the procedures, or the remote servers mentioned.
The middle tier of this application uses the registry to store these names, allowing fast alteration of the application without touching a single line of code or creating incompatibilities between components. The repercussions of this approach to enterprise-wide programming are wide-reaching, and the prospects very exciting.
Only when dealing with the user interface of the client component are the names of the required datasets and fields specified. The Form_Load event calls a standard function to populate combo box controls with the required data:
Private Sub Form_Load()
PopulateCombo cboAuthors, "Authors", "au_lname" PopulateCombo cboTitles, "Titles", "title"
The PopulateCombo function calls a GetRecordset function in the first middle tier of the model, passing in the recordset name required (either Authors or Titles in this case) and a search criteria string that is concatenated into the embedded SQL script to refine the recordset. GetRecordset returns an ADO recordset that populates the desired combo box:
Private Function PopulateCombo(oCombo As ComboBox, _
sRecords As String, _ sField As String) As Boolean
Dim adorRecords As ADODB.Recordset Dim sSearch As String
If sRecords = "Authors" Then sSearch = "contract = 1 AND state = 'CA'"
Else sSearch = "" End If
Set adorRecords = oAdmin.GetRecordset(sRecords, sSearch)
Do While Not adorRecords.EOF
oCombo.AddItem adorRecords(sField) adorRecords.MoveNext
Set adorRecords = Nothing
The GetRecordset method that sits on a central machine interrogates the registry (using the GetSetting function) to determine the names of the ActiveX server, the machine, and the procedure to call. I've also coded an alternative method of
144 Chapter 7- The Language Reference obtaining these names using a Select Case statement (which is commented out in the code sample). Finally, the CreateObject function obtains a reference to the appropriate ActiveX server on the appropriate machine and a call is made to the function in that server to obtain the correct recordset:
Public Function GetRecordset(sRecords As String, _
sCriteria As String _ ) As ADODB.Recordset
Dim sServer As String
Dim oServer As Object sServer = GetSetting(App.Title, sRecords, "Server") sLocation = GetSetting(App.Title, sRecords, "Location") sMethod = GetSetting(App.Title, sRecords, "GetMethod")
An alternative method of obtaining the names of the elements of the remote procedure call is to hard-code them into the application as follows: Select Case sRecords Case Is = "Titles"
sServer = "TestDLL.Titles" sLocation = "NTSERV1" sMethod = "GetTitles" Case Is = "Authors"
sServer = "Test2DLL.Authors" sLocation = "NTWS2" sMethod = "getAuthors" Case Else
Set GetRecordset = Nothing Exit Function End Select
Set oServer = CreateObject(sServer, sLocation)
Set GetRecordset = CallByName(oServer, _
sMethod, _ VbMethod, _ sCriteria)
The code to create the recordsets in TestDLL.Titles and Test2DLL.Authors isn't shown here, as it's straightforward database access code.
Now, imagine for a moment that the organization using this application wanted a minor alteration in the way the Authors recordset was presented to the client (a different sort order, for example). You can now make a change to the procedure, calling it getAuthorsRev; compile a completely new ActiveX server; and place it on the remote server. Then with two quick edits of the registry, all the clients in the organization would instantly access the new procedure with a minimum of fuss,
CallByName Function (VB6) 145
no loss of component compatibility, zero downtime, and an almost seamless transition.
Was this article helpful?