William Benson
vbacreations at gmail.com
Tue Aug 16 11:35:06 CDT 2011
Good reminders ken. I use exactly the approach you advocate for buttonclick events.... most times. Declaring buttonclicked publicly and testing there for screen.activeform.name and screen.activeform.activecontrol.name I get all the control I need to centralize operations. Have to say it is a tradeoff in programmer friendliness. Very hard to read a longer function which branches to many functions amist a lot of others in a standard module...rather than have a proc right in the form's code module clearly related to on-form user interaction. On Aug 16, 2011 12:25 PM, "Kenneth Ismert" <kismert at gmail.com> wrote: >> >> 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 > -- > AccessD mailing list > AccessD at databaseadvisors.com > http://databaseadvisors.com/mailman/listinfo/accessd > Website: http://www.databaseadvisors.com