LinelistSpecs

Modern facade that wraps a specifications workbook and exposes lazy-loaded, cached accessors for every collaborator object (dictionary, choices, translations, geo, analysis, passwords, format, exports, formulas). Provides lifecycle orchestration methods for importing data from external setup workbooks, preparing the dictionary with preserved sheet names, exporting specifications to a destination linelist workbook, and surfacing user-facing error dialogs. Uses a PredeclaredId factory pattern so callers construct instances via LinelistSpecs.Create(workbook) and receive an ILinelistSpecs interface reference.

Depends on: ILLdictionary, ILLChoices, ILLTranslation, IDesignerTranslation, ILLGeo, ILLExport, IAnalysis, IPasswords, ILLFormat, IDesignerImportService, ITemporaryRepos, TemporaryRepos, IFormulaData, ILLVariables, IFormulas, ITranslationObject, IApplicationState, ApplicationState, BetterArray, LLdictionary, LLChoices, LLTranslation, DesignerTranslation, LLGeo, LLExport, Analysis, Passwords, LLFormat, FormulaData, LLVariables, Formulas

Version: 1.1 (2026-02-16)

Factory helpers

create #

Create a new specification facade from a workbook

Signature:

Public Function Create(ByVal specsWorkbook As Workbook) As ILinelistSpecs

Construction and identity accessors. Validates the workbook structure upfront (checking for all required worksheets and named ranges), then constructs a new LinelistSpecs instance with caches initialised. Returns the ILinelistSpecs interface.

Parameters:

  • specsWorkbook: Workbook. The specifications workbook to wrap.

Returns: ILinelistSpecs. A fully initialised facade ready for use.

Throws:

  • ProjectError.ObjectNotInitialized When specsWorkbook is Nothing.
  • ProjectError.ElementNotFound When required worksheets are missing.

des-workbook #

Designer workbook backing all specification queries

Signature:

Public Property Get DesWorkbook() As Workbook

Returns the designer/specifications workbook reference. Raises an error if the workbook has not been assigned via the factory method.

Returns: Workbook. The designer workbook.

Throws:

  • ProjectError.ObjectNotInitialized When the workbook is not set.

State management

reset-caches #

Reset every cached collaborator

Signature:

Public Sub ResetCaches()

Cache invalidation for collaborator objects, translations, and categories. Clears all cached collaborator objects, the translation scope cache, and the category cache. Call after importing new data so subsequent reads query the workbook again.


Category helpers

categories #

Resolve category values for a variable with caching

Signature:

Public Function Categories(ByVal varName As String, Optional ByVal useShortlabels As Boolean = False) As BetterArray

Category resolution and caching for choice-type variables. Returns the list of category values for a choice-type variable (choice_manual, choice_multiple, choice_custom, or choice_formula). Results are cached using parallel key/value BetterArrays for efficient repeated access. Always returns a cloned BetterArray to prevent callers from modifying the cached copy.

Parameters:

  • varName: String. The variable name whose categories to resolve.
  • useShortlabels: Boolean. When True, returns short labels. Defaults to False.

Returns: BetterArray. Cloned list of category values.

Throws:

  • ProjectError.InvalidArgument When varName is empty.
  • ProjectError.ElementNotFound When the variable has no selectable categories.

Core accessors

dictionary #

Linelist dictionary

Signature:

Public Property Get Dictionary() As ILLdictionary

Public property accessors for each collaborator object, exposing the lazy-loaded instances through their respective interfaces. Returns the ILLdictionary instance providing column and row access to the Dictionary worksheet. Lazy-loaded on first access.

Returns: ILLdictionary. The dictionary collaborator.


choices #

Choices catalogue

Signature:

Public Property Get Choices() As ILLChoices

Returns the ILLChoices instance providing category lookups from the Choices worksheet. Lazy-loaded on first access.

Returns: ILLChoices. The choices collaborator.


design-format #

Visual formatting specifications

Signature:

Public Property Get DesignFormat() As ILLFormat

Returns the ILLFormat instance providing sheet and cell formatting methods based on the __formatter worksheet. Lazy-loaded on first access.

