6.1.2.11 Strings
Note
This section describes the implementation of MS-VBAL §6.1.2.11 Strings.
The Strings module is represented in the SDK by the interface
IStdStringsModule.
The Strings module is declared in full. MS-VBAL §6.1.2.11 has 43 subsections, and RD-VBA's Strings module
declares 55 members.
Some MS-VBAL subsections declare more than one member:
- the B-suffixed byte variants (
InStrB,LeftB,LenB,MidB,RightB) share a subsection with the member they vary; - the
$-suffixed String-returning twins (Chr$,ChrB$,ChrW$) share a subsection with the member they vary; - the
LTrim/RTrim/Trimgroup is one subsection, and so is its$-suffixed twin.
Note
Not implemented. Of the Strings members, only Len and LenB have a runtime implementation. Calling any
other member raises the run-time error "Application-defined or object-defined error".
6.1.2.11.1 Public Functions
Note
This section describes the implementation of MS-VBAL §6.1.2.11.1 Public Functions.
| § | Member | Declared members | Notes |
|---|---|---|---|
| 6.1.2.11.1.1 | Asc / AscW | Asc |
|
| 6.1.2.11.1.2 | AscB | AscB |
|
| 6.1.2.11.1.3 | AscW | AscW |
|
| 6.1.2.11.1.4 | Chr / Chr$ | Chr, Chr$ |
|
| 6.1.2.11.1.5 | ChrB / ChrB$ | ChrB, ChrB$ |
|
| 6.1.2.11.1.6 | ChrW / ChrW$ | ChrW, ChrW$ |
|
| 6.1.2.11.1.7 | Filter | Filter |
|
| 6.1.2.11.1.8 | Format | Format |
|
| 6.1.2.11.1.9 | Format$ | Format$ |
|
| 6.1.2.11.1.10 | FormatCurrency | FormatCurrency |
|
| 6.1.2.11.1.11 | FormatDateTime | FormatDateTime |
|
| 6.1.2.11.1.12 | FormatNumber | FormatNumber |
|
| 6.1.2.11.1.13 | FormatPercent | FormatPercent |
|
| 6.1.2.11.1.14 | InStr / InStrB | InStr, InStrB |
|
| 6.1.2.11.1.15 | InStrRev | InStrRev |
|
| 6.1.2.11.1.16 | Join | Join |
|
| 6.1.2.11.1.17 | LCase | LCase |
|
| 6.1.2.11.1.18 | LCase$ | LCase$ |
|
| 6.1.2.11.1.19 | Left / LeftB | Left, LeftB |
|
| 6.1.2.11.1.20 | Left$ | Left$ |
|
| 6.1.2.11.1.21 | LeftB$ | LeftB$ |
|
| 6.1.2.11.1.22 | Len / LenB | Len, LenB |
See §6.1.2.11.1.22. |
| 6.1.2.11.1.23 | LTrim / RTrim / Trim | LTrim, RTrim, Trim |
|
| 6.1.2.11.1.24 | LTrim$ / RTrim$ / Trim$ | LTrim$, RTrim$, Trim$ |
|
| 6.1.2.11.1.25 | Mid / MidB | Mid, MidB |
|
| 6.1.2.11.1.26 | Mid$ | Mid$ |
|
| 6.1.2.11.1.27 | MidB$ | MidB$ |
|
| 6.1.2.11.1.28 | MonthName | MonthName |
|
| 6.1.2.11.1.29 | Replace | Replace |
|
| 6.1.2.11.1.30 | Right / RightB | Right, RightB |
|
| 6.1.2.11.1.31 | Right$ | Right$ |
|
| 6.1.2.11.1.32 | RightB$ | RightB$ |
|
| 6.1.2.11.1.33 | Space | Space |
|
| 6.1.2.11.1.34 | Space$ | Space$ |
|
| 6.1.2.11.1.35 | Split | Split |
|
| 6.1.2.11.1.36 | StrComp | StrComp |
|
| 6.1.2.11.1.37 | StrConv | StrConv |
|
| 6.1.2.11.1.38 | String | String |
|
| 6.1.2.11.1.39 | String$ | String$ |
|
| 6.1.2.11.1.40 | StrReverse | StrReverse |
|
| 6.1.2.11.1.41 | UCase | UCase |
|
| 6.1.2.11.1.42 | UCase$ | UCase$ |
|
| 6.1.2.11.1.43 | WeekdayName | WeekdayName |
6.1.2.11.1.22 Len / LenB
Note
This section describes the implementation of MS-VBAL §6.1.2.11.1.22 Len / LenB.
Strings.Len and Strings.LenB are the RD-VBA implementation of MS-VBAL §6.1.2.11.1.22. Both have a runtime
implementation.
MS-VBAL says the pair returns "the number of characters in a string or the number of bytes required to store a
variable on the current platform". It says LenB "will return the same value as Len, except for strings or UDTs":
one function with two exceptions (strings and UDTs), rather than two functions.
Len and LenB are therefore implemented as one measurement, with one option that selects between them.
| Expression | Len |
LenB |
|---|---|---|
A String |
Its number of characters. | Two bytes per character. |
A fixed-length String |
Its declared length. | Twice its declared length. |
Null |
Null |
Null |
| Any other scalar | The bytes it occupies. | The same as Len: the bytes it occupies. |
| A UDT | "the size as it will be written to the file" | "the in-memory size, including any implementation-specific padding between elements" |
UDT sizes
The UDT row is the one that needs the platform to know two different sizes for the same value. 🎯 A UDT has two
sizes: Len reports its serialized size (its members concatenated, with no padding), and LenB reports its
in-memory size, which is also what
VBUserDefinedTypeValue.Size reports.
RD-VBAL §2.5.2.1.3 User-Defined Type (UDT) Values defines both UDT sizes and
holds the padding rule. Strings.Len and Strings.LenB make both sizes of a UDT observable to a program.
A record whose members include a variable-length String is the case MS-VBAL warns cannot be predicted: "Len might
not be able to determine the actual number of storage bytes required when used with variable-length strings in
user-defined data types". For such a record, Len counts the characters the member currently holds and LenB counts
the pointer, so the two move independently of each other.
Declared types at external dispatch
👉 An external call carries runtime values rather than typed ones, so the declared type of the value a member was
called with is recovered at external dispatch
(RD-VBAL §5.3.1.11 Procedure Invocation Argument Processing).
The declared type survives external dispatch because each intrinsic stores its own exact managed type: a short for
Integer and an int for Long, not one integer type for both
(RD-VBAL §2.5.2.1.1 Numeric Values).
👉 This is what lets Len return "the number of bytes required to store a variable" for the variable it is given.
Date and Double are indistinguishable at external dispatch. That costs Len nothing, because they have the same
width; a parameter declared Date will need its declared type to recover its argument.
⏮️ RD-VBAL §6.1.2.10 Math | ⏭️ RD-VBAL §6.1.2.12 SystemColorConstants