ShowHide

Holds the list of variables one worksheet layer offers the user, and the visible or hidden choice for each of them. The list is built from the dictionary. EntryCount, FieldKey, HeaderText, IsHidden, PositionIndex, ControlType and AuthoredVertical read one entry, IndexOf and HasField find one, SetHidden and SetAllOptionalHidden change the choices, SetHiddenInRange and RangeState do the same for a whole span of positions, Apply writes them through a layout, Adopt reads them back from a saved set and ResetToAuthored puts the choices, the sheet and the printed header directions back where the dictionary started them. The class reads the dictionary alone: the worksheet is ShowHideLayout's work and the saved choices are ShowHideStore's.

A SECTION IS A SPAN OF POSITIONS

Hiding a whole section is SetHiddenInRange over the positions SectionMap recorded for it. Nothing about a section is stored here or anywhere else: the choice lands on the member entries, so it travels through the store and through a migration file with no column of its own, and there is no second record that could disagree with the first.

FOUR KINDS OF ENTRY

A variable the dictionary marks as hidden is EXCLUDED. It never enters the list, because the designer said the user must never see it.

Of the variables that do enter, each is one of three kinds:

mandatory listed, always visible, the user cannot change it. locked listed, always hidden, the user cannot change it. A calculated column on a printed sheet or on a CRF lands here, and so does an automatic list: both are named by their CONTROL, never by the "list auto" column, which is about something else entirely. free listed, starts where the dictionary says, follows the user.

IsFree is the single question a click handler asks before it changes anything.

WHICH DICTIONARY COLUMN SAYS WHAT

HList, VList visibility Printed register book CRF crf status

The position of a variable comes from column index, and from crf index on the CRF layer. A variable with no position is listed, and the layout leaves it where it is.

THE STATE IS A BOOLEAN

Hidden is True or False. The display words the form shows ("Shown", "Hidden", "Mandatory") are translated at the form and stored nowhere. A user who changes the interface language between two sessions keeps every choice.

Depends on: LLdictionary, LLVariables, ShowHideLayout, BetterArray, Checking, Dictionary column names, The one register book value that asks for a turned header

Version: 1.2 (2026-08-11)

Instantiation

Create #

create

Build the entry list of one layer of one sheet

Signature:

Public Function Create(ByVal dict As LLdictionary, _
                       ByVal layer As Byte, _
                       ByVal sheetName As String) As ShowHide

The factory and the build it runs.

Walks the dictionary once, keeps the variables of the named sheet whose sheet type suits the layer, and files each one as mandatory, locked or free. The dictionary is prepared when it arrives unprepared, because the four columns this class reads (visibility, crf status, column index, crf index) are all written by Prepare.

Parameters:

  • dict: LLdictionary. The dictionary to read.
  • layer: Byte. A ShowHideWorksheetLayer value. Which of the four layers to build.
  • sheetName: String. The base sheet name, with no print_ or crf_ prefix.

Returns: ShowHide. The entry list, ready to read.

Throws:

  • ProjectError.ObjectNotInitialized When the dictionary is Nothing.
  • ProjectError.InvalidArgument When the sheet name is empty or the layer is outside the four values.

Accessors

EntryCount #

entry-count

The number of entries the user is offered

Signature:

Public Property Get EntryCount() As Long

What the list holds, and what each entry is.


TargetLayer #

target-layer

The layer this list was built for

Signature:

Public Property Get TargetLayer() As Byte

SheetName #

sheet-name

The base sheet name the entries belong to

Signature:

Public Property Get SheetName() As String

FieldKey #

field-key

The variable name of one entry

Signature:

Public Function FieldKey(ByVal index As Long) As String

Parameters:

  • index: Long. A one based entry index.

Returns: String. The variable name as the dictionary spells it.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

HeaderText #

header-text

The label the form shows for one entry

Signature:

Public Function HeaderText(ByVal index As Long) As String

Parameters:

  • index: Long. A one based entry index.

