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