MasterSetupImportService

Internal members (not exported)

Factory

Create #

Build a service over the master setup workbook and its managers.

Signature:

Public Function Create(ByVal targetBook As Workbook, _
                       ByVal builder As DiseaseSheet, _
                       ByVal dropdowns As DropdownLists, _
                       ByVal variables As MasterSetupVariables, _
                       Optional ByVal choices As LLChoices = Nothing, _
                       Optional ByVal importer As DiseaseImporter = Nothing) As MasterSetupImportService

Parameters:

Returns: MasterSetupImportService ready to import.


Configuration

Initialise #

Attach the workbook and the managers the imports write through.

Signature:

Public Sub Initialise(ByVal targetBook As Workbook, _
                      ByVal builder As DiseaseSheet, _
                      ByVal dropdowns As DropdownLists, _
                      ByVal variables As MasterSetupVariables, _
                      Optional ByVal choices As LLChoices = Nothing, _
                      Optional ByVal importer As DiseaseImporter = Nothing)

Setup Export Import

ImportSetupExport #

Fold a workbook exported for a setup back into the master setup.

Signature:

Public Function ImportSetupExport(ByVal sourceBook As Workbook, _
                                  Optional ByVal logger As DiseaseLogger = Nothing, _
                                  Optional ByVal diseaseName As String = vbNullString) As DiseaseImportSummary

The Metadata sheet is read first, then the Variables table takes the variables it lacks, the Choices sheet takes the lists it lacks, and the dictionary is staged as a disease table on a hidden sheet and landed on the disease worksheet. The staging sheet goes away on every path.

Parameters:

Returns: DiseaseImportSummary of the merge, or Nothing when no disease worksheet could take the block.


Disease Table Import

ImportDiseaseTable #

Land a table shaped as a disease table on the disease worksheet.

Signature:

Public Function ImportDiseaseTable(ByVal sourceTable As ListObject, _
                                   ByVal diseaseName As String, _
                                   ByVal languageTag As String, _
                                   Optional ByVal restoreFormulas As Boolean = False, _
                                   Optional ByVal logger As DiseaseLogger = Nothing) As DiseaseImportSummary

A worksheet of that name that is gone is built again, on the language given when the languages list carries it and on the default language otherwise; the block then replaces its table whole. A worksheet that is there is merged, with the imported values winning on the lines both carry. A worksheet of that name that is no disease worksheet is left alone and logged.

Parameters:

Returns: DiseaseImportSummary of the merge, or Nothing when the block was left out.


Name Resolution

ReadDiseaseName #

The disease name a file carries: its workbook tag, then its Metadata sheet.

Signature:

Public Function ReadDiseaseName(ByVal sourceBook As Workbook) As String

Returns: String, empty when the file names no disease.


DiseaseNameIsFree #

Whether a name can take a new disease worksheet in the target workbook.

Signature:

Public Function DiseaseNameIsFree(ByVal candidate As String) As Boolean

Empty names, names of a worksheet already there and names of the prohibited list are refused. A name already there would merge the file into a sheet the user did not name.


Results

AddedVariables #

Names of the variables the last import added to the Variables table.

Signature:

Public Property Get AddedVariables() As BetterArray

AddedChoices #

Names of the lists the last import added to the Choices sheet.

Signature:

Public Property Get AddedChoices() As BetterArray

DiseaseName #

Disease name read from the Metadata sheet of the last file.

Signature:

Public Property Get DiseaseName() As String

LanguageTag #

Language read from the Metadata sheet of the last file.

Signature:

Public Property Get LanguageTag() As String

DiseaseCode #

Disease code read from the Metadata sheet of the last file.

Signature:

Public Property Get DiseaseCode() As String

Metadata

ReadMetadata #

Settle the disease name, the language and the code of the file.

Signature:

Private Sub ReadMetadata(ByVal sourceBook As Workbook, ByVal givenName As String)

The workbook tags come first, the Metadata sheet fills what they leave empty, and a name given by the caller wins. A file with no name from any of the three is refused.


TagValue #

A workbook tag; a file with no hidden names store answers empty.

Signature:

Private Function TagValue(ByVal sourceBook As Workbook, ByVal nameId As String) As String

MetadataValue #

One value of the Metadata sheet, read by its label; empty without the sheet.

Signature:

Private Function MetadataValue(ByVal sourceBook As Workbook, ByVal metaLabel As String) As String

The Metadata sheet is a two-column block of labels and values, read by label so the order of the lines carries no weight.


Variables

UpdateVariables #

