[AccessD] Call an event in another form

Kenneth Ismert kismert at gmail.com
Tue Aug 16 11:24:08 CDT 2011


>
> William Benson:
> Lately I have been calling functions from most events.
>
> Private Sub SaveRecord_Click()
> Call SaveRecord
> End Sub
>
> Public Sub SaveRecord()
> 'Do the stuff SaveRecord_Click() would do
> End Sub
>
> And based on this I seem to be able to call it easily from any form
>
> 'In some other form
> Private Sub
>     Call Forms("OtherForm").SaveRecord   'As long as OtherForm  is open
> End Sub
>

I like William's approach better. My reasons:

 * The fact that events are private by default is a strong suggestion that
they should be used only by the form that owns them.
 * Making an event public is not a clear signal to other programmers
(including your future self) that the event is serving dual-purposes. It is
all too easy to remove or repurpose the event, breaking the external
dependency. When I see this in code, I count it as a mistake.
 * An explict public method like 'SaveRecord' looks much more deliberate,
and its purpose and availability for external use is much more likely to be
properly understood and used.

But, William's approach has issues, too:

 * Call Forms("OtherForm").SaveRecord is a late-bound call. You can remove
or rename the SaveRecord method, and the project will compile. But it will
fail at runtime.
 * I begin worrying about form state in these circumstances. While a target
form's public methods can be called at any time by external code, the form
probably won't be able to handle these calls gracefully in all
circumstances. These failures are only found at runtime, and almost always
by the end user.
* You have to explicitly add 'SaveRecord' support for each form that
requires it. Because the support is scattered, the tendency is to fix
problems piecemeal on a form-by-form basis, rather than generalizing a
solution for all forms in a central place.

My recommendations:

 * Ideally, forms should have no public methods, and only take care of
themselves. While this is not completely achievable in practice, striving
towards it reduces the interdependencies in a project, making it more
predictable and dependable.
 * One approach is to standardize handing of forms by using form handling
functions in a public module. So, a better approach might be:

' in modAccessForm
Public Sub SaveRecord(ByVal rForm As Access.Form)
    ' all logic to generically save a record and handle all special
conditions and exceptions
End Sub

' somewhere else
modAccessForm.SaveRecord(Forms("OtherForm"))

This way, you can manipulate any form using it's public methods, which is
OK. This approach has several benefits:
 1. You accumulate all logic to handle special conditions and exceptions in
one place, which benefits the project everywhere the function is used.
 2. You start thinking about using forms in a modular, uniform way, which
simplifies your project, and makes it more flexible.

Breaking a form's privacy with public methods should be done carefully.
Abusing this rule contributes to unreliable, unmaintainable projects.

-Ken



More information about the AccessD mailing list