SetupImport

Moves the content of a setup workbook in and out. Check validates the setup sheets, Import reads the Dictionary, Choices, Exports, Analysis and Translations sheets from a file, ImportFromWorkbook reads them from an open workbook, Export writes them out, and Clean empties them. Path and SetExportFolder say where files are read from and written to, LastExportFile names the file the last export produced, ProgressObject takes the label the form shows progress on, and DisplayPrompts decides whether the class puts a message in front of the user.

HOW A SHEET IS MOVED

A sheet travels either as a whole table through CustomTable, or through the domain manager that owns it: LLdictionary, LLChoices, LLExport, Analysis and SetupTranslationsTable. Excel state is held by an ApplicationState for the length of the run, and the worksheets are unprotected and protected again through Passwords.

THREE RULES HOLD ACROSS THE CLASS
  1. A cleanup block reached by falling off the end of the work runs under its own handler, with the failure handler disarmed first.
  2. Every failure handler copies Err.Number, Err.Source and Err.Description into locals as its first three statements. Cleanup calls run On Error Resume Next and clear Err, so an error read after them belongs to the cleanup.
  3. Sheet names are compared without regard to case. Excel matches worksheet names that way itself, so "choices" reaches the same code as "Choices".
Factory helpers

Create #

create

Create a ready-to-use service instance

Signature:

Public Function Create(ByVal importPath As String, Optional ByVal progressDisplay As Object) As SetupImport

Creates a new SetupImport instance and assigns the path and the display through the property setters, which validate both.

The validation is left to the setters on purpose. Create runs on the predeclared default instance, so a validator called here writes its answer (this.hasCaption) onto that default instance and the new object keeps a stale value until a setter fills it in.

Parameters:

  • importPath: String. Path to the source setup workbook.
  • progressDisplay: Optional Object. UI element receiving textual updates (must expose Caption or Value).

Returns: SetupImport. Configured service instance.


Public configuration

Path #

path

Retrieve configured import path.

Signature:

Public Property Get Path() As String

Returns: String. The configured import path.


ProgressObject #

progress-object

Retrieve the progress display object.

Signature:

Public Property Get ProgressObject() As Object

Returns: Object. The progress display object.


DisplayPrompts #

display-prompts

Retrieve the display prompts toggle.

Signature:

Public Property Get DisplayPrompts() As Boolean

Returns: Boolean. True when prompts are enabled.


SetExportFolder #

set-export-folder

Provide an explicit folder for exports, bypassing the folder picker.

Signature:

Public Sub SetExportFolder(ByVal folderPath As String)

The folder is consumed by one export. Export clears it when it closes the export workbook, so a second export on the same instance needs a second call to this method.

Parameters:

  • folderPath: String. The folder path to use for exports.

LastExportFile #

last-export-file

Path of the last export produced by the service.

Signature:

Public Property Get LastExportFile() As String

Returns the full file path of the last export workbook saved by the service. Returns an empty string when no export has occurred, and when the caller supplied its own workbook to Export.

Returns: String. The last export file path, or empty.


Core workflow

Check #

check

Validate the requested import operation before execution.

Signature:

Public Sub Check(ByVal importDictionary As Boolean, _
                 ByVal importChoices As Boolean, _
                 ByVal importExports As Boolean, _
                 ByVal importAnalysis As Boolean, _
                 ByVal importTranslations As Boolean, _
                 Optional ByVal cleanSetup As Boolean = False)

Ensures at least one import option is selected, verifies the import path is configured and the file exists, then attempts to open and immediately close the source workbook to confirm it is readable.

Parameters:

  • importDictionary: Boolean. Flag requesting dictionary import.
  • importChoices: Boolean. Flag requesting choices import.
  • importExports: Boolean. Flag requesting exports import.
  • importAnalysis: Boolean. Flag requesting analysis import.
  • importTranslations: Boolean. Flag requesting translations import.
  • cleanSetup: Optional Boolean. When True, performs a clean-only run. Defaults to False.

