vba

Module Naming

I love talking about naming conventions. Probably because I’ve spent so many years working on them, and I’ve come up with what works well for me, and I’m so friggin sure they’re so awesome, that I just love talking about them. What makes it even more fun is that my conventions aren’t all that conventional… gives me pretty good grounds for babbling on about them. <grin>

I’m not going to go into too much detail on my whole scheme, but there’s one in particular that I’ve been using for some time now, and I love it so much I’m here to share it with whoever’s lucky enough to be reading this.

Modulename.ProcedureName

Yep, that’s it. I’m not sure exactly how many people use this, but I think it’s quite few. In fact, I don’t think I’ve ever seen it “in the wild”, and of the group of MVPs that I blab to a bunch, I think maybe only one or two – if that – use it as well (but I’m working on changing that). So, in 10+ years of programming and listening to however many hundreds of thousands of people talking in forums, I’m going to guess that the usage rate for this is well below 1%.

But anyway, it wouldn’t be much of a blog post if I didn’t try to convince you why it’s so great.

Here’s the thing: any time that a programmer spends thinking about anything other than the immediate task at hand is simply wasted time. Worse even than direct wasted time, this “off thinking” takes us out of whatever zone we might happen to be in, which takes direct wasted time and adds a whole boatload of indirect wasted time, because we have to momentarily leave our train of thought, then try to jump back onto the thing when we’re done. If anyone’s ever tried to jump onto a train, you’ll know it’s a lot harder than jumping off it. Not convinced? Sure, no problem… just go read Armen Stein’s Code of Silence, then go pick up a copy of Peopleware and read that. If you’re still not convinced, don’t bother – you’re not going to gain anything from the rest of this.

So, if you’re still here, I’ll assume you can understand – and can even come to have great respect for, if you don’t already (and you should) – the fact that getting bumped out of a zone is detrimental to productivity.

Next factor: active memory. Not computer memory, but human memory. If you haven’t already, I strongly advise to go pick up a copy of Code Complete (it’s only the best book ever written about software construction). You’ll find that a recurring theme within the book – in fact, you might say it’s the whole point of the book – is that the key to good software construction is reducing complexity.

The more complex things are, the more stuff we have to try and hold in our heads at once. This doesn’t really work well, being that software is very complex, and we simply can’t keep it all in our heads and actually attempt to get work done at the same time (you’ll note, being in the zone effectively removes any thought consciousness except that which is directly related to your zone).

In numerous contexts within Code Complete, it’s stated that studies have shown that 7 tends to be a magical number: the one that, give or take, is the limit to what programmers can remember at any given time about any given thing. If a procedure has more than 7 arguments, try to refactor. If you have to remember more than 7 variables within a routine, refactor. If you have an interface that has more than 7 methods? Refactor. I haven’t specifically tested this myself, by Steve McConnell sure has hell seems to know what he’s talking about, and it makes enough sense to me where I’ll take it as a given. So let’s say that if we have more than 7 things we need to keep in our active memory at a given time, we’re in danger of being kicked out of a zone because we have to force our brains to pull up some other piece of information… sound good? Good.

Wait – we were talking about module names, right? Right.

Class names aren’t much for this discussion… you get an object variable and can only access their properties and methods through the variable, so by default you pretty much have to code this way with classes anyway. Standard modules however…

Not too many people give a whole ton of thought to standard module names beyond: a) picking something that has at least a slight resemblance to what code it contains, b) making sure it doesn’t interfere with an existing module name, and c) making sure that it doesn’t interfere with an existing public procedure name. That pretty much sums up most people’s criteria for naming a module. More so, once that module is named, it’s almost never used again except to pick it out of the left hand list in the VBE.

Let’s talk about procedure names for a minute also… naturally, we tend to name our procedures so that they don’t interfere with other procedures. We don’t worry about it all that much for private procs, because we don’t really care much outside of the context of the current module. Public procedures though, these tend to get a bit more thought. Sometimes we’ll even find ourselves fighting to come up with a good name for them: one that doesn’t interfere with other public proc names, because that’d cause an ambiguation problem.

As a result, we often end up with procedure names that may not be all the semantic (and I’ll take a second to point out that ALL of my naming conventions are heavily based on semantics, because semantics are what ultimately keep us from having to think of things too much, and in turn keep us in the zone: anti-semantics are EVIL. Programming is a language, and we as developers should be able to – without extraneous thought – convey what’s in our heads, what we need to do directly into a flowing computer language. In fact, this transfer should happen without thinking. We’ll think about what we need to do for the task at hand, we’ll think about the environment and the platform and the framework, but we’ll NOT think about how to convey that information into the language of the program itself: that should be done automatically, without thought (7 things adds up fast, this one is entirely unnecessary after a few months working with a given languages (as long as the language doesn’t suck, like PHP (I wonder how many nested side thoughts I can come up with??)))).

