How to add 'events' to Access form? (1 Viewer)

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
On computer 1 I have an mqtt server, and a C # procedure that 'hears' the commands sent by the clients connected to the server itself, and is able to execute any command
On computers 2 and 3 I have an Access procedure that has to manage the commands received from the mqtt server
I would like to find a way, which excludes polling, to run some vba code when a command arrives in the mqtt server
The question is: how to do the vba code (contained in the procedures on pc 2 and 3) to 'hear' the commands received on the mqtt server?
The ideal would be to add an 'event' to form or control, those available from vba code, to react as soon as possible to a command arrives
A system similar to that created by those libraries that allow communication on the serial port, when characters arrive on the rs232 port an event is triggered to which Access can react
So the question is: how to add a new event to the form that will have to manage the code to be executed?
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 08:49
Joined
May 7, 2009
Messages
19,237
if you are going to use Access, imho,
the server should wite to a table (in access or sql server).
then access, through some timer event read this table.

consult the mqtt documentation on how to interface with msa.
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
if you are going to use Access, imho,
the server should wite to a table (in access or sql server).
then access, through some timer event read this table.

consult the mqtt documentation on how to interface with msa.

The timer event is what I want to avoid
It takes cpu time even when there is no event to serve and also does not ensure the maximum possible reactivity
I would like to be able to run the event management code, exactly at the moment it happens and only at that moment
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Today, 08:49
Joined
May 7, 2009
Messages
19,237
you have misconception of timer event.
on the time you boot your pc, there is already
a timer for each "services" that opens up.

timer that checks whether there is an update for your
windows, for your office, for your anti-virus, your browser, etc.

did you "feel" these timers? i don't think so.

on your situation, i don't know any method of access
that can react to your trigger.
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
you have misconception of timer event.
on the time you boot your pc, there is already
a timer for each "services" that opens up.

timer that checks whether there is an update for your
windows, for your office, for your anti-virus, your browser, etc.

did you "feel" these timers? i don't think so.

on your situation, i don't know any method of access
that can react to your trigger.

You are talking about very different things than I asked for
In my case, the receipt of a message can take place several times per second, and then no longer be necessary even for many hours.
The polling method is never the best when it comes to managing the sequences of events and then there are also long waits
Imagine an rs232 port on which the program is waiting for characters, also in this case it is possible to perform the reception of characters by periodically checking if characters have arrived in the registers of the chip dedicated to the serial port
But it is not the best method, because it would take a lot of computational resources even if no characters are being received
This is why I asked how to add an event to those available as standard on an Access form, to manage the event only when needed and at the maximum possible speed.
Just like the various additional libraries for serial port management currently do
 

Pat Hartman

Super Moderator
Staff member
Local time
Yesterday, 20:49
Joined
Feb 19, 2002
Messages
43,266
What, EXACTLY, do you want this code to do and WHY do you need to execute it on multiple PC's? If the code updates data, you should do the update from the listening event on the server rather than trying to push the action to multiple FE's. If the code is NOT updating data, then your request makes no sense at all.
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
What, EXACTLY, do you want this code to do and WHY do you need to execute it on multiple PC's? If the code updates data, you should do the update from the listening event on the server rather than trying to push the action to multiple FE's. If the code is NOT updating data, then your request makes no sense at all.

On computer 1 I have an mqtt server, that 'hears' the commands sent by the clients connected to the server itself
On computers 2 and 3 i have an Access procedure that has to manage the commands received from the mqtt server

I want to use a different system from the classic periodic query on db for two reasons:
- the events received by the mqtt server on pc1 must be managed as quickly as possible
- there will be very long times in which no command will be received, and therefore I would like to avoid consuming PC1 resources by unnecessarily interrogating the db

Each command received from the mqtt server on pc1 will change the data on the db present on pc1
And in correspondence of this db data changes, it is necessary that the Access procedures running on pc2 and pc3 react immediately

What I would like to reproduce is exactly what any library does for a mqtt client, the library code certainly does not stay in a loop to check if messages have arrived, it simply subscribes to some categories of messages and it is the server that alerts the client only when the receipt of the message to which the client has subscribed occurs

Returning to the Access procedures that run on pc2 and pc3, what I would like to create is a mechanism of the type indicated above, the code inside the procedure subscribes to some events, and then it will be warned (in some way) that the requested event is received
 
Last edited:

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 01:49
Joined
Jul 9, 2003
Messages
16,280
I think you need to look at something called "Raise Events" ....

I suspect you will need to make a DLL file, possibly in C Sharp and register it with MS Access, but I don't really know what I'm talking about!

There are quite a few members here who would possibly be able to help you. The ones that spring to mind are @arnelgp, @MajP, @CJ_London
 
