The Dependency Train

Let's torture a train metaphor to illustrate the dangers of dependency chaining.

The Dependency Train

When you write your first Access application, you will be writing most of your code from scratch.  When you write your second application, you will find yourself copying and pasting functions and subroutines from your first application into your second.  By the time you get to your third application, you will likely start grouping those procedures into standalone code modules.  And by the time you get to your fourth application, you'll realize that you should probably start maintaining your most common code modules in a standalone location apart from your projects.

Congratulations, you now have the start of a code library.

Building a code library

If you follow my approach, your code library will consist of a Windows folder full of exported code modules and maybe a few form or report objects, too.  As you build out your library, you should keep similar procedures grouped into code modules.  For example, here are a few of my well-worn modules:

  • Compression.bas
  • ErrorMod_vbWatchdog.bas
  • FileFunctions.bas
  • StringFunctions.bas
  • ImageFunctions.bas
  • ProgressMeters.form
  • iRepresentation.cls

All told, I currently have over 130 separate standard modules, class modules, forms, macros, and reports in my code library.  About a dozen or so are modules that I include in every one of my projects.  However, the vast majority are modules that I may only use in a handful of projects, depending on how specialized they are.  In addition to making my code library easier to manage, it also helps keep my front-end file size down.

Loose coupling

When developing code, you generally want it to be "loosely coupled."  In the context of a code library, that means you want to reduce the number of interdependencies among your modules.  However, there are likely functions in one of your library modules that you will want to call from another library module. For example, I have several procedures in my FileFunctions module that call functions in my StringFunctions module.

In my FileFunctions module, I wrote a PathJoin() function.  Here is an excerpt from that function:

PathJoin = Conc(PathJoin, Component, "\")

In this example, the FileFunctions module is dependent on the StringFunctions module because the Conc() function belongs to the StringFunctions module.

The Dependency Train

Let's torture a train metaphor.

Let's say that each train car represents a code module in your code library.  Each seat on the train represents a function within that module.  And the literal couplers between train cars represent the figurative coupling between code modules.

Now, imagine that you need to use a single function from a single module in your code library.  So, you import that code module into your application.  Your train is now one car long.

Following the import, you compile the code to make sure you're not missing any dependencies.  Sure enough, there is a problem.  The module you just imported won't work unless you also import a different module.  

Funnily enough, the compile error has nothing to do with the one function you need.  Rather, it is a different function in the module that has the dependency.  It doesn't matter.  The only way to get the code to compile is to import the other module.  Your train is now two cars long.

It turns out the second module you imported calls procedures in two other modules in your code library.  You import those two modules.  Your train is now four cars long.

The third module you imported calls procedures in another module, but luckily it's one that we already imported.  Unfortunately, the fourth module calls procedures in four modules, only one of which has already been imported.  That means you need to import three more modules to get your project to compile.  Your train is now seven cars long.

A better way?

To recap, we wanted to use a single function in our project.  We imported the module that had that function.  Through a chain of dependencies we had to keep importing additional modules.  We're now up to seven code modules and counting.

I thought adding a code library was supposed to simplify things?  This seems anything but simple.

This was a very common issue for me when I first started building my code library.  I dealt with the issue in a variety of ways.  I'll cover a few of those techniques in my next article.

Image by Daniel Nebreda from Pixabay

All original code samples by Mike Wolfe are licensed under CC BY 4.0