Throws:

  • ProjectError.InvalidArgument When no import option is selected.
  • ProjectError.ElementNotFound When no file sits at the configured path.
  • ProjectError.SomethingWentWrong When the source workbook cannot be opened.

Clean #

clean

Clean target worksheets ahead of a fresh import.

Signature:

Public Sub Clean(ByVal pass As Passwords, ByVal sheetsList As BetterArray)

Iterates over the requested sheets, unprotects each one, clears all ListObject data and worksheet comments, then re-protects. A sheet the host workbook does not carry is skipped, which is what Import does with the same list.

Parameters:

  • pass: Passwords. Password handler for worksheet protection.
  • sheetsList: BetterArray. Worksheets participating in the clean-up.

Throws:

  • ProjectError.ObjectNotInitialized When no password handler is supplied.
  • ProjectError.InvalidArgument When the sheets list is missing or empty.

Import #

import

Perform the setup import from the configured workbook into the host workbook.

Signature:

Public Sub Import(ByVal pass As Passwords, ByVal sheetsList As BetterArray)

Opens the source workbook, iterates over each requested sheet, matches ListObjects between source and host, and delegates import to CustomTable.Import. Handles sheet protection/unprotection and export column alignment via PrepareImport.

PrepareImport renames two Choices columns for the length of the run and PostImport puts the names back. PostImport runs exactly once per call, whichever way the run ends: the success path guards it with its own handler and the failure path checks postImportDone. A second run would leave two columns named "Translated Label" and no "Formula Label".

Parameters:

  • pass: Passwords. Password handler for worksheet protection.
  • sheetsList: BetterArray. Worksheets participating in the import.

Throws:

  • ProjectError.ObjectNotInitialized When no password handler is supplied.
  • ProjectError.InvalidArgument When the sheets list is missing or empty.

Workbook-driven import

ImportFromWorkbook #

import-from-workbook

Perform the setup import leveraging dedicated worksheet classes.

Signature:

Public Sub ImportFromWorkbook(ByVal pass As Passwords, Optional ByVal sheetsList As BetterArray = Nothing)

Uses domain-specific classes (LLdictionary, LLChoices, LLExport, Analysis, SetupTranslationsTable) to import each worksheet from the source workbook. Falls back to the default sheets list when none is provided.

The sheet list is resolved before anything else, and PrepareImport is handed the resolved list from inside the protected block. PrepareImport exits on a missing list, so handing it the raw argument used to skip the export-row sync on every call that named no sheets - and the run still imported Exports into a host table that was too short.

Parameters:

  • pass: Passwords. Password handler for worksheet protection.
  • sheetsList: Optional BetterArray. Worksheets to import. Defaults to all five setup sheets.

Throws:

  • ProjectError.ObjectNotInitialized When no password handler is supplied.

Workbook driven Export

Export #

export-to-workbook

Export all setup worksheets to a new workbook.

Signature:

Public Sub Export(Optional ByVal outwb As Workbook)

Creates or reuses an export workbook, then exports each setup worksheet (Dictionary, Choices, Exports, Analysis, Translations) using domain-specific managers, along with hidden names and formatting data.

The caller owns any workbook it supplies through outwb. On that path the service writes the sheets and stops: it saves nothing, leaves LastExportFile empty, leaves the workbook open, and removes no sheet from it. A workbook the service creates itself is saved to the configured folder, closed, and stripped of the blank sheets Workbooks.Add gave it.

Parameters:

  • outwb: Optional Workbook. Pre-existing target workbook. When Nothing, creates a new one.

Internal members (not exported)

State and constants

Class_Initialize #

initialize

Set default state on construction.

Signature:

Private Sub Class_Initialize()

Public configuration

Path #

path-set

Store the path to the setup workbook.

Signature:

Public Property Let Path(ByVal value As String)

Parameters:


ProgressObject #

progress-object-set

Store the progress display object reference.

Signature:

Public Property Set ProgressObject(ByVal value As Object)

Parameters:

Throws:


DisplayPrompts #

display-prompts-set

Toggle UI prompts displayed during operations.

Signature:

Public Property Let DisplayPrompts(ByVal state As Boolean)

