Calling Proceedure Problem

Laser

Registered User.
Local time
Today, 02:33
Joined
Nov 18, 2009
Messages
26
The following code used to work fine in Access 2003 but refuses to work in Access 2016... Googled many results and tried various suggestions to get the call working but nothing works. Any idea as to the correct syntax I should be using please?

Call Forms.Invoices.InvoiceSearch_AfterUpdate
 
so what does 'refuses to work' mean? you get an error? the code is ignored and nothing happens?

where is the code? and what other code is around it - for example have you disabled error reporting?

For the record, the invoices form needs to be open when you call the function and you also need to change the private to public in the function name
 
...refuses to work...
Can you describe the symptoms of this problem in greater detail? Troubleshooting from "refuses to work" is impossible.
Cheers, :)
Mark
 
Thank you for responding. In order to keep it simple I created two forms. Form1 has a text box with a private sub changed to a public sub which for testing purposes has a message box response.

Form2 just has a command button with the code to call the afterupdate event of the text box on Form1.. Used to work with that same code but refuses to work now.. All I get is Run Time error 438 - object doesn't support this property or method
 
The usual convention uses a bang instead of a dot after Forms
I.e. Forms!Invoice.invoiceSearch_AfterUpdate

However I doubt that this will solve the issue.

Try a roundabout route.
It shouldn't make a difference but I had a case where it solved a similar issue

Create a function with the Call code
Check it works
If it does, then run the function from the button click.
Does it work now?
 
The following code used to work fine in Access 2003 but refuses to work in Access 2016... Googled many results and tried various suggestions to get the call working but nothing works. Any idea as to the correct syntax I should be using please?

Call Forms.Invoices.InvoiceSearch_AfterUpdate

The procedure would need to be changed from the default Private scope to Public to be accessible from outside its own module.

However I am not a fan of directly calling Event Procedures from outside a form. My preference is to create a Public procedure with a name that is meaningful in the Application context then call the Private Event procedure from there.

BTW The Call keyword is not necessary. Calling a Sub actually makes it behave like a function which only becomes evident if it has arguments, causing a lot of confusion about the use of parentheses when there are two or more arguments.
 
Many thanks for looking at my query your suggestions put me on the right track and the call I have found to use is Form_Invoices.InvoiceSearch_AfterUpdate
 
the call I have found to use is Form_Invoices.InvoiceSearch_AfterUpdate

Unfortunately, that piece of bad advice is quite common. It should never be used because it calls the procedure via its module rather than the object.

If the form is not loaded, a hidden instance will load which is indistinguishable from any subsequent instance opened using OpenForm.

Always use what ridders advised, calling via the Forms Collection:
Code:
Forms!Invoices.InvoiceSearch_AfterUpdate
 
Last edited:
Thanks Galaxiom for your input but...

Form_Invoices.InvoiceSearch_AfterUpdate = Works OK

Form!Invoices.InvoiceSearch_AfterUpdate = Does not work! - I get the return "Runtime error 2465 Microsoft Access can't find the field invoices referred to in your expression"
 
Galaxiom made a typo, it should be....
Code:
Form[COLOR="Red"]s[/COLOR]!Invoices.InvoiceSearch_AfterUpdate
You are referencing a named member of the global Forms collection.

This is incorrect...
Form_Invoices.InvoiceSearch_AfterUpdate
...because if the form is not open, this code will open it. That is a bit like leaving a board on the floor with a nail sticking through, pointy end up--an accident waiting to happen.

hth
Mark
 
Has something changed? I saw this and was floored that someone would try to make a form-module's element become PUBLIC.

By default, when you create any form/report event, it is declared as a Private Sub - so OK, first things first, you have to alter the entry point declaration to Public. If you do this for things in a form module, though, you make those things either a property or a method of the form's class module.

The problem (and this HAS been noted in earlier posts) is that if the form is not open at the time you make the call, Access would have to instantiate it and the content might not be property initialized at that time; nor would it be synchronized with its caller when using "back-door" instantiation.