Returns: String. The main label, carrying its sub section for a geo or hf variable.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

IsHidden #

is-hidden

Whether one entry is hidden right now

Signature:

Public Function IsHidden(ByVal index As Long) As Boolean

A mandatory entry answers False and a locked entry answers True, whatever the user asked for. Every other entry answers the stored choice.

Parameters:

  • index: Long. A one based entry index.

Returns: Boolean. True when the variable is hidden.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

IsMandatory #

is-mandatory

Whether one entry is always visible

Signature:

Public Function IsMandatory(ByVal index As Long) As Boolean

Parameters:

  • index: Long. A one based entry index.

Returns: Boolean. True when the user cannot hide the variable.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

IsLocked #

is-locked

Whether one entry is always hidden

Signature:

Public Function IsLocked(ByVal index As Long) As Boolean

Parameters:

  • index: Long. A one based entry index.

Returns: Boolean. True when the variable is held hidden and the user cannot show it.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

IsFree #

is-free

Whether the user may change one entry

Signature:

Public Function IsFree(ByVal index As Long) As Boolean

The single guard a click handler asks. An entry that is neither mandatory nor locked follows whatever the user picks.

Parameters:

  • index: Long. A one based entry index.

Returns: Boolean. True when the entry follows the user.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

PositionIndex #

position-index

Where one entry sits on the worksheet

Signature:

Public Function PositionIndex(ByVal index As Long) As Long

Parameters:

  • index: Long. A one based entry index.

Returns: Long. The column or row number, or 0 when the dictionary gives none.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

ControlType #

control-type

The dictionary control of one entry

Signature:

Public Function ControlType(ByVal index As Long) As String

Parameters:

  • index: Long. A one based entry index.

Returns: String. The control value in lower case, such as "geo1" or "formula".

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

AuthoredVertical #

authored-vertical

The header direction the dictionary asked for

Signature:

Public Function AuthoredVertical(ByVal index As Long) As Boolean

Read only, and true for a variable whose register book reads "print, vertical header". A reset restores this direction without the entry list ever owning the live orientation of the sheet.

Parameters:

  • index: Long. A one based entry index.

Returns: Boolean. True when the printed header should be turned.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

Lookup

IndexOf #

index-of

Find an entry by variable name

Signature:

Public Function IndexOf(ByVal fieldKey As String) As Long

Finding an entry by its variable name.

The name is trimmed and lower cased on the way in and on the way out, so a dictionary name carrying a stray space is still reachable.

Parameters:

  • fieldKey: String. The variable name to look for.

Returns: Long. The one based entry index, or 0 when the name is absent.


HasField #

has-field

Whether a variable name is in the list

Signature:

Public Function HasField(ByVal fieldKey As String) As Boolean

Parameters:

  • fieldKey: String. The variable name to look for.

Returns: Boolean. True when the list carries the name.


Choices

SetHidden #

set-hidden

Hide or show one entry

Signature:

Public Sub SetHidden(ByVal index As Long, ByVal hidden As Boolean)

Changing what the user sees.

A mandatory or locked entry keeps its state and the call returns quietly, so a caller that loops the whole list needs no guard of its own.

Parameters:

  • index: Long. A one based entry index.
  • hidden: Boolean. True to hide the variable.

Throws:

  • ProjectError.InvalidArgument When the index is out of range.

SetAllOptionalHidden #

set-all-optional-hidden

Hide or show every entry the user owns

Signature:

Public Sub SetAllOptionalHidden(ByVal hidden As Boolean)

Parameters:

  • hidden: Boolean. True to hide all the free entries.

SetHiddenInRange #

set-hidden-in-range

Hide or show every entry sitting in a span of positions

Signature:

Public Function SetHiddenInRange(ByVal firstPos As Long, _
                                 ByVal lastPos As Long, _
                                 ByVal hidden As Boolean) As Long

