I agree but sometimes it would be easier to locate a public sub in a form when the sub needs values from that forms' own fields. So reference woulbe be much easier.
I'm trying your suggestion:
Call Forms!ProjectKondicioTar.Test
But I get an error message: compile error: expected . or (
I would use a Module and With CodeContextObject you aviod referencing the Form or Report although SubForms have to be specified with the Parent / Form or Report expressed by a [Dot].
I would use a Module and With CodeContextObject you aviod referencing the Form or Report although SubForms have to be specified with the Parent / Form or Report expressed by a [Dot].
Shared code belongs in Modules and Classes, not on Forms or Reports.
With Forms I understood that Subroutines are actually Events of the Form. In other words, live code which will fire if the Form receives the particular event. I doubt you really intend for so much behavior overhead with your shared subroutine. Perhaps the same is true of Reports.
That is code on the subform reaching around through the parent form back to itself! Simply referring to Me the subform was not good enough as the subform control had lost focus when the button was pushed on the main / parent form.
The reference with the underscore is a call directly to the class module rather than the instance of the object. It becomes ambiguous when there are multiple instances of the class.
Call is mainly used to refer to a function when a return value is discarded. Access is expecting the "(" with Call because it is expecting a function. BTW If you put parentheses around a single parameter when passing parameters to a Sub it will be forced to pass ByVal regardless of the argument declaration in the Sub.
I use custom methods on forms all the time. Anyone who doesn't is not structuring their code very well.
An example. A subform requires the Enabled property of buttons to be set depending on the state of something in the main form. If you are using this code then you are doing it clumsily.
Code:
If whatever Then
With Me.subform.Form
.button1.Enabled = False
.button2.Enabled = True
etc
Add the state setting as a public sub on the subform object itself.
Code:
Public Sub ButtonState (ByVal Enable as Boolean)
With Me
.button1.Enabled = Enable
.button2.Enabled = Not Enable
etc
The above may work but it may not work as intended.
If the Form is Open then PublicSubName is called.
If the Form is closed an instance of the Form is opened with Visible = False. If the Form has Open and/or Load events they are called before the PublicSubName. The Form then remains Open but invisible and it is not in the Forms collection. Any subsequent calls to PublicSubName work without creating a new instance of the Form.
We can then open another instance of that Form from the database window and that Form will be visible. If we close the visible Form then its Unload and/or Close events will fire, if they exist. Then the invisible Form will close and fire its Unload/Close events if they exist.
There would be many different ways it could produce unexpected results.
So yes, Form_frmName.PublicSubName does work; but do we really want it to work that way?
If, after all that, you still wish to call a public procedure in a closed Form then this would probably be better:-
Code:
Sub TestIt()
Dim frm As New Form_frmName
frm.PublicSubName
End Sub
Here, again, the Open and Load events would run before PublicSubName is called.
The advantage is that the variable frm, used to reference the new instance of Form_frmName, will automatically get set to Nothing when it goes out of scope. When it gets set to Nothing the instance of the Form will be closed which will call the Unload and Close events if they exist.
That will at least mean that the instance of Form_frmName will not be left dangling somewhere not knowing if it is open or closed.