Anyway, we come up with these ridiculous function names that aren’t a direct representation of what we need to tell the computer to do. They’re a direct obstacle to something we shouldn’t at all have to actually think about. Hmmm… is that fGetOSUserName or GetOSUserName. That kind of stuff doesn’t do you much good when what you’re really needing to think about is what needs to be done with the user name, not how to get the stupid thing – like flying a plane: always be ahead of it. Writing code in the zone? You’re thinking ahead of it, not stuck on what you named that function.

A theoretical story, then, to FINALLY start talking about why these module names are so important…

Some time back, I was writing code. Let’s say it was a project where I had to perform a number of custom import routines from varying other systems. The kind that aren’t close enough where you can wrap them up into one routine with (7 or less) parameters to define the behavior. Naturally, each of these entirely different import code bases goes into separate modules.

Now, I’m sitting there writing code… or trying to anyway, but what I’m actually doing instead is trying to remember the name of that function that I call to perform the import. You know, if I was smart, I’d just name it ImportFile or something, because that’s exactly what it does… but we can’t have a bunch of ImportFile public functions laying around, right? So, like most people, I end up with: ImportMedentDailyVisitReport, ImportWebPTBillingReport, ImportBlahThisThatWhoCaresTheseNamesSuckBalls.

So there I am, wasting so freaking much time trying to remember the name of this module (“so freaking much time” is like more than 2 seconds to me… doesn’t take much to get kicked off a train). What do I do so I can remember the name? Go to the module, open it, look at the top of the module in the first proc or two where my entry points and public stuff usually is? While that’s a pretty retarded way to do things… why go through that trouble. Now I’m WELL beyond my two seconds: I’m rolling the dirty coughing on dust watching my train go somewhere else without me.

Screw that.

I type in the module name and hit period. Know why? Because this gives me intellisense and shows me exactly what public functions and properties the module has, so I just have to glance in the list, highlight it, CTRL+Left once or twice (with a shift in there) to highlight the module name and dele…

WAIT.

STOP. RIGHT. THERE. (don’t worry, the train’s long gone anyway)

“Self, wtf is this… why are you going to delete that module name?”

“Well, that’s what we do… nobody codes with module names in front of their functions all the time.”

“Self… why not?”

“Well, because…”

“…”

“…”

“Idunno, what if I change it later? My code will break!”

“Dumbass! Listen up… how many times do you go changing table names on a whim? How many times have you looked at a project three months later and said ‘hey, screw that field, I’m changing ya!’ Hm?”

“Ummm….”

“Ummm is right, you don’t know. Pick a halfway decent module name to begin with and you won’t have to change it later. Probably the only reason you’d ever consider changing it anyway is just because you can.”

“Idunno man… that’s like… not normal.”

“Listen dope, you just spend how much time trying to remember a function name? Just got your ass kicked off your train of thought that you owned, and now it’s going to take you how long to find the thing again, let alone get back on it? Because you want to retain the right to change a module name?!?! Here’s what you do: you take yourself outside, slap yourself as many times as necessary then come back in and prove to me that you’re not a hopeless imbecile.”

Somebody give me one good reason that we can’t use a module name as a prefix to fully qualify our function calls.

Protip. You can’t.

SEMANTICS! REDUCTION OF COMPLEXITY!!!! Now you can name every freaking import procedure “ImportFile” and it doesn’t matter! You’re going to qualify it with the module name! Now instead of ImportMedentDailyVisitReport() and ImportWebPTBillingReport() and ImportBlagThisThatWhoCares, we have things that MAKE SENSE! MedentDVR.ImportFile(), WebPTBilling.ImportFile(), ICare.ImportFile() (ok, bad example on the last one, capital I means too much as a prefix for anything, but you get the idea.)

Still doesn’t sound like much though, does it? So, let’s go alllll the way back up to the top (ok, don’t, I’ll do it for you), and take a look at some of what we previously discussed:

  • Getting bumped out of the zone causes major holdups in real, productive work
  • Having to think about too many things at once causes us to get bumped out of the zone
  • Having any sort of block between what we need to convey to the language and how to implement that need within the language is dangerous to the zone