Last edited:

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
Yes, I think it is inevitable to create an ActiveX to be used later with Access
I just have to find a guide to understand how to do it
 

Pat Hartman

Super Moderator
Staff member
Local time
Yesterday, 20:49
Joined
Feb 19, 2002
Messages
43,266
You very carefully explained YOUR solution but I still have no clue what the business need is or why a computer must send a message to the server so the server can force the computer to update its own data.

It sounds like you are storing replicas of a single database on multiple PCs and trying to keep them in sync which sounds pretty odd when you have a server where you can store a shared database that doesn't need to be sync'd.

Access is the wrong tool for this process.
 

The_Doc_Man

Immoderate Moderator
Staff member
Local time
Yesterday, 19:49
Joined
Feb 28, 2001
Messages
27,179
The reason you can't add events to a form in Access is because the events are actually (for the most part) hard-coded in Access, which is a compiled program. The reason your form sees a Current event is because Access goes through the steps of synchronizing a form's controls to the underlying record in the MSACCESS.EXE file's Current event subroutine and, at some time during that software routine, Access CALLS your Form_Current entry point as a second-layer subroutine, probably using a dispatch table. To add an event, you would need to have the Access source code so you could modify it to define a new event that would then - as part of its action - call your new VBA event subroutine and would add a new event slot in the dispatch table.

There might be a few tricks you can play. The idea of building your own C# or C++ variant .DLL would be to create a new class, perhaps, that had some specific events in it. However, there is still the issue of having this handled by Access - which we have already decided doesn't like foreign events.

You have run into the Microsoft non-interference directive - no process may interact with another unwilling parallel process without dire consequences. It's part of an old security standard regarding process isolation for security reasons. The only interactions that can do such a thing would involve WinAPI stuff involving semaphores, and even there you can run into issues. But... there is a possibility.

My advice would be if you wanted to look into WinSocket programming, you could create network sockets and send messages from PC1 to PC2 and PC3 whenever PC1 thinks it should. THEN have forms on PC2 and PC3 that have "listener" sockets established and set yourself up to have those sockets do a blocking i.e. synchronous I/O READ. When PC1 sends out two copies of its message (one each to PC2 and PC3), they can each wake up i.e. satisfy the I/O READ, and dispose of the data in the appropriate manner. That might involve putting the synchronization point in the PC2/PC3 form's Current event after creating a new record to store new data from the previous message. (I'm making assumptions about your process.) When stuff comes in, process it and get it into each of PC2 & PC3 soonest possible. If you trigger the form update operation from the Current routine, you will go through the update-related events normally simply by exiting the Form_Current routine after having triggered the update. If there WAS in fact an update, there will be a following Current event, which then perpetuates the cycle. You can choose any of a dozen ways to end the cycle including PC1 sending a Drop-Dead message or having control buttons on the PC2/PC3 forms. You prevent getting stuck by putting timeouts on the I/O READ and if the status comes back "timeout" you can check the "STOP" buttons or whatever other method you choose to grind this to a screeching halt. If it is NOT time to stop, just jump back and re-issue your I/O READ.

This would work reasonably well as long as you set up the sockets to store & hold messages sequentially, so that if PC1 suddenly sends a burst that is faster than PC2 or PC3 can handle, the network buffers will hold the messages to be delivered sequentially. As long as the messages are not so long and so fast as to blow out the network buffering capacity (which I believe you can control with WinSock connection setup routines), you should not miss anything.

You were concerned about the load involved here. Other than possibly sending a "keepalive" blip every few seconds (30 seconds being typical), there is no load at all on PC2 & PC3 other than the fact that they are in memory. An I/O WAIT state does not execute instructions. The status of PC1 is also at least under you control, in that if you don't have to send anything, don't send it. What else this MQTT server does, I can't address. But if it ain't sending over the socket, all that will be running is the every-30-second keepalive overhead, which usually doesn't amount to much.

This suggestion will work if you can do what is required for the WinSock programming and does not involve ANY new events in Access. Search the forum for issues of using WinSock or other network comm channels. This WOULD be one of those ways where the non-interference directive doesn't come into play, because you would have a mechanism for that interference. It would count as expected interference and thus is OK.
 

MarkK

bit cruncher
Local time
Yesterday, 17:49
Joined
Mar 17, 2004
Messages
8,181
On computer 1 I have an mqtt server, and a C # procedure that 'hears' the commands sent by the clients connected to the server itself
Did you write the C# procedure that hears the server events? Can you make that procedure do what you want?
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
Did you write the C# procedure that hears the server events? Can you make that procedure do what you want?