What hiding a whole section comes down to. The span is a range of column numbers on an HList sheet and of row numbers on a VList one, which is what SectionMap records for each section.

Hiding a section stores nothing of its own: the choice lands on each member entry, so the store, the show/hide form and a migration file all carry a collapsed section without knowing the word "section". Nothing can drift out of step with anything else, because there is only one record of the choice.

A mandatory or locked entry inside the span keeps its state, as it does everywhere else. So a section holding a mandatory variable never disappears whole, and the count says how many entries actually moved.

Parameters:

  • firstPos: Long. One end of the span.
  • lastPos: Long. The other end of the span.
  • hidden: Boolean. True to hide the span.

Returns: Long. How many entries the call changed.


RangeState #

range-state

Where a span of positions stands

Signature:

Public Function RangeState(ByVal firstPos As Long, ByVal lastPos As Long) As Byte

Read from the entries the user owns, so a section whose only visible column is a mandatory one still answers Hidden and a caller toggling it offers Show.

Parameters:

  • firstPos: Long. One end of the span.
  • lastPos: Long. The other end of the span.

Returns: Byte. A ShowHideRangeState value. Empty when no entry sits in the span, Fixed when none of those that do is free, and otherwise Shown, Hidden or Mixed by what the free entries say.


Worksheet

Apply #

apply

Put the worksheet in the state the list describes

Signature:

Public Function Apply(ByVal layout As ShowHideLayout) As Long

The two calls that put the list and a sheet in step.

The one place the entry list reaches a sheet, and it goes through the layout, so the row versus column question and the protection bracket are answered in one place. Entries with no position are skipped.

Parameters:

  • layout: ShowHideLayout. The sheet to reconcile.

Returns: Long. The number of positions that were set.


Adopt #

adopt

Read the worksheet back into the list

Signature:

Public Function Adopt(ByVal layout As ShowHideLayout) As Long

For the case where the user hid a column by hand rather than through the form. Mandatory and locked entries keep what the dictionary said.

Parameters:

  • layout: ShowHideLayout. The sheet to read.

Returns: Long. The number of entries that were read.


ResetToAuthored #

reset-to-authored

Put the choices and the sheet back where the dictionary started them

Signature:

Public Function ResetToAuthored(ByVal layout As ShowHideLayout) As Long

The reset button of the advanced form comes through here, once per worksheet. Every free entry goes back to the hidden or visible state the dictionary authored, the sheet is put in step through Apply, and on a printed sheet each header direction goes back to what register book asked. Mandatory and locked entries never left their authored state, so they are covered by the same walk.

Parameters:

  • layout: ShowHideLayout. The sheet to reconcile, or Nothing to reset the choices alone.

Returns: Long. The number of positions Apply set.


Build

Initialise #

initialise

Fill the entry list from the dictionary

Signature:

Public Sub Initialise(ByVal dict As LLdictionary, _
                      ByVal layer As Byte, _
                      ByVal sheetName As String)

The dictionary walk the factory runs.

Public because the factory calls it on a fresh instance. Every variable of the sheet is read once and the arrays are trimmed to what matched.

Parameters:

  • dict: LLdictionary. The dictionary to read.
  • layer: Byte. A ShowHideWorksheetLayer value. The layer being built.
  • sheetName: String. The base sheet name.

Internal members (not exported)

Helpers

EffectiveHidden #

effective-hidden

Work out the state one entry really has

Signature:

Private Function EffectiveHidden(ByVal index As Long) As Boolean

Private workers of the build and the accessors.

Parameters:

Returns: Boolean. True when the entry is hidden.


PositionInRange #

position-in-range

Whether one entry sits inside a span of positions

Signature:

Private Function PositionInRange(ByVal position As Long, _
                                 ByVal firstPos As Long, _
                                 ByVal lastPos As Long) As Boolean

The two bounds are read in either order, so a caller that hands them over the other way round gets the same answer. An entry with no position, which is what a variable the dictionary gives no column index looks like, is in no span.