Add to the Variables table every variable of the dictionary it lacks.

Signature:

Private Sub UpdateVariables(ByVal dictionaryTable As ListObject, ByVal logger As DiseaseLogger)

One read of the dictionary block serves every line. A name the table carries, or one the file names twice, is passed over. The Default Choice column takes the list the variable points at, never the control itself: ChoiceNameAt settles which column of the file carries it.


ChoiceNameAt #

The list one dictionary line points at, whatever shape the file has.

Signature:

Private Function ChoiceNameAt(ByRef block As Variant, ByVal rowIndex As Long, _
                              ByVal controlColumn As Long, ByVal detailsColumn As Long) As String

With no "Control Details" column the file is one DiseaseExporter wrote, whose "Control" column already carries the list name, so that value is answered as it stands. With the column there the file is a setup dictionary: the control decides whether the details name a list at all, plain for choice_manual, choice_multiple and choice_custom and wrapped in CHOICE_FORMULA(...) for choice_formula. Every other control names none and answers empty, which leaves the Default Choice of the variable blank.

Parameters:

Returns: String. The list name, empty when the line names none.


NormaliseControl #

A control read without its case and without a parenthesised tail.

Signature:

Private Function NormaliseControl(ByVal controlValue As String) As String

A setup writes "choice_manual" and also "choice_manual (something)"; both name the same control. This is the rule LinelistSpecs follows.

Parameters:

Returns: String. The control, lower case and cut at the first bracket.


ChoiceFromFormula #

The list name held in a CHOICE_FORMULA(...) control details.

Signature:

Private Function ChoiceFromFormula(ByVal controlDetails As String) As String

The name is the first argument. The head, the closing bracket and anything past the first comma are dropped.

Parameters:

Returns: String. The list name, empty when there is none.


RefreshAddedVariables #

Fill the joined choices values of the variables just added.

Signature:

Private Sub RefreshAddedVariables()

Only a default choice the Choices sheet carried before this import is joined: the labels of a list added by the same import sit where the user types them, and the label column follows once the sheet is edited.


Choices

UpdateChoices #

Add to the Choices sheet every list of the file it lacks, and fill the labels it lacks.

Signature:

Private Sub UpdateChoices(ByVal choicesTable As ListObject, ByVal logger As DiseaseLogger)

The labels travel only when the file is in English; otherwise the list lands with its name and its rows and every label empty. The choices ListObject of the master sheet, when there is one, is stretched over the rows added so the event handlers keep reading them. A list the sheet already carries is not added again, but its empty label cells are filled from an English file. That is the path back for a list added earlier from a file in another language, which lands with its rows and no label at all: the next English file naming the same list writes them. A cell that already holds a label, and a cell answering through a formula, are both left alone.


CollectListLabels #

Gather the labels of one list, in the order the file carries them.

Signature:

Private Sub CollectListLabels(ByRef block As Variant, _
                              ByVal listNameColumn As Long, _
                              ByVal listName As String, _
                              ByVal labelColumn As Long, _
                              ByVal translatedColumn As Long, _
                              ByVal rawColumn As Long, _
                              ByVal shortColumn As Long, _
                              ByVal keepLabels As Boolean, _
                              ByVal labels As BetterArray, _
                              ByVal shortLabels As BetterArray)

The label of a row is the label column when filled, then the translated label, then the non translated label. The short label falls back on the label. With keepLabels False both come out empty.


FillAbsentLabels #

Write the labels of the file into the empty label cells of a list already there.

Signature:

Private Sub FillAbsentLabels(ByRef block As Variant, _
                             ByVal listNameColumn As Long, _
                             ByVal listName As String, _
                             ByVal labelColumn As Long, _
                             ByVal translatedColumn As Long, _
                             ByVal rawColumn As Long, _
                             ByVal shortColumn As Long, _
                             ByVal logger As DiseaseLogger)

The rows of the list are matched by their position: the nth row of the list on the master sheet takes the nth label of the file. That is the order AddChoice wrote them in, so a list added from a file in another language lines up with the English file naming it later. Only a cell that is empty and holds no formula is written, so a label the user typed and a label answered by a formula both stand.

Parameters:


WriteWhenAbsent #

Write a value in a cell that holds nothing, and say whether it was written.

Signature:

Private Function WriteWhenAbsent(ByVal targetCell As Range, ByVal newValue As String) As Boolean

A cell carrying a formula answers its own value and is never written over, whatever that value comes to.

Parameters:

Returns: Boolean. True when the cell took the value.


MasterLabelColumn #

The column of the master Choices sheet holding the labels.