When False, suppresses folder-picker dialogs and other interactive prompts. Primarily used by automated tests.

Parameters:


Application state coordination

ApplicationScope #

application-scope

Guard Excel with the reusable ApplicationState scope.

Signature:

Private Function ApplicationScope() As ApplicationState

EnterBusyState #

enter-busy-state

Apply the busy state when heavy work starts.

Signature:

Private Sub EnterBusyState()

One scope covers a whole operation, including any inner call that enters the busy state again. The depth counter is what makes that work: only the outermost call restores, so an inner return can no longer put Calculation back to automatic in the middle of the work.


LeaveBusyState #

leave-busy-state

Restore Excel configuration when the outermost call completes.

Signature:

Private Sub LeaveBusyState(Optional ByVal silent As Boolean = False)

RestoreApplicationState #

restore-application-state

Restore Excel and release the scope.

Signature:

Private Sub RestoreApplicationState(ByVal silent As Boolean)

The scope is released once it has restored. ApplicationState captures its snapshot once per object, so a released scope is what makes the next operation record the settings as they are then.


Workbook-driven import

ImportDictionaryUsingClass #

import-dictionary

Import dictionary worksheet using LLdictionary.

Signature:

Private Sub ImportDictionaryUsingClass(ByVal pass As Passwords, _
                                       ByVal hostWorkbook As Workbook, _
                                       ByVal importWorkbook As Workbook)

ImportChoicesUsingClass #

import-choices

Import choices worksheet using LLChoices.

Signature:

Private Sub ImportChoicesUsingClass(ByVal pass As Passwords, _
                                    ByVal hostWorkbook As Workbook, _
                                    ByVal importWorkbook As Workbook)

ImportExportUsingClass #

import-exports

Import export specifications via LLExport.

Signature:

Private Sub ImportExportUsingClass(ByVal pass As Passwords, _
                                   ByVal hostWorkbook As Workbook, _
                                   ByVal importWorkbook As Workbook)

ImportAnalysisUsingClass #

import-analysis

Import analysis worksheet content via Analysis class.

Signature:

Private Sub ImportAnalysisUsingClass(ByVal pass As Passwords, _
                                     ByVal hostWorkbook As Workbook, _
                                     ByVal importWorkbook As Workbook)

ImportTranslationsUsingClass #

import-translations

Import translations worksheet using CustomTable and DataSheet.

Signature:

Private Sub ImportTranslationsUsingClass(ByVal pass As Passwords, _
                                         ByVal hostWorkbook As Workbook, _
                                         ByVal importWorkbook As Workbook)

ResolveTranslationsList #

resolve-translations-list

Resolve the translations ListObject from a worksheet.

Signature:

Private Function ResolveTranslationsList(ByVal sheetRef As Worksheet, _
                                         Optional ByVal preferred As ListObject = Nothing) As ListObject

Preparation helpers

PrepareImport #

prepare-import

Ensure the exports and dictionary sheets are aligned prior to import.

Signature:

Private Sub PrepareImport(ByVal pass As Passwords, _
                          Optional ByVal sheetsList As BetterArray, _
                          Optional ByVal forceSync As Boolean = True, _
                          Optional ByVal impStartRow As Long = EXPORT_HOST_START_ROW, _
                          Optional ByVal impStartColumn As Long = EXPORT_HOST_START_COLUMN, _
                          Optional ByVal renameChoices As Boolean = False)

PostImport #

post-import

Restore choices column names after import completes.

Signature:

Private Sub PostImport(ByVal pass As Passwords, _
                        Optional ByVal sheetsList As BetterArray)

Validation helpers

ResolveImportSheets #

resolve-import-sheets

Resolve the requested sheets set, defaulting to core setup worksheets.

Signature:

Private Function ResolveImportSheets(ByVal sheetsList As BetterArray) As BetterArray

DefaultImportSheets #

default-import-sheets

Default sheet list covering the core setup worksheets.

Signature:

Private Function DefaultImportSheets() As BetterArray

SheetListKeys #

sheet-list-keys

