Is this a normal behavior in Access? (1 Viewer)

KitaYama

Well-known member
Local time
Today, 13:52
Joined
Jan 6, 2022
Messages
1,893
After using Access for years, now I'm back to my first years that I don't even understand how Compile behaves.

I have a form with a simple code in it's On_Open event :
SQL:
Private Sub Form_Open(Cancel As Integer)
    SetTestMode Me
End Sub

And this is the function:

SQL:
Public Function SetTestMode(frm As Access.Form)
    MsgBox "hi"
End Function

The db compiles and runs without error.
If I change the function as bellow, still the db complies without any error.
SQL:
Public Function SetTestMode()
    MsgBox "hi"
End Function
But at run time it returns an error, apparently because of Me. (Run time error:13 - Type mismatch)
Has Access been behaving this way all these years and I simply hadn't noticed? or is it a new thing?
Why the compile doesn't return any error?

thanks.

PS: A sample db is attached. Since I use a non-english version of office, you can not open my forms. I had to use one of Isladogs' databases posted here to show my case. Apologies to @isladogs for using his db as a test.
 

Attachments

Last edited:
Normally when you wish to use a function without gracing its return value you use the syntax:
Code:
Call SetTestMode(Me)
rather than the syntax you used (which you would use for subs).

I am answering from my phone so I can't test whether it would fail to compile issuing the Call syntax
 
Last edited:
Normally when you wish to use a function without gracing its return value you use the syntax:
Code:
Call SetTestMode(Me)
rather than the syntax you used (weigh you would use for subs).

I am answering from my phone so I can't test whether it would fail to compile issuing the Call syntax
Same result :
Call SetTestMode(Me)

Compiles, but error at runtime.

But if I change Function to sub, compile fails.
 
Yes, seems strange.

Will try and test tomorrow on Acc 2k7 to see if it has been like that for a long time.
 
After years of using Access, it's the first time I realize Sub and Function behave different when there's no return for a Function.

Thanks.
 
@cheekybuddha thanks for your assist. Go to bed and have a good night.

to others:

This is the most strange thing I've encountered during all these years.
The following compiles too.

SQL:
Private Sub Form_Open(Cancel As Integer)
    Dim t As String
    t = SetTestMode(Me)
End Sub

Public Function SetTestMode()
    MsgBox "hi"
End Function
 
OK,
It's getting more weird and strange to me.
The following compiles, but shows error 13 at run time.

SQL:
Private Sub Form_Open(Cancel As Integer)
    Dim t As Variant
    t = SetTestMode(Me)
End Sub

Public Function SetTestMode() As Variant
    MsgBox "hi"
End Function
 
Last edited:
Has Access been behaving this way all these years and I simply hadn't noticed? or is it a new thing?
Why the compile doesn't return any error?

I tested what you're doing with A2016 and it's the same.

I don't see this as a new thing. For instance, when you write code with variables that aren't tied to a specific type, which we refer to as "late binding", the compiler overlooks those details and allows you to continue writing your code mindlessly. It’s only when you try to execute the code that it sends you to hell and it throws the errors you should have thought of before hand.
 
I've looked through the VBA Language Spec document but so far haven't found the semantic implications of omitting a name for a variable in a function/sub declaration.

I wonder if the REAL problem is that you have a zero-argument declaration for SetTestMode, but you use a one-argument activation, and the correct error should be "wrong number of arguments" or words to that effect.
 
The compiler error only occurs if the function is declared with a variant return. (see #13)
The compiler does not complain if the function is declared with a variant return.

Code:
Private Sub Form_Open(Cancel As Integer)
   SetTestMode Me
End Sub

Public Function SetTestMode() As Variant
    MsgBox "hi"
End Function
vs
Code:
Private Sub Form_Open(Cancel As Integer)
   SetTestMode Me
End Sub

Public Function SetTestMode() As String
    MsgBox "hi"
End Function
 
Last edited:
The compiler error only occurs if the function is declared with a variant return.
It's the other way round. ;-)
There is no compile error if the return type of the function is Variant or Object.
The latter is they key as to why there is no compile error.

If the SetTestMode function would return an Object, the code would call the default method of the returned object and pass the form (Me) to that method.

This compiles and executes without error (if there is an open form named "Form1"):
Code:
Public Sub TestStart()
    Dim formName As String
    formName = "Form1"
    Dim t As Variant
    t = SetTestMode(formName)
End Sub

Public Function SetTestMode() As Object
    Set SetTestMode = Forms
End Function

The variable t is then assigned the Controls collection of Form1. - Slightly weird, that this works without the Set keyword, but that's beyond the scope of the original question.
 
Thanks Philipp, that's exactly the explanation why the compiler can't report an error.
I hadn't thought about default properties. And since Variant/Object performs a late binding on object return, the compiler cannot know whether the default property of the “expected” object supports the parameter.
 
While I still have doubt about what already has been discussed, I still don't understand why I'm passing a form object to a function that doesn't need a parameter, and the compiler doesn't catch that.

Any explanation on that?

thanks.
 
Last edited:
Because the compiler assumes that the parameter is not the parameter of the function but the parameter of the default property of the object returned by the function.

Code:
Dim frm as Form
set  frm = Forms("...")

dim ctl as Variant ' ... or Control
set ctl = frm("ControlName") ' <--- this is not a parameter of the function 'frm'
' ctl = control reference, equal to
set ctl = frm.Controls("ControlName")

' or
dim x as Variant
x = frm("ControlName") ' ... equal to x = frm.Controls("ControlName").Value


[OT]
I would prefer to have a possibility in VBA like “Option Explict” to turn off the default properties. :)
 
Last edited:
is not the parameter of the function but the parameter of the default property of the object returned by the function.
Then why does it not throw/fail to compile when using the Sub syntax?

You can't write:
Code:
' ...
  frm.Controls "ControlName" = "Hello"
' ...
 
Then why does it not throw/fail to compile when using the Sub syntax?
Because the default method of a returned object may also be a Sub.

You can't write:
Code:
Code:
' ...
  frm.Controls "ControlName" = "Hello"
' ...
Controls is a collection and you must pass in the index or key of a collection item.
[PS]In similar previous examples this would only be certain a run time but not at compile time. So, then it would only cause a runtime error. With your code it is already certain at compile time and this raises an compile error. [/PS]
 
the parameter of the default property of the object returned by the function.
I'm sorry for acting dumb, but I don't understand what does it mean.
My function doesn't return any object, how ME passed to the function can be thought to be the default value of the object returned?
 

Users who are viewing this thread

Back
Top Bottom