CallByName Function
Executes a method, sets or returns a property, or sets or returns a field of an object.
Syntax
CallByName(object, procname, calltype, [args()])
Parameters
object- Required. Object expression on which the function will be executed.procname- Required. String expression containing the name of the property, method, or field member of the object.calltype- Required. Member of theVbCallTypeenumeration representing the type of procedure being called.args()- Optional.Variantarray containing the arguments to be passed to the property, method, or field being called.
VbCallType Constants
| Constant | Value | Description |
|---|---|---|
VbMethod |
1 | A method is being called |
VbGet |
2 | A property value is being retrieved |
VbLet |
4 | A property value is being set |
VbSet |
8 | A reference to an object is being set |
Return Value
Returns a Variant containing the result of the called property or method. For VbLet and VbSet,
the return value is not meaningful.
Remarks
The CallByName function allows you to execute object members by name at run time, providing
a form of late binding. This is particularly useful for:
- Creating generic routines that work with multiple object types
- Implementing dynamic property access based on user input
- Building reflection-like functionality in VB6
- Simplifying repetitive property access code
Important Notes
- Late Binding:
CallByNamealways uses late binding, even if the object variable is early bound - Performance: Slower than direct method/property calls due to name lookup overhead
- Case Insensitive: The
procnameparameter is case-insensitive - Error Handling: Raises run-time error if the member doesn't exist
- Type Safety: No compile-time checking of member existence or argument types
Call Type Details
VbMethod (1):
- Calls a Sub or Function
- Returns the function's return value (or Empty for Subs)
- Passes arguments in the args array
VbGet (2):
- Retrieves a property value or field value
- Can be used with property procedures (Property Get) or public fields
- For parameterized properties, pass indices in args array
VbLet (4):
- Sets a property value or field value
- For simple data types (numbers, strings, etc.)
- The new value must be the last element in the args array
- For parameterized properties, indices come before the value
VbSet (8):
- Sets an object reference property
- Similar to VbLet but for object references
- Used when you would normally use the Set keyword
Examples
Basic Method Call
Dim obj As Object
Set obj = CreateObject("Scripting.FileSystemObject")
' Call the GetFolder method
Dim folder As Variant
folder = CallByName(obj, "GetFolder", VbMethod, "C:\Temp")
Property Get
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
' Get the Drives property
Dim drives As Variant
drives = CallByName(fs, "Drives", VbGet)
Property Let
Dim txt As Object
Set txt = CreateObject("Scripting.TextStream")
' Set a property value
CallByName txt, "Line", VbLet, 10
Property Set (Object Reference)
Dim form As Form
Set form = New Form1
Dim btn As CommandButton
Set btn = New CommandButton
' Set an object property
CallByName form, "ActiveControl", VbSet, btn
Dynamic Property Access
Function GetPropertyValue(obj As Object, propName As String) As Variant
GetPropertyValue = CallByName(obj, propName, VbGet)
End Function
Function SetPropertyValue(obj As Object, propName As String, value As Variant)
CallByName obj, propName, VbLet, value
End Function
Common Patterns
1. Generic Property Copier
Sub CopyProperties(source As Object, dest As Object, propNames() As String)
Dim i As Integer
Dim value As Variant
For i = LBound(propNames) To UBound(propNames)
value = CallByName(source, propNames(i), VbGet)
CallByName dest, propNames(i), VbLet, value
Next i
End Sub
2. Form Field Population
Sub PopulateFormFromRecordset(frm As Form, rs As Recordset)
Dim fld As Field
Dim ctl As Control
For Each fld In rs.Fields
On Error Resume Next
Set ctl = frm.Controls(fld.Name)
If Not ctl Is Nothing Then
CallByName ctl, "Text", VbLet, fld.Value & ""
End If
On Error GoTo 0
Next fld
End Sub
3. Dynamic Method Invocation
Function InvokeMethod(obj As Object, methodName As String, _
ParamArray args() As Variant) As Variant
Dim argArray() As Variant
Dim i As Integer
If UBound(args) >= 0 Then
ReDim argArray(LBound(args) To UBound(args))
For i = LBound(args) To UBound(args)
argArray(i) = args(i)
Next i
InvokeMethod = CallByName(obj, methodName, VbMethod, argArray)
Else
InvokeMethod = CallByName(obj, methodName, VbMethod)
End If
End Function
4. Property Name Validation
Function HasProperty(obj As Object, propName As String) As Boolean
On Error Resume Next
Dim temp As Variant
temp = CallByName(obj, propName, VbGet)
HasProperty = (Err.Number = 0)
On Error GoTo 0
End Function
5. Bulk Property Setting
Sub SetMultipleProperties(obj As Object, propNames As Variant, _
propValues As Variant)
Dim i As Integer
For i = LBound(propNames) To UBound(propNames)
CallByName obj, propNames(i), VbLet, propValues(i)
Next i
End Sub
' Usage:
SetMultipleProperties myControl, _
Array("Left", "Top", "Width", "Height"), _
Array(100, 100, 200, 50)
6. Parameterized Property Access
' Access a property with parameters (like an indexed property)
Sub SetIndexedProperty(obj As Object, propName As String, _
index As Integer, value As Variant)
CallByName obj, propName, VbLet, index, value
End Sub
Function GetIndexedProperty(obj As Object, propName As String, _
index As Integer) As Variant
GetIndexedProperty = CallByName(obj, propName, VbGet, index)
End Function
7. Configuration-Driven Object Initialization
Sub InitializeFromConfig(obj As Object, configFile As String)
Dim fs As Object
Dim ts As Object
Dim line As String
Dim parts() As String
Set fs = CreateObject("Scripting.FileSystemObject")
Set ts = fs.OpenTextFile(configFile)
Do While Not ts.AtEndOfStream
line = ts.ReadLine
If InStr(line, "=") > 0 Then
parts = Split(line, "=")
CallByName obj, Trim(parts(0)), VbLet, Trim(parts(1))
End If
Loop
ts.Close
End Sub
8. Error-Safe Property Access
Function SafeGetProperty(obj As Object, propName As String, _
Optional defaultValue As Variant) As Variant
On Error Resume Next
SafeGetProperty = CallByName(obj, propName, VbGet)
If Err.Number <> 0 Then
If Not IsMissing(defaultValue) Then
SafeGetProperty = defaultValue
Else
SafeGetProperty = Empty
End If
End If
On Error GoTo 0
End Function
Advanced Usage
Calling Methods with Multiple Arguments
Dim obj As Object
Set obj = CreateObject("SomeLibrary.SomeClass")
' Call a method with multiple arguments
Dim result As Variant
result = CallByName(obj, "Calculate", VbMethod, 10, 20, "sum")
Working with Collections
Sub EnumerateCollection(coll As Collection, methodName As String)
Dim item As Variant
For Each item In coll
CallByName item, methodName, VbMethod
Next item
End Sub
Building a Simple ORM
Sub SaveObjectToDatabase(obj As Object, tableName As String, _
propNames() As String)
Dim sql As String
Dim values As String
Dim i As Integer
Dim value As Variant
sql = "INSERT INTO " & tableName & " ("
values = " VALUES ("
For i = LBound(propNames) To UBound(propNames)
If i > LBound(propNames) Then
sql = sql & ", "
values = values & ", "
End If
sql = sql & propNames(i)
value = CallByName(obj, propNames(i), VbGet)
values = values & "'" & value & "'"
Next i
sql = sql & ")" & values & ")"
' Execute SQL...
End Sub
Error Handling
Common errors when using CallByName:
- Error 438: Object doesn't support this property or method
- The specified member doesn't exist
-
Check spelling and case (though
CallByNameis case-insensitive) -
Error 450: Wrong number of arguments or invalid property assignment
- Incorrect number of arguments in the args array
- Using
VbLetfor an object (should useVbSet) -
Using
VbSetfor a value type (should useVbLet) -
Error 13: Type mismatch
- Argument types don't match what the member expects
On Error Resume Next
result = CallByName(obj, "PropertyName", VbGet)
If Err.Number <> 0 Then
MsgBox "Error accessing property: " & Err.Description
End If
On Error GoTo 0
Performance Considerations
CallByNameis significantly slower than direct member access- Name resolution happens at runtime, not compile time
- Consider caching frequently accessed members
- Use early binding and direct calls in performance-critical code
CallByNameis best for scenarios where dynamic access is necessary
Limitations
- Cannot call private members
- Cannot call Friend members from outside the project
- No
IntelliSensesupport for the member being called - No compile-time type checking
- Cannot call default members by passing empty string
- More difficult to debug than direct calls
Related Functions
Eval: Evaluates an expression (only in VBA, not VB6)Execute: Executes a statement (only in VBA, not VB6)GetObject: Returns a reference to an objectCreateObject: Creates an instance of an objectTypeName: Returns the type name of a variableVarType: Returns the variant subtype of a variable
Parsing Notes
The CallByName function is not a reserved keyword in VB6. It is parsed as a regular
function call (CallExpression). This module exists primarily for documentation
purposes and to provide a comprehensive test suite that validates the parser
correctly handles CallByName function calls in various contexts.