Returns: ILLFormat. The format collaborator.


analysis #

Analysis setup specifications

Signature:

Public Property Get Analysis() As IAnalysis

Returns the IAnalysis instance providing access to the Analysis worksheet configuration. Lazy-loaded on first access.

Returns: IAnalysis. The analysis collaborator.


export-object #

Export column specifications

Signature:

Public Property Get ExportObject() As ILLExport

Returns the ILLExport instance providing access to export column definitions from the Exports worksheet. Lazy-loaded on first access.

Returns: ILLExport. The export collaborator.


password #

Password manager

Signature:

Public Property Get Password() As IPasswords

Returns the IPasswords instance providing workbook and sheet protection utilities from the __pass worksheet. Lazy-loaded on first access.

Returns: IPasswords. The password collaborator.


geo-object #

Geographic data manager

Signature:

Public Property Get GeoObject() As ILLGeo

Returns the ILLGeo instance providing geographic hierarchy lookups from the Geo worksheet. Lazy-loaded on first access.

Returns: ILLGeo. The geo collaborator.


formula-data-object #

Formula data provider

Signature:

Public Property Get FormulaDataObject() As IFormulaData

Returns the IFormulaData instance providing formula parsing support from the __formula worksheet. Lazy-loaded on first access.

Returns: IFormulaData. The formula data collaborator.


has-template #

Whether the workbook uses a ribbon template

Signature:

Public Property Get HasTemplate() As Boolean

Reads the RNG_MainTemp named range on the Main worksheet and returns True when the value equals "has template".

Returns: Boolean. True when a template is configured.


translations #

Translation tables manager

Signature:

Public Property Get Translations() As ILLTranslation

Returns the ILLTranslation instance providing access to the linelist translation worksheet. Lazy-loaded on first access.

Returns: ILLTranslation. The translations collaborator.


designer-translations #

Designer translation accessor

Signature:

Public Property Get DesignerTranslations() As IDesignerTranslation

Returns the IDesignerTranslation instance providing designer UI translations from the DesignerTranslation worksheet. Lazy-loaded on first access.

Returns: IDesignerTranslation. The designer translation collaborator.


trans-object #

Scoped translation object

Signature:

Public Property Get TransObject(Optional ByVal translationScope As Byte = TranslationOfMessages) As ITranslationObject

Returns an ITranslationObject for the requested translation scope. Results are cached per scope using direct fields for each TranslationScope value (0-4), avoiding generic container overhead.

Parameters:

  • translationScope: Byte. The translation scope constant (e.g., TranslationOfMessages, TranslationOfDictionary). Defaults to TranslationOfMessages.

Returns: ITranslationObject. The scoped translation object.

Throws:

  • ProjectError.ElementNotFound When the scope is not available.

temporary-sheet-name #

Temporary sheet name for a given scope

Signature:

Public Property Get TemporarySheetName(ByVal scope As Byte) As String

Returns the fixed worksheet name used for temporary internal sheets, mapped from the TempSheetScope enum (TempSheetAnalysis, TempSheetList, etc.) to its canonical name string.

Parameters:

  • scope: Byte. A TempSheetScope enum value.

Returns: String. The worksheet name string.

Throws:

  • ProjectError.InvalidArgument When the scope is not recognised.

value #

Configuration value by tag name

Signature:

Public Property Get Value(ByVal tagName As String) As String

Returns a configuration value from the Main worksheet for the given tag name. The special tag "numberofexports" returns the export count from the Exports worksheet; all other tags resolve the named range directly on the Main worksheet.

Parameters:

  • tagName: String. The configuration key to look up.

Returns: String. The configuration value, or empty string if tagName is empty.


Workbook orchestration

prepare #

Prepare all specifications using an import service

Signature:

Public Sub Prepare(ByVal importService As IDesignerImportService)