The scope of a variable in a form/report module is ALWAYS Private. Declaring it Public doesn't make it so. It turns it into a property-like entity - for which the dot syntax will work only because you are forcing it to do so. The module's event code, normally declared Private, could also be modified to Public and then called like a method - but remember that some events have automatic arguments like the cases that can use Cancel.

This design is asking for trouble. If it worked in Ac2003, it was because that version was dumber than more modern versions. More to the point, if you are planning to call something from another form or from code launched from a macro, that something should be placed in a general module where Public actually MEANS Public. Calling a Private routine is bypassing the Variable Scope mechanism and is inviting - BEGGING - for a side effect to pop in (using the literally precise program definition of "side effect.")

OK, that came across as a bit harsh and I am not trying to be ugly about it.

Laser, what is it that you are trying to do. DO NOT ANSWER with "Call the form's AfterUpdate routine." That tells us nothing. What is the business effect you are trying to achieve?
 
More to the point, if you are planning to call something from another form or from code launched from a macro, that something should be placed in a general module where Public actually MEANS Public.

I agree with much of Doc's post but I disagree with the letter of this particular comment. I expect he intended different meaning from what he actually wrote.

The defining factor isn't about where a procedure is called from but where the code is applied. If the code is uniquely pertinent to the object then it applies it belongs in the object's module, declared as Public, becoming a Method of the object.

It only belongs in a Standard Module when a procedure is applied to multiple objects. Generally the object or a value would be passed as a parameter.

I would never convert an object's event procedure to Public for all the reasons Doc described.

Just because something works, it doesn't mean it should be used.
 
Following a good nights sleep and digesting the thoughts and comments of people who are obviously far superior to programming than I am. I decided to do away with trying to activate an afterupdate event remotely as good advice indicates that my method would be bad practice. I have this morning adapted the database accordingly and although it was a bit harder to obtain the results I needed, at least I now know that I am following the best advice for a structured database.

So a big thank you to all of those people who were kind enough to devote a little time to helping. It is really appreciated!!
 
Laser, good luck with your project. And may I offer this thought. While of course you have to maintain the code and if it is ugly code to get your desired results, it is still far better to have RELIABLE code than EASY code.

Galaxiom said:
The defining factor isn't about where a procedure is called from but where the code is applied.

True, G... and when and to what it is applied. I.e. the whole context of the situation.

My concern is exemplified in a simple question: Inside the called Event code on that other form, if that code uses Me.xxx, where does "Me" point? To the form holding the code that was called or to the form that called the code? "Me" is a dynamic pointer. Remember that in a general module, "Me" has no meaning, even if the public code was called from a form. So is its value bound at run-time or compile-time?

I would also add this question... when calling that other form's event code, if you use screen.activecontrol.xxx constructs inside that event code, they won't point to the form whose code you are running. Will the code references still work since they are not pointing at the called form?

I actually don't know the answer (and don't care since this isn't something I would do) - but the fact that I have to ask should tell you that there is a potential problem.

To be clear, I have MANY times called one event routine from another IN THE SAME FORM! For instance, due to auditing requirements and a department policy on "tell me twice" for anything that was a "deliverable" event, I did not allow navigation off of a dirty form and the navigation buttons would be disabled in that case. Instead I had command buttons for Save and for Undo (Cancel) and a few other functions. I called the event routine for Undo_Click in order to force a form reset if I detected an error condition that the user would not be able to continue, or a restriction / conflict situation. There were OK-Only message boxes explaining the error, so my users were not totally in the dark. (Then again, we WERE government contractors who were like mushrooms...)

So I am NOT saying to not call one event's code from another event. I am just saying that calling another form's event code is trickier. Mostly due to the context constraints such that "Public" doesn't actually mean "Public" for a form module, and that when you are dealing with implicit instantiation, you are unsure of what the form references. With explicit instantiation and an explicit navigation followed by the call, you would eliminate the issue of uncertainty as to what would be affected.

But as an old fuddy-duddy in programming terms, I still think it is unwise to make that part of your design.
 

Users who are viewing this thread

Back
Top Bottom