Yes
I have available the C # procedure that 'sees' all the messages passing through the server
And i can modify it to do other operations
What I haven't been able to do yet is the construction of an activex that 'adds' events to Access so that they can be managed from vba code
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
The reason you can't add events to a form in Access is because the events are actually (for the most part) hard-coded in Access, which is a compiled program. The reason your form sees a Current event is because Access goes through the steps of synchronizing a form's controls to the underlying record in the MSACCESS.EXE file's Current event subroutine and, at some time during that software routine, Access CALLS your Form_Current entry point as a second-layer subroutine, probably using a dispatch table. To add an event, you would need to have the Access source code so you could modify it to define a new event that would then - as part of its action - call your new VBA event subroutine and would add a new event slot in the dispatch table.

There might be a few tricks you can play. The idea of building your own C# or C++ variant .DLL would be to create a new class, perhaps, that had some specific events in it. However, there is still the issue of having this handled by Access - which we have already decided doesn't like foreign events.

You have run into the Microsoft non-interference directive - no process may interact with another unwilling parallel process without dire consequences. It's part of an old security standard regarding process isolation for security reasons. The only interactions that can do such a thing would involve WinAPI stuff involving semaphores, and even there you can run into issues. But... there is a possibility.

My advice would be if you wanted to look into WinSocket programming, you could create network sockets and send messages from PC1 to PC2 and PC3 whenever PC1 thinks it should. THEN have forms on PC2 and PC3 that have "listener" sockets established and set yourself up to have those sockets do a blocking i.e. synchronous I/O READ. When PC1 sends out two copies of its message (one each to PC2 and PC3), they can each wake up i.e. satisfy the I/O READ, and dispose of the data in the appropriate manner. That might involve putting the synchronization point in the PC2/PC3 form's Current event after creating a new record to store new data from the previous message. (I'm making assumptions about your process.) When stuff comes in, process it and get it into each of PC2 & PC3 soonest possible. If you trigger the form update operation from the Current routine, you will go through the update-related events normally simply by exiting the Form_Current routine after having triggered the update. If there WAS in fact an update, there will be a following Current event, which then perpetuates the cycle. You can choose any of a dozen ways to end the cycle including PC1 sending a Drop-Dead message or having control buttons on the PC2/PC3 forms. You prevent getting stuck by putting timeouts on the I/O READ and if the status comes back "timeout" you can check the "STOP" buttons or whatever other method you choose to grind this to a screeching halt. If it is NOT time to stop, just jump back and re-issue your I/O READ.

This would work reasonably well as long as you set up the sockets to store & hold messages sequentially, so that if PC1 suddenly sends a burst that is faster than PC2 or PC3 can handle, the network buffers will hold the messages to be delivered sequentially. As long as the messages are not so long and so fast as to blow out the network buffering capacity (which I believe you can control with WinSock connection setup routines), you should not miss anything.

You were concerned about the load involved here. Other than possibly sending a "keepalive" blip every few seconds (30 seconds being typical), there is no load at all on PC2 & PC3 other than the fact that they are in memory. An I/O WAIT state does not execute instructions. The status of PC1 is also at least under you control, in that if you don't have to send anything, don't send it. What else this MQTT server does, I can't address. But if it ain't sending over the socket, all that will be running is the every-30-second keepalive overhead, which usually doesn't amount to much.

This suggestion will work if you can do what is required for the WinSock programming and does not involve ANY new events in Access. Search the forum for issues of using WinSock or other network comm channels. This WOULD be one of those ways where the non-interference directive doesn't come into play, because you would have a mechanism for that interference. It would count as expected interference and thus is OK.


Yes, the use of a socket for communication is excellent advice
I had not thought about it, and it is probably the system I will use

I must say that during the research, I focused on the construction of a dedicated activex in order to equip pc2 and pc3 with a mechanism to send/receive information to/from pc1
And a first prototype, the classic activex controls, following the examples found on the net, I have already managed to set it up
I only miss the inclusion of the events to which the activex has to react, and which should be 'seen' by the Access vba code
And so, in order to learn something new for me, I plan to continue with the completion of the activex
Although then, for security and reliability reasons, i will probably use the Windows winsock control

For those who have the same problem, I would also like to indicate SimpleSocket library (on spotwise.com), which allows you to activate an udp socket very simply
 

Uncle Gizmo

Nifty Access Guy
Staff member
Local time
Today, 01:49
Joined
Jul 9, 2003
Messages
16,280
in order to learn something new for me, I plan to continue......

This has been one of the most interesting threads I've seen for a while.

I, and I'm sure others, would be very grateful if you would keep us advised of your progress with this project.
 

amorosik

Member
Local time
Today, 02:49
Joined
Apr 18, 2020
Messages
390
Is a program of 2006 of Martin Bergek
I think is only for 32 bit system

Code:
https://spotwise.com/2006/06/08/simplesocket/
 

Users who are viewing this thread

Top Bottom