85. Variant and Lotus scriptvariant in BASIC and Lotus script
Origin
Recently, I read back my Notes on Notes and found that in the Notes bugs category, there is almost no difference between the two numbers.
2. 'Type mismatch' occurs if an nested array e.g. when an item of ColumnValues is an array, is assigned to a variant or passed as an argument of a function.
4. When an item of ColumnValues is an array, 'Type mismatch' occurs if it is assigned to a variant, e. g. columns = entry. Columnvalues
There are at least two things. First, when I first encountered the above errors and recorded them, I did not pay attention to them or even forgot them completely. The next time I hit them again, I would also generate a new discovery record. Second, I keep my English at the same level and have the same style in describing the same thing.
I think it is necessary to explain the lesson of falling down twice in the same place. It can not only remind you not to repeat my mistakes, but also deepen my impression, so as not to repeat the next time.
Source of Variant in Lotus script
To fully understand this problem and increase the number of words, we should start with variant. Visual Basic variant is a data structure that can accommodate various data types [NOTE 1 ]. Technically speaking, it is taggedunion (tag-based union), which occupies 16 bytes of memory. The first two bytes store the data type encoding (that is, tags ), section 3 to section 8 is blank for alignment, and the actual data (that is, Union) is stored in a total of eight bytes from the ninth to sixteen ). The content of the first two bytes can be returned using the VarType function as follows:
Constant |
Value |
Description |
VbEmpty |
0 |
Empty (uninitialized) |
VbNull |
1 |
Null (no valid data) |
VbInteger |
2 |
Integer |
VbLong |
3 |
Long integer |
VbSingle |
4 |
Single-precision floating-point number |
VbDouble |
5 |
Double-precision floating-point number |
VbCurrency |
6 |
Currency value |
VbDate |
7 |
Date value |
VbString |
8 |
String |
VbObject |
9 |
Object |
VbError |
10 |
Error value |
VbBoolean |
11 |
Boolean value |
VbVariant |
12 |
Variant (used only with arrays of variants) |
VbDataObject |
13 |
A data access object |
VbDecimal |
14 |
Decimal value |
VbByte |
17 |
Byte value |
VbLongLong |
20 |
LongLong integer (Valid on 64-bit platforms only .) |
VbUserDefinedType |
36 |
Variants that contain user-defined types |
VbArray |
8192 |
Array |
Because the variant can accommodate various data types, it immediately brings both positive and negative effects. The disadvantage is that the type check during compilation is canceled and errors are easily introduced. The advantage is that you can write more flexible code without the limitations of static types [NOTE 2 ].
Usage and features
Lotus script is a BASIC-style scripting language that inherits the features of BASIC when it was invented, including shaping. The variants in Lotus script can accommodate all data types except user-defined types. The Return Value of the DataType function for determining the specific data type is as follows:
Return |
Value type |
Constant |
Variants only |
0 |
EMPTY |
V_EMPTY |
Yes |
1 |
NULL |
V_NULL |
Yes |
2 |
Integer |
V_INTEGER |
|
3 |
Long |
V_LONG |
|
4 |
Single |
V_SINGLE |
|
5 |
Double |
V_DOUBLE |
|
6 |
Currency |
V_CURRENCY |
|
7 |
Date/Time |
V_DATE |
Yes |
8 |
String |
V_STRING |
|
9 |
OLE object or NOTHING |
V_DISPATCH |
Yes |
10 |
OLE error |
V_ERROR |
Yes |
11 |
Boolean |
V_BOOLEAN |
|
12 |
Variant list or array |
V_VARIANT |
|
13 |
IUNKNOWN (OLE value) |
V_IUNKNOWN |
Yes |
17 |
Byte |
V_BYTE |
|
34 |
User-defined object |
V_LSOBJ |
|
35 |
Product object |
V_PRODOBJ |
|
2048 |
List |
|
|
8192 |
Fixed array |
|
|
8704 |
Dynamic array |
|
|
For the last three items in the table above as the container, the return value of DataType is the sum of the values corresponding to them plus the type values of the elements they contain. For example, for a fixed string array, get 8192 + 8 = 8200; for a dynamic variant array, get 8704 + 12 = 8716. Note that the type value 12 of the variant is used only for the variant list and array, because when DataType is applied to a single variant, the specific data type value that it contains is obtained.
I prefer the sense of certainty brought by static type variables and the sense of security ensured by the type check during compilation, so unless in special circumstances, I do not like to use the variant. However, the limitations of the syntax of Lotus script make it unusable in some cases.
1. The return type of the function cannot be declared as an array. If this is required, only the variant type can be used.
2. The methods of custom objects do not support overloading. You can only use the variant type when multiple types of parameters are required.
3. the array variable cannot be assigned as a whole, for example, from Split () or doc. ItemName, it can only be changed.
When an array value is assigned to a variant, it points to a new array instead of the original array. Therefore, the Data Change of the original array cannot be read from it.
Dim logger As Log4DomSet logger=GetLogger(Nothing )Dim vDim fa(0) As Stringv=falogger.PrintMsg(v(0))'[1]14:56:03:63 - fa(0)="fa" '[1]14:56:07:67 - logger.PrintMsg(v(0))
As shown above, when the content of the original array fa has been changed, the array contained in the variant v is not affected.
Problem
Although the above mentioned changes are not tortuous, there are still rules to follow and be able to understand. Next, let's talk about the behaviors I mentioned at the beginning of this article that neither document nor understand.
Search for NotesDocument or NotesViewEntry through the view, and then read the relevant data from them is the most common situation in programming. In this case, if you read the field or calculated value displayed in the view, the column value in the view is the index (84. from the View index, the Notes database (below) is faster than reading documents. For example:
Dim vDim fa(0) As Stringv=fafa(0)="fa"Dim da() As StringReDim da(0)da(0)="da"Dim container(2) As Variant'v=container 'No error'Print "DataType(container): " & DataType(container) '8204'Print "DataType(v): " & DataType(v) '8716'container(0)=1'v=container 'No error'Set container(0)=New NotesSession'v=container 'No error'container(0)=fa'container(1)=da'v=container 'Error
When you assign a variant array to a variant variable, if the elements of the variant array are Scalar values such as Empty, number, and string, or object values such as NotesDocument, no problem. If the element is an array, an error occurs. In other words, a variant variable cannot contain two or more nested arrays. Is this inherited from BASIC? Why? I don't know yet. Therefore, when ColumnValues and multi-value columns are used, you cannot assign them to a variant variable. Instead, you can only keep writing
forall e in entry.ColumnValues (1)print eend forall
Note 1: Apart from fixed-length strings and user-defined types, other data types can be accommodated before VB6. VB6 also supports user-defined types.
NOTE 2: In VB, because it is often necessary to interact with OLE objects, and objects such as Collection type and IDispatch interface involve objects of undetermined types during compilation, you must use a variant. The Optional (Optional) function parameter of VB may be omitted during the call and has no content. It must also be defined as a variant. In addition, the method call of a variant object is late binding and can be used to write more common code.