Signature:

Private Function MasterLabelColumn() As Long

The translated label column wins when the sheet carries one; that is the column LLChoices.AddChoice writes, so the fill lands where the add would have.

Returns: Long. The worksheet column, 0 when the sheet carries neither.


MasterChoicesColumn #

One column of the master Choices sheet, found on its header row.

Signature:

Private Function MasterChoicesColumn(ByVal headerName As String) As Long

The header row is the start row of the LLChoices block and it is read from its start column rightwards until it runs out of headers.

Parameters:

Returns: Long. The worksheet column, 0 when the sheet carries no such header.


StretchChoicesTable #

Stretch the choices ListObject over the rows AddChoice wrote under it.

Signature:

Private Sub StretchChoicesTable()

LLChoices writes below the last filled line and knows nothing of the table; the master event handlers read the sheet through the table.


Staging

BuildStagingTable #

Write the dictionary as a disease table on a hidden staging sheet.

Signature:

Private Function BuildStagingTable(ByVal dictionaryTable As ListObject) As ListObject

Seven columns in the disease table order. The order column takes the dictionary order when it is a number and the position of the line otherwise; the choice values column stays empty, its formula comes back once the block has landed. The Choice column of a disease table holds a list name, so it takes what ChoiceNameAt reads and never the control. A dictionary with no named line stages a header-only table.


OrderValue #

The dictionary order of a line when it is a number, its position otherwise.

Signature:

Private Function OrderValue(ByRef block As Variant, ByVal rowIndex As Long, _
                            ByVal orderColumn As Long, ByVal position As Long) As Variant

CountNamedRows #

Count the lines of a block carrying a variable name.

Signature:

Private Function CountNamedRows(ByRef block As Variant, ByVal nameColumn As Long) As Long

Disease Worksheet

BuildDiseaseSheet #

Build a disease sheet for an imported block.

Signature:

Private Function BuildDiseaseSheet(ByVal diseaseName As String, _
                                   ByVal languageTag As String, _
                                   ByVal logger As DiseaseLogger) As Worksheet

PurgeStaleDiseaseName #

Drop a diseases-list entry whose worksheet is gone.

Signature:

Private Sub PurgeStaleDiseaseName(ByVal diseaseName As String)

IsDiseaseSheet #

A disease worksheet is known by its hidden sheetTag.

Signature:

Private Function IsDiseaseSheet(ByVal targetSheet As Worksheet) As Boolean

Lookups

FindTable #

Find a ListObject by name anywhere in the workbook, then by sheet.

Signature:

Private Function FindTable(ByVal sourceBook As Workbook, _
                           ByVal tableName As String, _
                           ByVal sheetName As String) As ListObject

The exported tables carry the names a setup gives its own. A file edited by hand can have lost the table name and kept the sheet, so the first table of the named sheet is the fallback.


FindWorksheet #

Locate a worksheet by name without relying on implicit errors.

Signature:

Private Function FindWorksheet(ByVal targetBook As Workbook, ByVal sheetName As String) As Worksheet

TableBlock #

Read a ListObject with its header row as a two-dimensional block.

Signature:

Private Function TableBlock(ByVal table As ListObject) As Variant

HeaderColumn #

Column of a header in a block read with its header row, 0 when absent.

Signature:

Private Function HeaderColumn(ByRef block As Variant, ByVal headerName As String) As Long

CellAt #

Text of a block cell; a column of 0 reads as empty.

Signature:

Private Function CellAt(ByRef block As Variant, ByVal rowIndex As Long, ByVal columnIndex As Long) As String

DistinctValues #

Distinct values of one column of a block, in first-use order.

Signature:

Private Function DistinctValues(ByRef block As Variant, ByVal columnIndex As Long) As BetterArray

ContainsKey #

Whether a name has already been seen, without regard to case.

Signature:

Private Function ContainsKey(ByVal keys As BetterArray, ByVal key As String) As Boolean

TextOf #

Text of a cell value; an error value or an empty cell reads as empty.

Signature:

Private Function TextOf(ByVal cellValue As Variant) As String

IsEnglish #

A language tag starting with "en" is English.

Signature:

Private Function IsEnglish(ByVal languageTag As String) As Boolean

ResetTallies #

Start the tallies of a new import.

Signature:

Private Sub ResetTallies()

ErrorHandling

ThrowError #

Centralised error raising aligned with ProjectError codes.

Signature:

Private Sub ThrowError(ByVal errNumber As ProjectError, ByVal errMessage As String)

Used in (5 file(s))