Reputation: 46
I am facing a problem when I want to rewrite part of my program. This part is put in module1 and look like as follows:
Public Function InputCorr(Target As MSForms.Control) As Boolean
If FrmAddRecord1Shown Then
Target.Value = CallByName(frmAddRecord1, Target.Name & "_Min", VbMethod)
ElseIf FrmAddRecord2Shown Then
Target.Value = CallByName(frmAddRecord2, Target.Name & "_Min", VbMethod)
End If
End Function
And I am going to rewrite like this:
Public Function InputCorr(Target As MSForms.Control) As Boolean
Dim UF As UserForm
If FrmAddRecord1Shown Then
set UF = frmAddRecord1
ElseIf FrmAddRecord2Shown Then
set UF = frmAddRecord2
EndIf
Target.Value = CallByName(UF, Target.Name & "_Min", VbMethod)
End Function
FrmAddRecord1Shown and FrmAddRecord2Shown are boolean, indicating which userform (frmAddRecord1 or frmAddRecord2)is active.
However, "run-time error"438": Object doesn't spport this property or method" occurs. I believe I was stuck at the "UF" defining part. Is it possible for me to define the "object" part of "callbyname" function with variable? Please advice. Thank you very much for all yours sincere help.
Upvotes: 0
Views: 3474
Reputation: 56
CallByName(object, procname, calltype, [args()])
(Reference: https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/callbyname-function) performs an action on the object
during run-time (late binding). Before using CallByName
, your should make sure that the equivalent early binding operation works.
Depending on the calltype
you use in CallByName
, the procname
corresponds to different members of the object
: (The following cases are expressed in the form of "late-binding corresponds to early-binding")
(1) CallByName(object, procname, calltype:=vbGet)
corresponds to object.[Property]
(2) CallByName(object, procname, calltype:=vbLet)
corresponds to object.[Property, which is a value]
(3) CallByName(object, procname, calltype:=vbMethod)
corresponds to object.[Method]
(4) CallByName(object, procname, calltype:=vbSet)
corresponds to object.[Property, which is an object]
Now, in your function, you are performing on the UF
object (an UserForm
object) with CallByName(UF, procname, VbMethod)
, which corresponds to Case (3) mentioned above. Therefore, your procname
should be a Method of the UserForm
object. You can check the Methods of the UserForm
object in the Object Browser (press F2 in the VBA editor, and find UserForm under the MSForms Libary). The Methods are listed in the following code: (DO NOT run the code, the codes do not do anything.)
Private Sub UserFormMethods()
Dim ufForm As UserForm
Set ufForm = frmAddRecord1
With ufForm
.Copy
.Cut
.Paste
.RedoAction
.Repaint
.Scroll
.SetDefaultTabOrder
.UndoAction
End With
End Sub
However, in your CallByName
function, your procname
argument is Target.Name
. Target
in your definition is an MSForms.Control
object, which is an object PROPERTY, not a METHOD, of the UserForm
object. Therefore it triggers the "run-time error"438": Object doesn't spport this property or method" error.
I think what you are trying to do is actually using CallByName
on the Target
object (an MSForms.Control
object). I would suggest changing your function to:
Public Function InputCorr(Target As MSForms.Control) As Boolean
Dim UF As UserForm
Dim ctlTarget As MSForms.Control
If FrmAddRecord1Shown Then
Set UF = frmAddRecord1
ElseIf FrmAddRecord2Shown Then
Set UF = frmAddRecord2
End If
Set ctlTarget = CallByName(UF, Target.Name, VbGet)
Call CallByName(ctlTarget, "_Min", VbMethod)
End Function
I was not able to find the MSForms.Control._Min
method in the object browser. Maybe it is a hidden method but you must make sure this method exists.
Also, you did not specify what your function's return value is. It should have a final line like: InputCorr = ...
Upvotes: 2