Lifecycle methods for importing, preparing, exporting, and error-managing the specifications workbook. Orchestrates the full specification preparation workflow:

  1. Creates a temporary repository for working files.
  2. Creates a new output workbook (from template if configured).
  3. Exports designer components via the import service.
  4. Retrieves exported domain instances from the service.
  5. Prepares the dictionary with preserved sheet names and geo references.
  6. Adds the "list auto" column if not already present.
  7. Translates and sorts all collaborators using dictionary translations. Handles errors with cleanup and busy-state restoration.

Parameters:

  • importService: IDesignerImportService. The configured import service.

Throws:

  • ProjectError.ObjectNotInitialized When importService is Nothing.
  • ProjectError.ErrorUnexpectedState When an unexpected error occurs.

ll-workbook #

The output linelist workbook created during Prepare

Signature:

Public Property Get LLWorkbook() As Workbook

Returns the linelist workbook created by Prepare that received exported data from the import service. Returns Nothing before Prepare is called.

Returns: Workbook. The linelist workbook, or Nothing.


temporary-repos #

The temporary repository created during Prepare

Signature:

Public Property Get OutputTemporaryRepos() As ITemporaryRepos

Returns the ITemporaryRepos instance created by Prepare for working files. Returns Nothing before Prepare is called.

Returns: ITemporaryRepos. The temporary repository, or Nothing.


error-manage #

Display an error dialog for specification failures

Signature:

Public Sub ErrorManage(Optional ByVal textMessage As String = vbNullString)

Shows a message box describing the error and informing the user that the linelist creation process is being aborted.

Parameters:

  • textMessage: String. Error description. Defaults to vbNullString.

Internal members (not exported)

Factory helpers

self #

Interface-cast self reference

Signature:

Public Property Get Self() As ILinelistSpecs

Returns the current instance cast as ILinelistSpecs for fluent construction patterns within the factory method.

Returns: ILinelistSpecs. This instance as its interface type.


internal-workbook #

Setter for the backing workbook reference

Signature:

Public Property Set InternalWorkbook(ByVal specsWorkbook As Workbook)

Used during construction to assign the workbook before caches are initialised. Not part of the public interface.


State management

reset-object-caches #

Clear all collaborator object references

Signature:

Private Sub ResetObjectCaches()

reset-translation-cache #

Clear the translation scope cache

Signature:

Private Sub ResetTranslationCache()

reset-category-cache #

Clear the category list cache

Signature:

Private Sub ResetCategoryCache()

Guard helpers

ensure-workbook #

Verify that the backing workbook is assigned

Signature:

Private Sub EnsureWorkbook()

Lazy-initialisation guards for the workbook and category arrays.

Throws:


ensure-category-arrays #

Create the parallel category arrays if they do not exist

Signature:

Private Sub EnsureCategoryArrays()

Worksheet resolution

resolve-sheet #

Resolve a worksheet by name with optional error surfacing

Signature:

Private Function ResolveSheet(ByVal sheetName As String, _
                              Optional ByVal allowMissing As Boolean = False) As Worksheet

Direct worksheet lookups by name within the specifications workbook. Looks up a worksheet in the specifications workbook by name. When the sheet is not found and allowMissing is False, raises a descriptive error.

Parameters:

Returns: Worksheet. The resolved worksheet, or Nothing if allowMissing.

Throws:


External workbook helpers

enter-busy-state #

Transition the application into a busy state

Signature:

Private Sub EnterBusyState(ByRef busyScope As IApplicationState)

Utilities for opening, closing, and validating external workbooks during the Prepare workflow. Creates or refreshes an ApplicationState snapshot and applies the busy state (suppressing screen updates and calculation) if not already busy.

Parameters:


import-geobase #

Import geobase data from the user-specified path

Signature:

Private Sub ImportGeobase(ByVal geoObj As ILLGeo)

Reads the geobase file path from the Main worksheet. If the path is not empty, opens the geobase workbook, sets the dictionary language on the exported geo worksheet via RNG_MetaLang, calls geoObj.Import to populate the output geo sheet, then closes the geobase workbook. Silently skips if the path is empty or the file cannot be opened.

Parameters:


exit-busy-state #

Restore the application from a busy state

Signature:

Private Sub ExitBusyState(ByRef busyScope As IApplicationState)

Parameters:


build-preserved-sheet-names #

Build the list of sheet names to preserve during dictionary preparation

Signature:

Private Function BuildPreservedSheetNames(ByVal messageTranslations As ITranslationObject) As BetterArray

Collects all specification sheet names and temporary sheet names into a BetterArray, then appends translated linelist sheet names (Admin, Analysis, Spatial, etc.) when message translations are available.

Parameters:

Returns: BetterArray. The list of preserved sheet names.


safe-translated-value #

Look up a translation key, falling back to the key itself on failure

Signature:

Private Function SafeTranslatedValue(ByVal translations As ITranslationObject, ByVal key As String) As String

Parameters:

Returns: String. The translated value, or the key if translation fails.


reset-post-import-caches #

Clear caches that become stale after importing new data

Signature:

Private Sub ResetPostImportCaches()

Resets the variables object, category cache, and translation cache so they are rebuilt from the freshly imported data.


Workbook validation

validate-workbook-reference #

Validate a workbook reference and its structure

Signature:

Private Sub ValidateWorkbookReference(ByVal specsWorkbook As Workbook)

Structural validation of specifications workbooks.

Throws:


validate-workbook-structure #

Check that a workbook contains all required worksheets and named ranges

Signature:

Private Sub ValidateWorkbookStructure(ByVal specsWorkbook As Workbook)

Iterates the list of required sheet names and collects any that are missing. If the format sheet exists, also validates that the DESIGNTYPE named range is present.

Parameters:

Throws:


required-sheet-names #

Return the array of required specification worksheet names

Signature:

Private Function RequiredSheetNames() As Variant

Returns: Variant. Array of sheet name strings.


worksheet-exists-internal #

Test whether a worksheet exists in a workbook

Signature:

Private Function WorksheetExistsInternal(ByVal specsWorkbook As Workbook, _
                                         ByVal sheetName As String) As Boolean

Parameters:

Returns: Boolean. True when the worksheet exists.


range-exists-internal #

Test whether a named range exists on a worksheet

Signature:

Private Function RangeExistsInternal(ByVal hostSheet As Worksheet, _
                                     ByVal rangeName As String) As Boolean

Parameters:

Returns: Boolean. True when the named range exists.


join-names #

Join a BetterArray of names into a comma-separated, quoted string

Signature:

Private Function JoinNames(ByVal values As BetterArray) As String

Parameters:

Returns: String. Formatted string like "'Sheet1', 'Sheet2'".


safe-workbook-name #

Safely retrieve a workbook's name, returning "" on error

Signature:

Private Function SafeWorkbookName(ByVal specsWorkbook As Workbook) As String

Parameters:

Returns: String. The workbook name or "".


Collaborator ensures

ensure-exports #

Lazy-load the export collaborator

Signature:

Private Sub EnsureExports()

Lazy-initialisation guards for each collaborator object. Each EnsureXxx method creates the collaborator from its backing worksheet on first access, then caches it for subsequent calls.


ensure-dictionary #

Lazy-load the dictionary collaborator

Signature:

Private Sub EnsureDictionary()

Requires the export collaborator to be available first (for the number of exports parameter), then creates the dictionary from the Dictionary worksheet.


ensure-choices #

Lazy-load the choices collaborator

Signature:

Private Sub EnsureChoices()

ensure-translations #

Lazy-load the translations collaborator

Signature:

Private Sub EnsureTranslations()

Creates the LLTranslation instance from the linelist translation worksheet.


ensure-designer-translations #

Lazy-load the designer translations collaborator

Signature:

Private Sub EnsureDesignerTranslations()

ensure-geo #

Lazy-load the geo collaborator

Signature:

Private Sub EnsureGeo()

ensure-analysis #

Lazy-load the analysis collaborator

Signature:

Private Sub EnsureAnalysis()

ensure-passwords #

Lazy-load the passwords collaborator

Signature:

Private Sub EnsurePasswords()

ensure-formula-data #

Lazy-load the formula data collaborator

