LLTranslation
Manages the translation ListObjects that sit on one worksheet and hands out a TranslationObject per scope. TransObject answers the object of one scope, Refresh drops what is held, Import and Export move whole translation tables between workbooks, ImportDictionary and ExportDictionary move the setup translation table on its own, and InitialiseHiddenNames writes the translated configuration values into a workbook as hidden names.
WHAT THE FIVE TABLES HOLD
Four of them translate the linelist itself: T_TradLLMsg the messages, T_TradLLShapes the button captions, T_TradLLForms the form labels and T_TradLLRibbon the ribbon labels.
Tab_Translations is the SETUP's translation table, which is a different thing from the linelist dictionary. The setup file carries it, InitTransfer copies it onto the linelist's copy of this worksheet while the linelist is being built, and it is what translates the dictionary, the choices and the analyses. ImportDictionary is the copy in and ExportDictionary the copy out: a data export from a linelist carries this table on its own.
THE FIVE TABLES ARE ALL REQUIRED
Create asks for all five. The designer template ships every one of them, so a sheet missing one is a broken sheet and the failure is raised at creation.
WHERE THE LANGUAGES LIVE
The two language codes live in workbook-level hidden names, RNG_LLLanguageCode and RNG_DictionaryLanguage, on the workbook that holds the translation worksheet. TransObject reads them there and raises when the code it needs is empty.
WHAT IS HELD IN MEMORY
The hidden name store and the five scoped TranslationObjects are built once per instance. Building the store walks every Name of the workbook, and each TranslationObject holds its own copy of its table, so a caller that keeps this instance keeps both. Refresh drops all of them. The two import routines drop the scoped objects themselves, and a caller that writes into a translation table by any other route calls Refresh.
Depends on: TranslationObject, CustomTable, HiddenNames, Checking
Version: 1.2 (2026-07-30)
Factory
Create #
create
Create a new LLTranslation from a translation worksheet
Signature:
Public Function Create(ByVal translationSheet As Worksheet) As LLTranslation
Instance creation via VB_PredeclaredId factory pattern.
Validates that the worksheet is not Nothing and that all five translation ListObjects are present (T_TradLLMsg, T_TradLLShapes, T_TradLLForms, T_TradLLRibbon, Tab_Translations).
Parameters:
translationSheet: Worksheet. The worksheet hosting all translation ListObjects.
Returns: LLTranslation. A facade over the five tables.
Throws:
- ProjectError.ObjectNotInitialized When translationSheet is Nothing.
- ProjectError.ElementNotFound When a required ListObject is missing.
Properties
Wksh #
wksh
Host translation worksheet
Signature:
Public Property Get Wksh() As Worksheet
Accessors for translation objects and the host worksheet.
Returns the worksheet bound to this instance.
Returns: Worksheet. The host translation worksheet.
TransObject #
trans-object
Scoped translation object
Signature:
Public Property Get TransObject(Optional ByVal trans As Byte = TranslationOfMessages) As TranslationObject
Returns a TranslationObject configured for the requested translation scope. The language code is resolved from the hidden names of the workbook holding the translation worksheet: RNG_DictionaryLanguage for the dictionary scope and RNG_LLLanguageCode for the other four.
Each scope is built once and kept. Refresh drops the five.
Parameters:
trans: Optional Byte. TranslationScope value selecting the content scope. Defaults to TranslationOfMessages.
Returns: TranslationObject. The translation object for the requested scope.
Throws:
- ProjectError.InvalidArgument When the scope is outside the enum.
- ProjectError.ElementNotFound When the requested ListObject is absent from the host worksheet, or when the language code the scope needs is empty.
Refresh #
refresh
Drop everything this instance holds in memory
Signature:
Public Sub Refresh()
Clears the hidden name store and the five scoped translation objects, so the next read builds them again. Call it after a name is deleted and added back on the workbook, and after writing into a translation table by any route other than this class.
DataExchange
Export #
export
Export all translation tables to an output workbook
Signature:
Public Sub Export(ByVal outputWkb As Workbook, _
Optional ByVal Hide As Long = xlSheetVeryHidden)
Import, export, and dictionary exchange operations.
Creates or empties a worksheet in the output workbook matching the host sheet name, then exports every ListObject from the host sheet using CustomTable.Export with stacking. Formats the used range and sets the sheet visibility to the Hide parameter value.
Tab_Translations is written LAST, under the other four. InitTransfer overwrites it with the setup's own table as soon as the sheet has arrived, and CustomTable.Import writes the incoming rows over the cells below the table rather than inserting them. Anywhere but the bottom of the stack, a setup table with more rows than the designer carries would land on the table below.
Parameters:
outputWkb: Workbook. The destination workbook.Hide: Optional Long. Sheet visibility after export. Defaults to xlSheetVeryHidden.
Throws:
- ProjectError.ObjectNotInitialized When outputWkb is Nothing.
Import #
import
Import translation tables from another workbook
Signature:
Public Sub Import(ByVal fromWkb As Workbook)
Finds the worksheet in the source workbook carrying the host sheet name, and for each ListObject on the host sheet imports the data of the matching ListObject on that source sheet. A table the source does not carry is left standing.
Tab_Translations used to be emptied here before the loop had discovered whether the source carried a replacement, and it was emptied through a CustomTable with no key column, which takes the tag column with the rest. A source without Tab_Translations left the setup translations blank with nothing to write them back.
Parameters:
fromWkb: Workbook. The source workbook containing translation data.
Throws:
- ProjectError.ObjectNotInitialized When fromWkb is Nothing.
- ProjectError.ElementNotFound When the source workbook carries no worksheet of the host sheet name.
ImportDictionary #
import-dictionary
Take the setup translation table onto the host worksheet
Signature:
Public Sub ImportDictionary(ByVal dictionaryTable As ListObject)
Overwrites Tab_Translations with the supplied ListObject, which is the translation table of the setup file. The host table takes the source column headers with keepSourceHeaders, so it comes out carrying the language columns the setup carries. InitTransfer calls this on the LINELIST's translation sheet while the linelist is being built, and what lands here is what translates the dictionary, the choices and the analyses. The designer's own translation sheet is never written this way: its four linelist tables are maintained by hand, through the designer's import button.
Parameters:
dictionaryTable: ListObject. The setup translation ListObject.
Throws:
- ProjectError.ObjectNotInitialized When dictionaryTable is Nothing.
- ProjectError.ElementNotFound When the host dictionary table is not found.
ExportDictionary #
export-dictionary
Write the setup translation table onto a worksheet of an output workbook
Signature:
Public Sub ExportDictionary(ByVal outputWkb As Workbook, _
Optional ByVal sheetName As String = "Translations", _
Optional ByVal Hide As Long = xlSheetVisible)
Creates or empties a worksheet in the output workbook with the given name, then exports Tab_Translations using CustomTable.Export. Formats the used range and sets the sheet visibility.
LLExporter calls this when a user exports data out of a linelist. Of the five tables, this is the one that travels: it is what lets the exported dictionary and choices still be read in the language the user picked.
Parameters:
outputWkb: Workbook. The destination workbook.sheetName: Optional String. Worksheet name for the export. Defaults to "Translations".Hide: Optional Long. Sheet visibility after export. Defaults to xlSheetVisible.
Throws:
- ProjectError.ObjectNotInitialized When outputWkb is Nothing.
- ProjectError.ElementNotFound When the host dictionary table is not found.
Internal members (not exported)
Factory
Seal #
seal
Seal the instance against further creation-only writes
Signature:
Public Sub Seal()
InternalSheet #
internal-sheet
Friend setter for the host worksheet
Signature:
Friend Property Set InternalSheet(ByVal value As Worksheet)
Used by the factory method during construction. Writing to it after Create raises, so the cached hidden name store and the cached translation objects can never point at a worksheet the instance has given up.
Parameters:
value: Worksheet. The translation worksheet to bind.
Throws:
- ProjectError.SomethingWentWrong When the instance is already sealed.
WorkbookNames #
workbook-names
The hidden name store of the workbook holding the translations
Signature:
Private Function WorkbookNames() As HiddenNames
Built once per instance. Building one walks every Name of the workbook.
Returns: HiddenNames. The workbook-level store.
Internal Helpers
BuildScope #
build-scope
Build the translation object of one scope
Signature:
Private Function BuildScope(ByVal tableName As String, _
ByVal langNameId As String) As TranslationObject
Private utility methods.
Resolves the table and the language code the scope needs, and raises when the code is empty. An empty code gives a TranslationObject whose language matches no column header, and every tag then translates to itself with no error raised anywhere below it.
Parameters:
tableName: String. The ListObject backing the scope.langNameId: String. The hidden name carrying the language code.
Returns: TranslationObject. The translation object for that table.
Throws:
- ProjectError.ElementNotFound When the table is absent or the language code is empty.
DropScopeCache #
drop-scope-cache
Forget the five scoped translation objects
Signature:
Private Sub DropScopeCache()
Each one holds a copy of its table, so anything that rewrites a table has to drop them.
ResolveListObject #
resolve-list-object
Resolve a ListObject by name from the host worksheet
Signature:
Private Function ResolveListObject(ByVal tableName As String) As ListObject
Returns the ListObject with the given name from the host translation worksheet. Raises an error when the table is not found.
Parameters:
tableName: String. The ListObject name to resolve.
Returns: ListObject. The resolved table.
Throws:
- ProjectError.ElementNotFound When the table is not found.
FindOrCreateSheet #
find-or-create-sheet
Find or create a worksheet in the target workbook
Signature:
Private Function FindOrCreateSheet(ByVal targetWkb As Workbook, _
ByVal targetName As String) As Worksheet
Finds the worksheet of the given name in the target workbook. When it is there, its tables are deleted and its cells cleared; when it is absent, a worksheet of that name is added at the end.
Clearing cells leaves the ListObject objects standing, and each one keeps its name. The export that follows adds tables under those same names, so a second export into one workbook used to meet a name Excel had already given out and raise 1004.
Parameters:
targetWkb: Workbook. The target workbook.targetName: String. The worksheet name to find or create.
Returns: Worksheet. The resolved or newly created worksheet.
FormatExportSheet #
format-export-sheet
Apply standard formatting to an exported sheet
Signature:
Private Sub FormatExportSheet(ByVal sh As Worksheet, ByVal Hide As Long)
Sets font and alignment over the used range, autofits it, then sets the sheet visibility.
The look of the sheet is cosmetic and a failure there is suppressed. The visibility write is not cosmetic and stands outside the suppression: Excel refuses to hide the last visible worksheet of a workbook and refuses a write to a protected workbook structure, and either one leaves the translation tables on show in a delivered linelist.
Parameters:
sh: Worksheet. The sheet to format.Hide: Long. Sheet visibility constant.
CheckRequirements #
check-requirements
Validate that the translation sheet has all required tables
Signature:
Private Sub CheckRequirements(ByVal translationSheet As Worksheet)
Ensures the worksheet is not Nothing and that all five translation ListObjects are present.
Parameters:
translationSheet: Worksheet. The worksheet to validate.
Throws:
- ProjectError.ObjectNotInitialized When the sheet is Nothing.
- ProjectError.ElementNotFound When a required table is missing.
HiddenName writing
EnsureAndSet #
ensure-and-set
Give a HiddenName its value, creating it when it is absent
Signature:
Private Sub EnsureAndSet(ByVal store As HiddenNames, ByVal nameId As String, _
ByVal value As String)
Creating a hidden name and giving it its value.
EnsureName writes the value only when it creates the name, so a name that is already there needs the SetValue. Creating one and setting it straight after costs a full RefersTo rewrite and a comment re-apply on every one of the 17 names, which is why the two are branches here.
Parameters:
store: HiddenNames. The hidden names manager.nameId: String. The hidden name identifier.value: String. The value to set.
Error Handling
ThrowError #
throw-error
Raise a ProjectError-based exception
Signature:
Private Sub ThrowError(ByVal errNumber As Long, ByVal message As String)
Centralised error raising.
Parameters:
errNumber: ProjectError. The error constant.message: String. Descriptive error message.
Used in (24 file(s))
- LLExporter.cls
- EventLinelist.cls
- Linelist.cls
- LinelistSpecs.cls
- InitTransfer.bas
- EventsLinelistButtons.bas
- EventsLinelistRibbon.bas
- FormLogicAdvanced.bas
- FormLogicEpiWeek.bas
- FormLogicExport.bas
- FormLogicExportMig.bas
- FormLogicGeo.bas
- FormLogicImportRep.bas
- FormLogicShowHide.bas
- FormLogicShowHidePrint.bas
- FormLogicShowHideSave.bas
- FormLogicShowHideSections.bas
- FormLogicShowVarLabels.bas
- TestExportOtherLinelist.bas
- TestHeadlessLinelistBuild.bas
- TestHelpers.bas
- TestHelpersLite.bas
- TestEventLinelist.bas
- TestLLTranslation.bas