Those are the main points. Let’s see how not fully qualifying procedure calls with module names interferes with those points:

  • When we have to stop and think of a function name for more than a fraction of time, we’re bumped from the zone
  • When we have to stop and think of a function name, we’re almost always running a mental scan of the application in an attempt to try and trigger something that’ll give it to us. That’s usually a LOT more than 7 things, so your train is gone. No helping it.
  • We can’t think ahead of ourselves and code productively because we need to stop and think about function names.

And finally, let’s see how a fully qualified ModuleName.FunctionName helps with those points:

  • Semantic. Your procedure names make sense and your modules are cake to remember. Here’s why: your module names come in two flavors: common, reusable code like DateTime.IsWeekday() or ODBCUtil.ExecutePT(), and task-specific code like WebPTBilling.ImportFile() Now you don’t have to think about 7 things or more – you don’t even have to think outside of the scope of your current task! The common module names you’ll have so memorized in short order that you don’t need to think of it (and intellisense is amazing for quick-picking functions within a module), and the “task at hand” type module names are already part of your allowed 7 memory items because they’re… guess what? Tasks at hand! Brilliant!
  • No longer need to run mental scans of the modules within the app in hopes to trigger what that function name was. No longer try to type it three times before you give up and go look for it. No need to jot it down on a piece of paper so it’s in front of you five minutes later. Just type the module name!
  • And finally, the whole point of this rather lengthy and ridiculous post: you don’t need to stop doing anything to tell your programming language what to do. What you need is conveyed to what you type without having to make a conscious translation! Just keep plugging away without mundane interruptions… SEMANTICS!

There you have it kids. Use fully qualified module names. It’s for the good of you, eh?

So go turn on some Dead and have fun ridin’ that train (however, I’d heed Cash’s advice and leave that cocaine be).

In all seriousness though, I can’t convey enough how much of an impact this tiny little change from the norm has had for me in terms of coding productivity. Simply amazing. You’d never think that such a little thing could make such a difference.

There is one caveat, and it’s very small: if you’re writing function names that are ambiguous across your project’s modules, you will not be able to use them within the Expression Service (eg, queries, control expressions, etc.) because the ES doesn’t allow you to qualify a function name with a module name. This is of very, very little consequence though… the types of functions that tend to have ambiguous names across modules are the types that fit into the second category of modules, the “task at hand” type modules like WebPTBilling.ImportFile() stuff which you’d never call through ES anyway. The common ones don’t end up with the same name due to semantics, but you have the huge added benefit of intellisense support for them now. Win. Win.

I can’t advocate this one enough!

(if you liked this article, thank Patrick Wood – he’s the reason it was written)

Cheers,
-jack

When to use Class Modules in VBA

(this post was pulled from my reply at my iHome at UtterAccess: thread here)

A lot of people struggle with class modules. The more prominent struggle tends to be “how do I use them” (for one of literally thousands of examples out there, check out this UA Wiki article). There’s another hurdle though, one that’s a bit less in the forefront: “when do I use them?” This post addresses the “when to use” scenarios and hopefully can give a bit of insight on what to look for as far as ways to make the best use of custom objects in the Access/VBA world.

It’s tough to say “when” is the best time to use any of the “more advanced” features that Access/VBA offers… knowing when to use them to a greater benefit comes from knowing how to use them, knowing that the tools are capable of doing XYZ, and knowing when the task is better fitted for XYZ than something else… which, if course, is difficult to know if you don’t have a lot of experience with it, so a bit of a catch 22: the more you use them, the more you find places and reasons to use them, but without using them, you really don’t know what you could do with them.

For Class modules, there’s some straightforward enough tell-tale signs that they’d be better suited. For example, when you have a module whose sole purpose is to basically do one single (probably large) task, and the coding is getting unruly (although it’s difficult to define “unruly”), the code itself may be simplified and easier maintained by going into a class module instead of a standard module.

When you have one module that crunches a lot of code to do one particular task, likely the module only really has one main entry (one public sub/function that’s called), usually with a rather long list of arguments, most of which are probably optional, set with a default. So, we have lots of “options” for this particular module, and they’re all stuffed into the main calling point of the main function of the module, and it’s really kind of ugly to look at when you call the function and see a list of 10 or 20 arguments. Something like this may be a good candidate for a Class module, because you could take all those optional settings (and even the required ones), and turn them into properties, then provide a procedure in the class to process everything that’s been previously set. So, you might go to much “cleaner” code, like this:

'in "loaded-function" form:
lngResult = SomeFunction(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg11:="this", arg19="that")
 
' if it were in a class
Dim obj As New SomeClass
 
With obj
  .property1 = "blah"
  .property2 = "blah"
  .property3 = "blah"
  .property4 = "blah"
  .property5 = "blah"
  .property6 = "blah"
  .property7 = "blah"
  .property8 = "blah"
  .property11 = "blah"
  .property19 = "blah"
  lngResult = .RunMe()
  If obj.Errors <> "" Then Debug.Print obj.Errors
End With
 
Set obj = Nothing

A major advantage to having direct control over the properties as opposed to a long argument list, is that now you can individually handle each property assignment, such as wrapping with prepatory functions (.property1 = Trim(” SomeString “)), whereas with a long function call, if you had lots of that type of work to do, you’d have to create variables to hold temporary values, or have an even longer and uglier function call that incorporates all that stuff.

Also, with a Class module in this type of situation, the code itself (the code in the Class), tends to be a lot more organized and maintainable than code which might perform the same task were it all stuffed into a standard module. It’s hard to explain how – one of those things that comes with firsthand experience – but one small example is the built in private procedures of Initialize and Terminate of all VBA class objects. They run all the time when the class is first instantiated and when it is destroyed, and gives you a place to initialize all of those would-be optional, defaulted arguments, and also a place to clean up any loose ends on the way out, when everything’s done. Such initialization and cleanup can be done in a standard module as well, but not nearly so elegantly.

Lebans’ ConvertReportToPDF function is a good example, I think, of a standard module long-signature function that could have been more manageable in a Class module instead. See the image below:

(image broken, sorry)

Much nicer would have been a class interface for this instead:

Dim pdf As New PDFReport
 
pdf.ReportName = "MyReport"
pdf.OutputPDFFile = "C:\ThisFile.pdf"
pdf.StartViewer = False
pdf.FontEmbedding = True
 
pdf.CreateReport
 
Set pdf = Nothing

So, there’s a few cases of how class modules can make your codebase a bit more user-friendly. However, it’s fair to note here that everything mentioned above can be done with Standard Modules also, if not quite so elegantly.

Here’s a case where you want to consider thinking of a Class module, in such a scenario that it might actually make your code safer to run, unlike the above which just makes it a little easier to manage. Let’s say you have a standard module, like above, that does many things with more or less one main entry point. Let’s say it’s really a one-shot deal… you call the function, it crunches a bunch of code, then returns and you’re done, but inside that module let’s say you have lots of module level private variables that are extremely essential to the operation of the task at hand. These *really* need to be correct, or bad things will happen. Then you start thinking about your overall usage requirements for the task itself, and you ask yourself: what would ever happen if this function somehow got called again, before the original was done running… such as maybe from a timer event or from a query… it’s probably not likely, but oh boy would that really make a bad mess of things….

Enter Class modules. Because Classes are instantiated rather than Static (such as a Standard Module), you can create any number of instances of a class and never have any worries that internal variable XYZ might “cross paths” from one instance of the class to another… each instance is self-contained. This is why we can open multiple instances of a form (as explained quite nicely by Allen Browne, if you’re unfamiliar with how), and each instance can have its own data and the forms won’t get confused and accidentally pull data from this other instance instead of the one it’s supposed to.

So, here’s a case where using a class module gives a real, tangible (in the sense of programming, anyway!) plus over standard modules, rather than just making the code a little nicer to work with. This is most especially true when the Class you’re using has a fairly large scope: an instance of it might exist throughout a fairly tall stack of different procedure calls, or maybe even the entire session of the application.

Here’s another one that I made great use of… for my forms, I wanted them all to act the same way. Of course, as a novice we put code behind our forms to make standard behavior happen. As we want our applications to look more professional, we end up doing this same thing in most of our forms, and then we’ve got a lot of duplicate code sitting around in all these different forms. Somewhere around the stage of intermediate, we’ll decide to take all those duplicate codes, and put them into a standard module instead, so there’s just one copy and each form calls that copy instead of having a bunch of different versions scattered throughout the app. Good work. Now, at some point, you’ll run into a case where this function call will require a number of different parameters, and we get what we had in my first example: a huge run of arguments to call the function. Worse though, and the real kicker, is that with one static (standard module) function, you might run into some serious issues if formA and formB get tangled. At the more advanced stage, you say hey, I can make a Class module to handle all this stuff, so the code’s all defined in a single place, and then attach that class module to the form so each for has its own instance…