[AccessD] Refreshing open forms when something changes

jwcolby jwcolby at colbyconsulting.com
Thu Jun 23 14:32:45 CDT 2011


OK, I think I understand and my objection to the method is the same as the "twiddle controls" 
method.  Which is that the sender has to know who needs to be twiddled.

This is just ass backwards from event driven programming.

So I understand what you are doing, but I use event driven methods.

In event driven programming, it is not the senders job to keep track of who might need to know that 
the sender did something.  It is just the sender's job to wave a flag saying that it did something.

My understanding of what you are doing is that in your message sender, you have to have a line for 
each place that the message is going.  As an example, my form adds / deletes records in a table.  So 
frm_AfterUpdate would have to have a line in it for every "destination" of the message

sub form_AfterUpdate
   SendMessageToForm "FrmA"
   SendMessageToForm "FrmK"
   SendMessageToForm "FrmZ"
end sub

This certainly works but it runs all of that code about checking to see if the form is open etc, 
parsing events all that stuff.

The event driven method just raises an event

Private Sub Form_AfterUpdate()
     cMsg.send "sfrmVolunteerCities", "frmVolunteers", "RefreshLists"
End Sub

If anyone is sinking the event then they do whatever they do.

Understand that I have specific parameters *in this case* or with this message class where I can 
send any or all of 4 parameters:

1) From
2) To
3) Subject
4) Message

So anyone who wants to listen for messages can do so.  If no one is listening then the only line of 
code to run is the

     cMsg.send "sfrmVolunteerCities", "frmVolunteers", "RefreshLists"

which of course goes out and raises an event.  What I mean is that it really is about 5 lines or so 
by the time the event is raised.

If one form is listening then whatever code is inside of that form's event sink for the message 
class runs.  If two forms are open and sinking events then all the code in each form's event handler 
runs.  Etc.

In any event, I simply do not care what form is open, nor do I have to go discover what form is 
open, nor do I have to generate lists of what form I think might be open in the place that raises 
the event.

I wave my hand.
If you are listening then you do whatever you do when you see my hand waving.

This is called event driven programming and we all use this every day.  Except most of us never 
raise an event, we (most of us) just listen for events.  Of course what I am talking about is 
sinking combo, check box, form events etc.  Every Access programmer knows about that.
	
I just also happen to know how to raise events, and that is a handy trick because I can now wave my 
hand whenever I want.

Event Driven Programming, available now at a programming kiosk near you.  :)

John W. Colby
www.ColbyConsulting.com

On 6/23/2011 1:51 PM, Kenneth Ismert wrote:
> OK ... I was on vacation, and am only now catching up with the AccessD
> posts.
>
> So, I'm just going to ignore the philosophical discussion, and wade in where
> I am almost surely not welcome ;)
>
> Here is how I do this:
>
> 1) Define an interface named IMessage as a standard class:
>
> Option Explicit
> Public Function Message(ByVal MyMessage As String, _
>      ByRef Parameters() As Variant) As Variant
> End Function
>
> 2) Implement IMessage in a form:
>
> Implements IMessage
> Private Function IMessage_Message(ByVal MyMessage As String, _
>      Parameters() As Variant) As Variant
>      ' ... handle message using parameters
> End Function
>
> 3) Send a message to a form, and get a response, using this function in a
> standard module:
>
> Public Function SendMessageToForm(ByVal sForm As String, _
>      ByVal sMessage As String, _
>      ParamArray vParameters() As Variant) As Variant
>
>      Dim rForm As Object
>      Dim vParmValues() As Variant
>      Dim i As Long
>
>      On Error GoTo HandleErr
>
>      SendMessageToForm = Empty
>
>      ' exit if form not open
>      If SysCmd(acSysCmdGetObjectState, acForm, sForm)<>  acObjStateOpen Then
>          Exit Function
>      End If
>
>      Set rForm = Forms(sForm)
>
>      ' exit if form doesn't implement IMessage
>      If Not TypeOf rForm Is IMessage Then
>          Exit Function
>      End If
>
>      ' pack parameter values array
>      vParmValues = VBA.Array()
>
>      If UBound(vParameters)>  -1 Then
>          ReDim vParmValues(0 To UBound(vParameters))
>          For i = 0 To UBound(vParameters)
>              If IsObject(vParameters(i)) Then
>                  Set vParmValues(i) = vParameters(i)
>              Else
>                  vParmValues(i) = vParameters(i)
>              End If
>          Next
>      End If
>
>      ' send message, get response
>      SendMessageToForm = rForm.Message(sMessage, vParmValues())
>
>      Set rForm = Nothing
>      Exit Function
>
> HandleErr:
>      Err.Raise Err.Number, "SendMessageToForm"&  vbCrLf&  Err.Source,
> Err.Description
> End Function
>
>
> This is generic and flexible, and you can easily implement a change
> notification scheme, passing whatever parameters the other forms need to
> sync up.
>
> This needn't clutter up your form code, because the message could be the
> name of a public handler function, which you invoke using Application.Run
>
> Heck, any class can implement IMessage, making it useful for more than just
> forms.
>
> -Ken



More information about the AccessD mailing list