Build one lower-cased key string out of a sheets list.

Signature:

Private Function SheetListKeys(ByVal sheetsList As BetterArray) As String

The list is walked once per call and every later question is answered with InStr. The separator sits on both sides of each name, so a short name cannot match inside a longer one.


SheetInKeys #

sheet-in-keys

Answer whether a sheet name sits in a key string.

Signature:

Private Function SheetInKeys(ByVal sheetKeys As String, ByVal sheetName As String) As Boolean

SameSheetName #

same-sheet-name

Compare two worksheet names the way Excel does.

Signature:

Private Function SameSheetName(ByVal leftName As String, ByVal rightName As String) As Boolean

EnsureImportSelection #

ensure-import-selection

Ensure at least one import option is selected.

Signature:

Private Sub EnsureImportSelection(ByVal importDictionary As Boolean, _
                                  ByVal importChoices As Boolean, _
                                  ByVal importExports As Boolean, _
                                  ByVal importAnalysis As Boolean, _
                                  ByVal importTranslations As Boolean, _
                                  ByVal cleanSetup As Boolean)

EnsureImportPathConfigured #

ensure-import-path-configured

Ensure the import path has been configured.

Signature:

Private Sub EnsureImportPathConfigured(ByVal value As String)

ValidatePasswords #

validate-passwords

Validate availability of requested passwords object.

Signature:

Private Sub ValidatePasswords(ByVal pass As Passwords)

EnsureSheetsList #

ensure-sheets-list

Ensure the sheets list is initialised.

Signature:

Private Function EnsureSheetsList(ByVal sheetsList As BetterArray) As BetterArray

ValidateImportPath #

validate-import-path

Confirm the import path string is valid.

Signature:

Private Sub ValidateImportPath(ByVal pathValue As String)

ValidateProgressDisplay #

validate-progress-display

Ensure the progress display object exposes a Caption or Value property.

Signature:

Private Sub ValidateProgressDisplay(ByVal progressDisplay As Object)

An object that carries neither property is refused. The refusal used to sit below a plain Exit Sub, on a label nothing could jump to, so any object at all was accepted and the writers below then wrote to nothing.


TestProperty #

test-property

Test whether an object supports a named property.

Signature:

Private Function TestProperty(ByVal probeObject As Object, _
                              ByRef hasProp As Boolean, _
                              ByVal propName As String) As Boolean

The probe reads the property. Writing to it was how this used to work, so asking a label whether it had a caption erased the caption. A name the probe does not know answers False.


EnsureImportFileExists #

ensure-import-file-exists

Ensure the import workbook file exists before opening.

Signature:

Private Sub EnsureImportFileExists(ByVal filePath As String)

Workbook helpers

EnsureImportWorkbook #

ensure-import-workbook

Obtain the imported workbook, opening it when needed.

Signature:

Private Function EnsureImportWorkbook() As Workbook

EnsureExportWorkbook #

ensure-export-workbook

Obtain or create the export workbook, prompting for a folder when needed.

Signature:

Private Function EnsureExportWorkbook() As Workbook

The sheets the new workbook is born with are captured here, by reference, so the export can drop exactly those at the end. Deleting Worksheets(1) instead assumed one blank sheet and assumed every manager appends after the last one.


CaptureWorksheets #

capture-worksheets

Hold every worksheet of a workbook in a Collection.

Signature:

Private Function CaptureWorksheets(ByVal workbookRef As Workbook) As Collection

RemoveExportBaseSheets #

remove-export-base-sheets

Drop the blank sheets the export workbook was created with.

Signature:

Private Sub RemoveExportBaseSheets(ByVal targetWorkbook As Workbook)

Only a workbook the service created carries captured sheets, so a workbook the caller supplied keeps every sheet it had. The delete stops while one sheet is left, because a workbook cannot hold zero worksheets.


EnsureSavedExport #

ensure-saved-export

Save the export workbook to the configured path.

Signature:

Private Sub EnsureSavedExport()

The format is stated. Without it Excel writes in whatever default format the machine is set to, so a machine set to .xlsb produced a binary payload under an .xlsx name.


