tdmsoares
tdmsoares

Reputation: 533

Error Trying to run Procedure from Another Form

I'm trying to call a Sub from another Form, but I get:

Error 2465: Application defined error or object defined error

I already know that to call a procedure from another form I can use the syntax:

 Form(Name).Procedure  

But, in this case I want to refer to this form from a variable (Type Form).

Code from form Parametro_Cadastro:

Dim formCaller As Form
Set formCaller = Application.Forms("Cadastro_Aluno").Form
If (Not formCaller Is Nothing) Then
    '
    formCaller.SetDadosParametroCadastro Me.txtKey.Value, dadoAlterado
    Set formCaller = Nothing
End If

Code from form Cadastro_Aluno:

Sub SetDadosParametroCadastro(ByVal KeyValue As String, ByVal DataValue As String)
    '
    '...
End Sub

The code in Parametro_Cadastro gives Error 2465 on the line:

formCaller.SetDadosParametroCadastro Me.txtKey.Value, dadoAlterado` 

...even before the Sub SetDadosParametroCadastroin the form Cadastro_Alunos to be called.

In the Immediate Window, the variable formCaller is already signed as Form\Form_Cadastro_Alunos as expected.

What can I do in this case?

EDIT

The only way it worked was to assign the variable formCaller to Access.Forms(formName) and not through Application.Forms(formName) or simply Forms(formName), so the code now is like below:

Code from form Parametro_Cadastro:

Dim formCaller As Form
Set formCaller = Access.Forms("Cadastro_Aluno")
If (Not formCaller Is Nothing) Then
    '
    formCaller.SetDadosParametroCadastro Me.txtKey.Value, dadoAlterado
    Set formCaller = Nothing
End If

When I check the variable formCaller in the Imediate Window, I also get (as before) Forms\Form_Cadastro_Alunos. The interesting thing is this only change make the code work as expected. Maybe the Forms member to be called is from Access Object instead of Applications?

Upvotes: 1

Views: 707

Answers (1)

ashleedawg
ashleedawg

Reputation: 21639

Although you can call a procedure from a form, it's generally avoided and is considered bad practice.

Any Sub or Function that need to be shared should be placed in a separate, shared module.


Some excellent advice from Stewart @ Bytes.com:

Form code modules are essentially 'private' in scope. Functions and subroutines defined in them are normally unavailable outside of the form concerned - although it is actually possible to call the functions and subroutines defined as Public in scope within a form code module from outside of that module.

Use of the keyword Public is not just a matter of suddenly adding one as a change of style. It reflects that you wish the subroutine, function or variable to be available outside of the scope of the code module concerned...

The code modules which can be created or opened from the Modules tab are the usual locations of public subroutines and functions. Named modules provide a means of grouping tasks by logical function, and if used consistently can be an aid to maintainability.

I use many several named modules in my applications, separating custom linked table maintenance from username parsing, e-mail handling and so on. I also include a "General" module which contains general bespoke functions that I find useful and re-use across multiple databases (for example, to return the current financial year or the current quarter within it).

All subroutines and functions defined using the Public keyword in the publicly-accessible code modules are available outside of the module concerned, whereas those defined as Private cannot be used outside of the scope of the code module in which they reside.


"If you must..."

If, for some reason, you must call a public sub from a form, the syntax is:

Call Forms!FormName.SubName
  • Note that the sub being called must have the Public keyword specified.

More Information:

Upvotes: 1

Related Questions