Looking for Correct Snbtax (1 Viewer)

David44Coder

Member
Local time
Today, 16:36
Joined
May 20, 2022
Messages
109
Gee you can spend hours trying to work this out the simplest thing sometimes.
I have a function DoDur in frmMain I want to call from a Module
Code:
m = Forms("frmMain").DoDur(i)
What's wrong with that ? ! Access says Application—defined 0r object-defined error
Also I don't get it in the drop down list as expected.

Many thanks for any help.
 

June7

AWF VIP
Local time
Yesterday, 19:36
Joined
Mar 9, 2014
Messages
5,399
Is DoDur declared as Public?

Why isn't function in a general module?
 

David44Coder

Member
Local time
Today, 16:36
Joined
May 20, 2022
Messages
109
Yes it is public. Why do you ask why it's not in a Module ?
 

June7

AWF VIP
Local time
Yesterday, 19:36
Joined
Mar 9, 2014
Messages
5,399
Public procedures in a general module are easily available to any other module. However, I have done what you are attempting.

So, is frmMain open?

If you still need help, suggest you provide db for analysis. Follow instructions at bottom of my post.
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 14:36
Joined
Jan 20, 2009
Messages
12,847
Try this;
Code:
m = Form_frmMain.DoDur(i)
 

KitaYama

Well-known member
Local time
Today, 12:36
Joined
Jan 6, 2022
Messages
1,478
I always do it this way :

Code:
    If IsLoaded(MyForm) Then
        Forms(MyForm).SetFocus
        ReturnVal = Forms(MyForm).MyFucnctionName
    End If
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 22:36
Joined
Feb 28, 2001
Messages
26,946
1. IF the function is (a) in a general module and (b) is declared PUBLIC and (c) its name is unique within the project), just call it (DoDur(i)) from anywhere within that project with no prefix needed to qualify its location (which is why you declare it as PUBLIC). Just call it by its unique name. However, ... if the function name is not unique, then shame on you for poor planning.

2. IF the function is declared elsewhere in the class module of the same form from which you are calling it, again just call DoDur(i). In this case (call from same form/class module) it does not matter whether you declare it public or private. It should be visible to you.

3. If the function is declared in a different class module than the one from which you are calling it, but still is defined PUBLIC, try directly referencing it without qualifiers, i.e. just plain DoDur(i). NOTE, however, that KitaYama's test for the form's activation is the right idea in that specific case, see below for why.

If the function declaration is in a class module associated with another form, you run the risk of the function not being loaded at the moment because the class module is linked intimately to the form. This risk and its consequences are high enough that you should change the structure and location of the function so that it resides in a general module. General modules are available within the project for as long as the project is open.

There are pitfalls within this "general module" suggestion: The function should not reference things from within its code that would be local to the class module other than the input parameter. In a general module, the local variables of the class module are NOT within scope, i.e. not visible.

This idea, referencing local variables not declared within the function, is called a SIDE EFFECT and is to be vigorously avoided. Things break easily when you allow side effects to creep in.

A further warning is appropriate: IF you qualify the reference (i.e. form.DoDur(1) ) AND the function is not loaded because the form & class module are ALSO not loaded, I believe there is a chance that you would instantiate the form anyway, simply by referencing it in the qualifier. However, any form-based variables would be loaded according to that form's _OPEN, _LOAD, and _CURRENT events for whatever is the first record loaded when the form loads, with no synchronization between what you are doing and that suddenly-instantiated form. I'm not sure on that auto-instantiate, but I recall some discussion on that a couple of years ago. If it happens, it is probably not a good thing.
 

June7

AWF VIP
Local time
Yesterday, 19:36
Joined
Mar 9, 2014
Messages
5,399
When calling a procedure behind a form from some other module (class or general) the call must use the form prefix AND the procedure must be declared PUBLIC. If the form is not open, code will simply error, there is no 'instantiation'. All tested.
 

Gasman

Enthusiastic Amateur
Local time
Today, 03:36
Joined
Sep 21, 2011
Messages
13,964
Why not just do it the 'normal' way?
Put the function in a module, and call that from the form and elsewhere?
 

David44Coder

Member
Local time
Today, 16:36
Joined
May 20, 2022
Messages
109
The suggestion to put the function into a module was certainly doable but I wanted to find why I couldn't get it working where it was. It was already in use as click event in the Form. I did use the syntax shown by Galaxiom in msg 6 but wanted to avoid the underscore.
Yes, frmMain was Open. I also used successfully the example from KitaYama but didn't have an IsLoaded Function (until getting one on line). Should I have?
Now I find the instruction in msg 1 DOES work. Why it didn't yesterday I'll never know. It wasn't a case of the Form being closed as that (now) shows Microsoft Access cannot find the referenced form 'frmMain'. A different error.
Anyway I'm much better informed, so many thanks, particularly Doc_Man.
 

Gasman

Enthusiastic Amateur
Local time
Today, 03:36
Joined
Sep 21, 2011
Messages
13,964
I seem to recall a user over on AF had lots of problems trying to execute a form module from outside the form?
TBH, I feel if it is meant to be public, it should be in a code module.
What happens in Forms stays in Forms :)
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 22:36
Joined
Feb 28, 2001
Messages
26,946
When calling a procedure behind a form from some other module (class or general) the call must use the form prefix AND the procedure must be declared PUBLIC. If the form is not open, code will simply error, there is no 'instantiation'. All tested.

Regarding the fine point of calling across class modules, I recall we (not you and me, but the forum) had a long discussion on this subject several years ago. I firmly believe in this case the correct answer is "move the function to a general module." I DID make the point that I wasn't sure about auto-instantiation. If you read the MS Online help about functions, they are ambiguous about PUBLIC declarations in a class module.
 

Pat Hartman

Super Moderator
Staff member
Local time
Yesterday, 23:36
Joined
Feb 19, 2002
Messages
42,872
If a function is intended to be used by multiple forms, it belongs in a general module which is always accessible. Pass in a form reference if you need to. As everyone has pointed out, code in a form is only available when the form is open.

Also, forms don't store data. Tables store data so the logic of using a procedure in a form this way escapes me.
 

Users who are viewing this thread

Top Bottom