Lost in Translation: runtime multi-language Access apps
Long before "i18n" was a checkbox in every framework, shipping one application that an operator could flip between languages at runtime was real work. This piece, written for Smart Access in 2004, shows how I did it in Microsoft Access: one compiled file, every language living in a table, and the whole interface re-labeled on the fly when the user changes a setting.
The approach holds up. Instead of compiling a separate build per language, all UI strings live in a tblTranslateInterface table keyed by language code. A small translator class walks the open forms and CommandBars and swaps each control's caption, tooltip and status text. Reports are the exception: one already open in Preview is a metafile image, so it can only be translated by closing it and opening it again. Menus are the hard part, because CommandBar controls have no unique name, so I keyed them on the Tag property and searched recursively. Changing the active language re-labels every open form immediately, and every form opened afterwards picks up the new language as it loads.
What dates the article is the stack: DAO, Access 97 through 2002, VBA. What does not is the idea. Keep translatable text out of the binary, drive the interface from data, switch at runtime. This site does the same thing two decades later, on .NET 10 and Blazor, but only halfway: the articles, case studies and services are markdown read from disk at runtime, while the interface chrome is still a string table compiled into the binary. The 2004 version was the more thorough of the two.
The full article, with the complete code and the sample database, was republished by Microsoft and is still online:
Read "Lost in Translation" on Microsoft Learn
Originally published in Smart Access, July 2004, Pinnacle Publishing.