Parameters:

Returns: Boolean. True when the position falls inside the span.


MatchesSheet #

matches-sheet

Whether a variable belongs to the sheet being built

Signature:

Private Function MatchesSheet(ByVal vars As LLVariables, ByVal varName As String) As Boolean

Parameters:

Returns: Boolean. True when the sheet names agree.


MatchesLayer #

matches-layer

Whether a dictionary sheet type suits the layer being built

Signature:

Private Function MatchesLayer(ByVal sheetType As String) As Boolean

The dictionary vocabulary is "vlist1D" and "hlist2D". A printed sheet and a CRF are both derived from an hlist2D sheet, so all three of HList, Printed and CRF test for "hlist". The CRF case used to test for "crf", a word the vocabulary has never held, so every CRF list came back empty.

Parameters:

Returns: Boolean. True when the variable belongs on this layer.


StatusForLayer #

status-for-layer

Read the status column that belongs to the layer

Signature:

Private Function StatusForLayer(ByVal vars As LLVariables, _
                             ByVal varName As String, _
                             ByVal registerBook As String, _
                             ByVal hasVisibility As Boolean, _
                             ByVal hasStatus As Boolean, _
                             ByVal hasCrfStatus As Boolean) As String

Parameters:

Returns: String. The status text for this layer.


IsMandatoryStatus #

is-mandatory-status

Whether a status makes an entry always visible

Signature:

Private Function IsMandatoryStatus(ByVal layerStatus As String, _
                                   ByVal controlVal As String, _
                                   ByVal layer As Byte) As Boolean

The first geo level of an HList sheet is mandatory whatever its status says, because the geo cascade of every other level reads it.

Parameters:

Returns: Boolean. True when the user cannot hide the entry.


IsLockedStatus #

is-locked-status

Whether a status holds an entry hidden

Signature:

Private Function IsLockedStatus(ByVal layerStatus As String, _
                                ByVal controlVal As String, _
                                ByVal layer As Byte, _
                                ByVal isMandatoryEntry As Boolean) As Boolean

A calculated column and an automatic list have nothing to give on a printed sheet or a CRF, so both layers hold them hidden. A mandatory entry is never locked as well.

Parameters:

Returns: Boolean. True when the entry is held hidden.


InitialHidden #

initial-hidden

The state a free entry starts in

Signature:

Private Function InitialHidden(ByVal layerStatus As String) As Boolean

The register book vocabulary of a printed sheet is "print, horizontal header", "print, vertical header" and "hidden". An empty cell means the column prints, which is why the default answer is visible.

Parameters:

Returns: Boolean. True when the entry starts hidden.


SafeValue #

safe-value

Read a dictionary cell and answer empty when it is absent

Signature:

Private Function SafeValue(ByVal vars As LLVariables, _
                           ByVal colName As String, _
                           ByVal varName As String) As String

Parameters:

Returns: String. The cell value, or an empty string.


Normalise #

normalise

Trim and lower case a value for comparison

Signature:

Private Function Normalise(ByVal value As String) As String

Parameters:

Returns: String. The trimmed, lower cased text.


NormaliseKey #

normalise-key

Build the lookup key of a variable name

Signature:

Private Function NormaliseKey(ByVal value As String) As String

The same shape on the way in and on the way out. A dictionary name carrying a trailing space used to be stored untrimmed and looked up trimmed, so its saved state was dropped on every load.

Parameters:

Returns: String. The lookup key.


EnsureValidIndex #

ensure-valid-index

Refuse an entry index outside the list

Signature:

Private Sub EnsureValidIndex(ByVal index As Long)

Parameters:

Throws:


ValidateLayer #

validate-layer

Refuse a layer outside the four values

Signature:

Private Sub ValidateLayer(ByVal layer As Byte)

Parameters:

Throws:


ThrowError #

throw-error

Raise a project error naming this class

Signature:

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

Parameters:


Used in (14 file(s))