> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Distributing One-Time Data "Hot Fixes"
- URL: https://nolongerset.com/distributing-one-time-data-hot-fixes/
- Published: 2022-07-08T21:35:21.000Z
- Updated: 2026-05-08T12:56:29.000Z
- Description: Rolling out changes to *production data* when you don't have direct access to that data can be tricky. This tip makes the process easier.
- Author: Mike Wolfe
- Tags: Deployment, Defensive Programming, #Import 2026-05-20 02:59

Fixing *production client* *data* for a subset of a large user base is a tricky problem.

For example, we support about 75 tax collectors spread across four counties in Pennsylvania. We prepare their annual tax data files which include billing information for all the taxpayers in their district. Occasionally, we realize after sending out the data files that we made a mistake in the files for some of the collectors.

So how do you distribute a **one-time** data fix to **multiple users** without impacting **unaffected users**?

## The `ApplyHotFixes()` Routine

At startup, our tax collection software calls the following routine:

```vba
Sub ApplyHotFixes()
    On Error GoTo Err_ApplyHotFixes

    If NeedsHotFix8335 Then ApplyHotFix8335
    If NeedsHotFix8044 Then ApplyHotFix8044
    If NeedsHotFix7668 Then ApplyHotFix7668
    If NeedsHotFix6484 Then ApplyHotFix6484

Exit_ApplyHotFixes:
    Exit Sub
Err_ApplyHotFixes:
    Select Case Err.Number
    Case Else
        LogErr Err, Errors, "tcHotFixes", "ApplyHotFixes", elHide
    End Select
    Resume Exit_ApplyHotFixes
End Sub
```

The routine goes through a series of checks to see whether the current user's data file requires a particular hot fix. If it does, the hotfix gets applied.

If there is an error within any of the calls, the error gets logged via the `LogErr` call (either to a local text file or to FogBugz via the BugzScout feature). The `elHide` parameter is an error logging enumerated value that tells the `LogErr` function not to display the error to the user. I include this to avoid an unexpected error message annoying the user on every startup. 

This entire routine runs in under a tenth of a second almost every time it's called.

## Key Objectives: Speed and Safety

In test driven development, the first step is to create a failing test.

We treat the `NeedsHotFix####` function the same way here. It should return **True** before running the associated `ApplyHotFix####` routine and return **False** after that routine runs.

Once we confirm it works the way we expect, we can put it in place to act as a gatekeeper for the `ApplyHotFix####` routine.

### Achieving Speed

Rather than running an expensive query to check whether a problem exists in the data, **I start with a series of very fast guard clauses**. 

The goal is that these checks will disqualify the data environment without having to run the query in the first place. Here's an example of what that looks like in practice:

```vba
Private Function NeedsHotFix8335() As Boolean
    If Duplicate.TaxDistrict <> td_BermudianSpringsSD Then Exit Function
    If App.G.Year <> 2020 Then Exit Function
    If App.G.CountyID <> C.CountyID.Adams Then Exit Function
    If Duplicate.EntityType <> et_School Then Exit Function
    If ECount("*", "Receipts", "(BillID=146128) AND (ReceiptID=1) AND (TCReceiptID=3117)") = 0 Then Exit Function
    
    NeedsHotFix8335 = True
End Function
```

I start out with four extremely fast-executing checks that will fail for most circumstances. I run them in order from fastest to slowest to execute. The first four have similarly fast execution speeds. As a tie-breaker, I start with the most restrictive check (i.e., the one most likely to return True in the greatest number of situations).

Only after all four instant checks pass do I finally use Allen Browne's [ECount() function](http://allenbrowne.com/ser-66.html) to look inside the data to see if the hot fix needs to be applied.

### Achieving Safety

Within my `ApplyHotFix####` routines, I try to *rely as little as possible* on the `NeedsHotFix####` routine being run first.

For example, I use the most restrictive WHERE clause I possibly can so that if somehow the ApplyHotFix#### routine gets run accidentally it doesn't ruin someone's day. Here's an example of that:

```vba
Private Sub ApplyHotFix8335()
    Dim SQL As New clsSQL
    SQL.From = "Receipts"
    'This hot fix should only be applied to a single record 
    '    in the Bermudian Springs school district file
    SQL.Where = "District='10'"
    SQL.AndWhere "SchoolDist='B'"
    SQL.AndWhere "BillID=146128"
    SQL.AndWhere "ReceiptID=1"
    SQL.AndWhere "TCReceiptID=3117"
    SQL.SetValue "TCReceiptID", 1003117
    SQL.Update
    Debug.Print SQL.RecordsAffected
End Sub
```

In my development environment, I would run the above routine a few times to confirm that (A) it only changed the number of records it was supposed to on the first run and (B) it did not change any records on subsequent runs.

### Sample Execution

*Note: In the screenshot below, I did not switch the routine signatures to make them `Public`. By fully qualifying the routine name of a Private Sub or Function you can [call it from the Immediate Window](https://nolongerset.com/debugging-private-procedures/)! Try it, it really works (you will have to type the name out...IntelliSense won't autocomplete a private routine).*

![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2022/07/image-8.png)

## High Signal to Noise Ratio

I use the `NeedsHotFix####` and `ApplyHotFix####` naming conventions because they convey a lot of information in a very compact format.

The number that gets appended to each routine name corresponds with a case number in our FogBugz database. I can highlight the number then press \[Ctrl\] + \[Win\] + \[F\] and my browser will immediately open to the case information associated with that number. 

The FogBugz case provides way more detail and context than I would ever consider putting into a code comment.

*(If you're curious how the \[Ctrl\] + \[Win\] + \[F\] trick works, it's very similar in concept to the \[Ctrl\] + \[Win\] + \[G\] AutoHotkey shortcut that I describe in [this article](https://nolongerset.com/a-mind-reading-script/).)*

---

### Referenced articles

[Debugging Private ProceduresAfter more than 14 years as a VBA developer, I recently discovered that you can debug private procedures without temporarily making them public!![](https://nolongerset.com/favicon.png)No Longer SetMike Wolfe![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2021/05/monkey-thoughts.jpg)](https://nolongerset.com/debugging-private-procedures/)

[A Mind-Reading ScriptWhat if you could highlight any text, press a hotkey, and have Windows do what you want almost every time? You’d have my top productivity hack.![](https://nolongerset.com/favicon.png)No Longer SetMike Wolfe![](https://storage.ghost.io/c/eb/d7/ebd732c1-5f03-4f07-b386-5d08557e15c9/content/images/2020/10/psychics-1026092_1920.jpg)](https://nolongerset.com/a-mind-reading-script/)

### External references

[Microsoft Access tips: Extended DCount()Code to count the number of records in a table/query in Microsoft Access, with the option to count the number of distinct values. A replacement for DCount().![](http://allenbrowne.com/favicon.ico)](http://allenbrowne.com/ser-66.html)

*Image by [zoli gy](https://pixabay.com/users/zoli2003-2323971/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=1303313) from [Pixabay](https://pixabay.com/?utm%5Fsource=link-attribution&utm%5Fmedium=referral&utm%5Fcampaign=image&utm%5Fcontent=1303313)*