DictionaryFormatHeaders #

dictionary-format-headers

Header names the dictionary import carries its formatting for.

Signature:

Private Function DictionaryFormatHeaders() As BetterArray

BuildExportFilePath #

build-export-file-path

Build the stamped export file path from the configured folder.

Signature:

Private Function BuildExportFilePath() As String

Whatever follows the last dot of the host name is dropped, so a host saved as .xlsm or .XLSB no longer carries its extension inside the new name. The stamp carries the time as well as the date, so two exports in one day are two files.


CloseImportWorkbook #

close-import-workbook

Close and release the imported workbook.

Signature:

Private Sub CloseImportWorkbook()

CloseExportWorkbook #

close-export-workbook

Close and release the export workbook.

Signature:

Private Sub CloseExportWorkbook()

The folder is cleared with the workbook, so a second export on the same instance needs a fresh SetExportFolder call.


CloseWorkbook #

close-workbook

Close workbook safely without raising errors.

Signature:

Private Sub CloseWorkbook(ByVal workbookRef As Workbook)

TryWorksheet #

try-worksheet

Resolve a worksheet, answering Nothing when it is absent.

Signature:

Private Function TryWorksheet(ByVal workbookRef As Workbook, ByVal sheetName As String) As Worksheet

TryListObject #

try-list-object

Resolve a ListObject, answering Nothing when it is absent.

Signature:

Private Function TryListObject(ByVal sheetRef As Worksheet, ByVal listName As String) As ListObject

FirstListObject #

first-list-object

Resolve the first ListObject of a worksheet.

Signature:

Private Function FirstListObject(ByVal sheetRef As Worksheet) As ListObject

Worksheet helpers

CleanWorksheetTables #

clean-worksheet-tables

Clean all ListObjects within a worksheet.

Signature:

Private Sub CleanWorksheetTables(ByVal targetSheet As Worksheet)

ClearWorksheetComments #

clear-worksheet-comments

Remove the classic comments from a worksheet.

Signature:

Private Sub ClearWorksheetComments(ByVal targetSheet As Worksheet)

Range.ClearComments covers classic comments. Threaded comments are reached through Worksheet.CommentsThreaded, which Mac Excel does not carry.


ProtectWorksheet #

protect-worksheet

Protect worksheet with default rules.

Signature:

Private Sub ProtectWorksheet(ByVal pass As Passwords, ByVal sheetName As String)

Every protect call in this class comes through here. Passwords.Protect defaults both flags to True, so a bare call left the Choices sheet allowing shapes and row deletion at the end of every import.


Messaging helpers

WriteInfo #

write-info

Display informational text through the progress object.

Signature:

Private Sub WriteInfo(ByVal message As String)

WriteProgress #

write-progress

Update a textual progress bar representation.

Signature:

Private Sub WriteProgress(ByVal percentage As Long)

The percentage is clamped on both sides in plain VBA. A worksheet function call for a two-value minimum is a round trip into Excel, and it left the low side open, so a negative percentage reached String$ and raised error 5.


ProgressPercent #

progress-percent

Turn a done-out-of-total pair into a percentage.

Signature:

Private Function ProgressPercent(ByVal completed As Long, ByVal total As Long) As Long

BuildOpenFailureMessage #

build-open-failure-message

Combine failure details when opening a workbook fails.

Signature:

Private Function BuildOpenFailureMessage(ByVal sourcePath As String, ByVal failureDetails As String) As String

Error handling

ReportAndThrow #

report-and-throw

Report message then raise a project error.

Signature:

Private Sub ReportAndThrow(ByVal errNumber As Long, ByVal message As String)

Parameters:


ThrowError #

throw-error

Raise a ProjectError-based exception.

Signature:

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

The code is typed Long, which is the repo rule: an Enum in a parameter list misbehaves on Mac Excel, and every call site already passes a ProjectError member that widens to Long on its own.

Parameters:


Class_Terminate #

terminate

Cleanup resources on destruction.

Signature:

Private Sub Class_Terminate()

Used in (7 file(s))