Run-time error 9, "Subscript out of range," is one of those VBA errors that sounds more intimidating than it really is. In plain English, your code asked for something that does not exist. Usually it is an array element, but it can also be a collection item or a key that is missing. It is like reaching for the sixth donut when the box only had five. Disappointing, yes, but at least the problem is fairly straightforward once you know where to look.
A subscript is simply the index or key VBA uses to identify one item in a group. If you have an array with five positions, numbered 1 through 5, then asking for item 3 is perfectly fine. Asking for item 6 is not. VBA cannot retrieve, read, or write an item that was never created, so it stops the code and gives you error 9.
Arrays are probably the most common place Access developers run into this error. An array lets you store related values under one variable name. Instead of separate variables like Color1, Color2, and Color3, you might use one array called Colors with several indexed positions.
For example, if an array is declared with indexes from 1 to 3, the valid positions are Colors(1), Colors(2), and Colors(3). The first valid index is called the lower bound, and the last valid index is called the upper bound. Anything outside those boundaries is out of range.
So if your array runs from 1 through 5, X(5) is valid. X(6) is too high and causes error 9. But do not forget about the other end of the range. X(0) is also invalid because it falls below the lower bound. A lot of people assume their loop counter got too large, and sometimes it did. But it can just as easily be zero, negative one, or some other value below the first valid position.
One of the most common beginner traps involves VBA's Array() function. Arrays created with Array() are normally zero-based. That means an array containing Red, Green, and Blue uses indexes 0, 1, and 2. It has three values, but its highest valid index is 2, not 3.
This is where the classic off-by-one error comes in. You see three items and write a loop that runs from 0 to 3. It works for indexes 0, 1, and 2, then makes one extra trip when the counter reaches 3. At that point, VBA is looking for a fourth item that does not exist. Boom. Error 9.
The best habit you can develop is to stop guessing where an array starts and ends. VBA gives you two functions that do the work for you: LBound returns the lower bound, and UBound returns the upper bound. When looping through an array, use those functions instead of hard-coding values such as 0 to 2 or 1 to 10.
A loop based on LBound(MyArray) To UBound(MyArray) automatically processes every valid item in the array, regardless of whether it starts at zero or one. It also keeps working if you add more values later. Today you may have three colors. Tomorrow you add purple and orange. Let VBA figure out the boundaries instead of trusting your memory, which is usually the least reliable variable in the whole project.
When error 9 appears, click Debug. VBA will normally highlight the exact line that failed. That highlighted line is your best clue. Look for the array index, collection index, or key being requested. Then compare that value with the valid range.
If you are working with an array, the Immediate Window is very handy for this. You can inspect the lower bound, upper bound, and current loop counter to see what is happening. If the array's valid range is 0 through 2 but your loop variable is already 3, you have found the smoking gun.
Dynamic arrays can cause a similar problem if they have not been dimensioned yet. Collections can also produce error 9 when you request an item number or key that is not present. The investigation is still basically the same: what did your code ask for, and does that item actually exist?
One thing error 9 is not is a good excuse to slap On Error Resume Next at the top of the procedure and hope for the best. That is like putting duct tape over the check-engine light. The error may disappear, but the bug is still sitting there waiting to cause trouble somewhere else. Find the bad request and fix the logic that generated it.
So the short version is this: error 9 means VBA was asked for an item outside the available range. Check both the lower and upper bounds, remember that Array() normally starts at zero, and use LBound and UBound so your loops adapt automatically when the array changes.
Once you get used to comparing the requested index with the actual valid range, "Subscript out of range" becomes one of the easier VBA errors to diagnose. Watch the embedded video for the full walkthrough and demonstrations in the VBA editor.
Live long and prosper,
RR