Signature:

Private Sub EnsureFormulaData()

ensure-variables #

Lazy-load the variables collaborator

Signature:

Private Sub EnsureVariables()

Requires the dictionary to be available first, then creates the LLVariables instance from it.


ensure-format #

Lazy-load the format collaborator

Signature:

Private Sub EnsureFormat()

Resolves the design name from the DESIGNTYPE named range on the format sheet, then creates the LLFormat instance.


resolve-design-name #

Extract the design name from the format worksheet's DESIGNTYPE range

Signature:

Private Function ResolveDesignName(ByVal formatSheet As Worksheet) As String

Parameters:

Returns: String. The trimmed design type name.

Throws:


ensure-category-lookup #

Ensure choices, variables, and category arrays are ready

Signature:

Private Sub EnsureCategoryLookup()

number-of-exports #

Return the number of exports defined in the export specifications

Signature:

Private Function NumberOfExports() As Long

Returns: Long. The export count.


List auto helpers

add-list-auto #

Populate the "list auto" dictionary column for list_auto variables

Signature:

Private Sub AddListAuto()

Automatic list column generation for formula-based variables. Adds a "list auto" column to the dictionary, then finds all variables with control type "list_auto" and marks their control details with "list_auto_origin". For formula-type variables (formula, case_when, choice_formula), recursively traces referenced variables and marks them as well.


recursive-list-auto #

Recursively mark referenced variables in formula chains as list_auto

Signature:

Private Sub RecursiveListAuto(ByVal varName As String)

Parses the control details of a formula-type variable using the Formulas engine, extracts the list of referenced variables, marks each with "list_auto_origin", and recurses into any that are themselves formulas or case_when types.

Parameters:


Category helpers

find-category-index #

Search the category keys array for a matching key

Signature:

Private Function FindCategoryIndex(ByVal cacheKey As String) As Long

Parameters:

Returns: Long. The 1-based index if found, or 0 if not found.


resolve-category-list #

Build a category list from the choices sheet for a given variable

Signature:

Private Function ResolveCategoryList(ByVal varName As String, _
                                     ByVal useShortlabels As Boolean) As BetterArray

Determines the category name from the variable's control type and control details, then queries the choices collaborator.

Parameters:

Returns: BetterArray. The resolved category list.

Throws:


normalise-control-type #

Strip parenthesised suffixes from a control type string

Signature:

Private Function NormaliseControlType(ByVal controlValue As String) As String

Parameters:

Returns: String. The normalised, lower-cased control type.


extract-choice-formula #

Extract the choice name from a CHOICE_FORMULA(...) control details string

Signature:

Private Function ExtractChoiceFormula(ByVal controlDetails As String) As String

Parameters:

Returns: String. The extracted choice name.


Core accessors

resolve-translation-scope #

Query the translations collaborator for a given scope

Signature:

Private Function ResolveTranslationScope(ByVal translationScope As Byte) As ITranslationObject

Parameters:

Returns: ITranslationObject. The resolved translation object.

Throws:


Error handling

throw-error #

Raise a project error with the class name as source

Signature:

Private Sub ThrowError(ByVal errNumber As Long, ByVal messageText As String)

Internal error-raising utility.

Parameters:


Test support

test-assign-designer-translations #

Inject a mock IDesignerTranslation instance for testing

Signature:

Public Sub TestAssignDesignerTranslations(ByVal designerTrads As IDesignerTranslation)

Backdoor setters for injecting mock collaborators during testing.

Parameters:


test-assign-translations #

Inject a mock ILLTranslation instance for testing

Signature:

Public Sub TestAssignTranslations(ByVal translations As ILLTranslation)

Also resets the translation cache to ensure the mock object is used for subsequent TransObject lookups.

Parameters:


Interface implementation

ILinelistSpecs_ResetCaches #

Signature:

Private Sub ILinelistSpecs_ResetCaches()

ILinelistSpecs delegation stubs. Each member forwards to its corresponding public member on the concrete class. No @label tags are needed on delegation stubs.


Used in (17 file(s))