I have quite a few instances where I start with a basic subform, then I have 3 other subforms which build on it, each adding some different elements to the basic ones. This means that I have a code page for each subform, with lots of repetition. Is it OK to put the common elements into a separate module, and leave only the additional code relevant to each subform on its code page? Are there any performance issues with this?
-
when you say "Class" do you mean Class Module or Form Code Module? – HK1 Apr 26 '12 at 15:48
-
@HK1: I didn't mention 'Class' at all. I had a go setting up a new module for one of the subforms and moving all the repeated code into it, but it didn't work, changes on the other subforms didn't fire the event code properly. – Chelle Apr 27 '12 at 07:54
-
The word "class" does appear in the title. – HK1 Apr 27 '12 at 12:41
-
It might be helpful to know what kind of repeated code you're talking about. – HK1 Apr 27 '12 at 12:42
-
Apologies, didn't look at the title when I reread my question. The list of form code pages appears under the heading 'MS Office Access Class Objects', hence that mention. For the most part the code controls enabled properties, so that associated options are enabled depending on selections in controls. Some sets the options for comboboxes depending on a particular variable. I set up a form with common elements to act as a kind of template then used it to base my other forms on, each adding another handful of controls plus their associated coding. – Chelle Apr 27 '12 at 13:04
3 Answers
Short answer, yes, do it, split out the code that is repeated between each of the forms.
Longer answer, but pulling out the code that is repeated into a separate module or class is, in my opinion, the better way to do it.
Classes make your code more manageable and easier to maintain. If you have code that is similar in multiple places, it makes maintenance more difficult because you have to change it in each location. Having it located in one place makes it easier to manage and maintain.
The list of advantages was taken from a Chicago Access Users Group (CAUG) talk - "Class Modules in Access"
:
Advantages of using classes/objects:
- let's you create more complex objects than tables or queries provide
alone
- using classes within classes let's you restrict function visibility
- class methods & attributes are more descriptive than module's
function list alone
- let's you use Intellisense for more efficient coding
- no "ambiguous name" errors with multiple copies of the same class
module
- can copy class modules without worry of creating ambiguous function
names
- static variables are implicit in class objects, and so are easier to
manage
- isolating access layers within wrapper classes promote
portability/maintainability
- better support for separation of UI/business logic/data access =
n-tier development
- promotes modular thinking in analysis, design
- easier to adapt many publicly-available object models to Access apps
- prepares you for transition to .NET and other fully object-oriented
architectures

- 242,637
- 56
- 362
- 405
-
+1 I'd never taken the time to compare them really before, I use both but have always favoured the standard module over the class but those points are interesting. – Matt Donnan Apr 26 '12 at 12:43
If I'm understanding the question, yes you can centralize a certain amount of code by moving it into a standard code module. There are probably numerous ways you could do this but one of the better ways is to pass in the form object to your functions. Here's an example:
Private Sub Form_BeforeUpdate(Cancel As Integer)
If ValidateContact = False Then Cancel = True
End Sub
'This code goes in a standard code module not associated with any form
Public Function ValidateContact(ByRef frm as Form) as Boolean
Dim bValid as Boolean
bValid = True
If Nz(frm!FirstName, "") = "" Then
MsgBox "First Name cannot be blank."
bValid = False
ElseIf Nz(frm!LastName, "") = "" Then
MsgBox "Last Name cannot be blank."
bValid = False
End If
ValidateContact = bValid
End Function
Also, if I understand correctly you're question is not at all about using Class Modules/Class Objects, at least not explicitly. (In truth, basically every bit of code you write in Access is making use of a class object, most often implicitly.) Another SO user has already posted a great answer about the benefits of using Class objects in Access so I won't expound much more on that. In truth, standard code modules are basically a Singleton class that doesn't have to be instantiated like a class object does. There are reasons why singleton/standard code modules are preferred, at least for some things, if for no other reason than that it's easier to call functions. However, if you find yourself writing functions that have about four or more arguments, you'd probably benefit from changing it to a class object which would allow you to set properties before calling related methods.

- 11,941
- 14
- 64
- 99
Regarding the last part of your question, "Are there any performance issues with this?"
There are 2 consequences I'm aware of:
- form load time
- memory use
As a hypothetical example, imagine you have a form with a tab control. That tab control contains 10 pages, and each page contains a subform. If those subforms include copies of the same VBA code, that common code must be loaded again for each subform. That takes time and increases memory use.
If you move the common code to a standard module and reference it from your subforms, you need load it only once ... reducing both form load time and memory consumption.
So the net result is that the approach you're considering could make your application more responsive ... which may lead to happier users.
However, even if that approach does not yield a noticeable performance improvement, I would still do it anyway because it means you will need maintain only one copy of the common code.

- 95,961
- 11
- 77
- 135
-
Computers do seem to be fast enough these days that the performance problems you mentioned are rarely obvious to the user. +1 for your last line. Code centralization is so important when it comes to future manageability of your code/application. – HK1 May 02 '12 at 14:43
-
@HK1 I have seen Chelle's application. The main form is similar to my "hypothetical" case, and there is a *significant* lag at form load. However, I'm not really disagreeing with your point ... it wouldn't be much of an issue with a less complex form. Anyway sounds like you and I are in complete agreement RE code centralization. :-) – HansUp May 02 '12 at 14:55
-
1I'm still learning new ways to improve on code manageability. It seems like it's a never ending process of learning and refinement. – HK1 May 02 '12 at 15:13
-
I have separated any functions used by all/most of the subforms into a module, and that's fine. This issue is more to do with having four subforms, all with repeated code, BUT only one of these subforms is used in any given instance. My main form acts as a container and only the subforms relevant to that user are called on load. So I take it in this case there is nothing to be gained performance-wise. The form is currently taking about 2 seconds to load. – Chelle May 04 '12 at 13:57
-
OK, I wasn't thinking of that scenario. But yes, you're right ... you won't improve performance. I think the approach you're considering is still worthwhile to avoid maintaining multiple copies of the same code. – HansUp May 04 '12 at 14:07
-
-
1The actual events do still trigger properly, right? Did you try putting MsgBox or Debug.Print in the events in question to see if they fire or not? – HK1 May 05 '12 at 02:12
-
1I've made some changes to the subforms, using nested subforms for the additional elements rather than a complete new subform so that's done away with the repeated code. And instead of loading all the subforms with the load event of the main form as I was doing, I'm loading them with the tab control's change event so performance is much improved now, only one subform being loaded at the start. – Chelle May 11 '12 at 16:19