In AskiaScript, a variant is a special type of variable that can hold several different basic type values: null, boolean, number, string, date, array and dictionary. Whenever a variable's type cannot be known by the compiler in advance, AskiaScript provides a variant type. The variant type is flexible enough to allow you to convert the value stored in the variable during run-time to an appropriate variable type.
For example, when you iterate through an array of questions, the Value property could have different types depending on the question type (number for a numeric question, string for an open-ended question etc...). In this situation, the Value of the anonymous question would be a Variant.
You can always compare a variant with an appropriate type, or convert the variant to that type.
In this topic:
To create a variant variable, assign a variant to a variable or declare a variable as a variant.
Dim myValue = Q1.Value
Dim myValue As Variant
Because the variant can host several types, you can directly assign the value of any of those types to a variant, as follows:
Number and later change its value to a String, as follows:
Dim myValue As Variant = 12 myValue.InnerTypeOf() ' => number myValue = "Hello" myValue.InnerTypeOf() ' => stringThis is possible because the variable type (returned by
TypeOf) is always a variant.Null.
Dim myValue As Variant myValue.InnerTypeOf() ' => null
| From / To | ToBoolean | ToNumber | ToDate | ToString | ToArray | ToDictionary |
|---|---|---|---|---|---|---|
| Null | False |
DK |
DK |
"null".Same as Null.ToString() |
@[] |
@{} |
| Boolean | Value |
0 or 1.Same as Boolean.ToNumber() |
DK |
"false" or "true".Same as Boolean.ToString() |
@[value] |
@{} |
| Number | 0 / DK is False,otherwise True. |
Value |
Date from Epoch(1). Same as Number.ToDate() |
"value".Same as Number.ToString() |
@[value] |
@{} |
| DK | False |
DK |
DK |
"-999999.99"Same as Number.ToString() |
@[DK] |
@{} |
| Date | Epoch(1) / DK is False,otherwise True. |
Number from Epoch(1). Same as Date.ToNumber() |
value |
Date as string. Same as Date.ToString() |
@[value] |
@{} |
| String | "" is False,otherwise True. |
Try conversion. Same as String.ToNumber() |
Try conversion. Same as String.ToDate() |
value |
@[value] |
@{} |
| Array | Try to convert the first item. Same as Array[1].ToBoolean(). |
Try to convert the first item. Same as Array[1].ToNumber() |
Try to convert the first item. Same as Array[1].ToDate() |
Array as string. Same as Array.ToString() |
value |
Try to convert the first item. Same as Array[1].ToDictionary() |
| Dictionary | Empty dictionary Dictionary.Keys.Count = 0 is False,otherwise True. |
Number of key/value pairs. Same as Dictionary.Keys.Count |
DK |
Dictionary as string. Same as Dictionary.ToString() |
@[value] |
value |
| From / To | ToBoolean | ToNumber | ToDate | ToString | ToArray | ToDictionary |
(1) Epoch is the 30/12/1899 00:00:00 which is equal to 0.
AskiaScript provides automatic casting or conversion on Variant type variables. This means that all operators, properties and (read-only) methods from types that could be held by a Variant are available on the Variant itself. For example, the method Sum(), which is available for Array variables, and not explicily for Variant, is still available on Variants.
During the run-time execution of the script, the engine could:
Array and Dictionary), if the method changes the underlying object and is not of the right type, the object is not modified.The rules for automatic casting and conversion are as follows:
Number > String > NumberArray > StringArray > Array > Date > Boolean > Dictionary > Null
Does the property/method exist on a variant?
Dim myVariant As Variant = @["abc", 1] myVariant.ToNumber() ' DK => Use the VARIANT[1].ToNumber() method
Dim myVariant As Variant = @["abc", 1] myVariant.TypeOf() ' "variant" => Use the VARIANT.TypeOf() method
When the property/method doesn't exist on variant.
Does the property/method exist on the inner variable type?
Dim myVariant As Variant = @["abc", 1]
myVariant.Join(", ") ' "abc, 1" => The InnerTypeOf() is an Array
' The Join() method exist on the inner variable type, so use it.
Dim myVariant As Variant = "abc,1"
myVariant.Split(",") ' {"abc"; "1"} => The InnerTypeOf() is a String
' The Split() method exist on the inner variable type, so use it.
Dim myVariant As Variant = "54321"
myVariant.IndexOf("2") ' 4 => The InnerTypeOf() is a String.
' The IndexOf() (with a string argument) method exist on the inner variable type, so use it.
When the property/method doesn't exist on a variant, nor on the inner variable type.
Is the property/method compatible with only one variable type?
Dim myVariant As Variant = #25/03/2011 16:32:07#
myVariant.Round(2) ' 40627.69 => The Round() is only available for Number
' Convert to number first using the VARIANT.ToNumber() method:
' It result to 40627.688969907409, then use the Round() method:
' It result to 40627.69
Dim myVariant As Variant = "22/03/2011"
myVariant.Day ' 22 => The Day property is only available for Date
' Convert to date first using the VARIANT.ToDate() method:
' It result to #22/03/2011#, then use the Day property:
' It result to 22
When the property/method doesn't exist on a variant, nor on the inner variable type,nor is it compatible with only one variable type.
Is it possible to determine the method using the arguments?
Dim myVariant As Variant = 54321
myVariant.IndexOf(@["a", 1]) ' DK => The IndexOf() is available for String, NumberArray, StringArray and Array.
' We can only use the Array argument for the IndexOf() of Array.
' Convert to Array first using the VARIANT.ToArray() method:
' It result to @[54321], then use the IndexOf() method:
' It result to DK
When the property/method doesn't exist on variant, nor on the inner variable type, nor is it compatible with only one variable type, nor can it be determined using the method arguments.
Use the following priority to convert:
Number > String > Date > Boolean > NumberArray > StringArray > Array > Dictionary
Dim myVariant As Variant = 54321
myVariant.IndexOf(54321) ' 1 => The IndexOf() is available for String, NumberArray, StringArray and Array.
' Using the arguments (rule 4.), we can reduce the list of matching types to: NumberArray and Array.
' The NumberArray have a priority to the Array, so convert to NumberArray:
' It result to {54321}, then use the IndexOf() method:
' It result to 1
Dim myVariant As Variant = 54321
myVariant.IndexOf("2") ' 4 => The IndexOf() is available for String, NumberArray, StringArray and Array.
' Using the arguments (rule 4.), we can reduce the list of matching types to: String, StringArray and Array.
' The String have a priority to the StringArray and Array, so convert to String:
' It result to "54321", then use the IndexOf() method:
' It result to 4
Dim myVariant As Variant = "1.2"
myVariant.Format("0.00") ' "1.20" => The Format() is available for Number and Date.
' The format string argument is available for number and date.
' Convert to Number first using the VARIANT.ToNumber() method:
' It result to 1.2, then use the Format() method:
' It result to "1.20"
Dim myVariant As Variant = "22/03/2011"
myVariant.Format("yyyy-MM-dd") ' DK => The Format() is available for Number and Date.
' The format string argument is available for number and date.
' Convert to Number first using the VARIANT.ToNumber() method:
' It result to DK
Use the JSON string in argument to initialize the value of the variant.
Returns a successful value if the operation succeeds, otherwise it returns a failed value.
Returns a MethodResult.
Dim items As Variant
Dim result = items.LoadJSON("invalid json format")
' result.Success ' => False
' result.ErrorMessage ' => "SyntaxError: Unexpected token i in JSON at position : 0"
' items ' => Null
' items.InnerTypeOf() ' => "null"
Dim items as Variant
Dim result = items.LoadJSON("null")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => Null
' items.InnerTypeOf() ' => "null"
Dim items as Variant
Dim result = items.LoadJSON("true")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => True
' items.InnerTypeOf() ' => "boolean"
Dim items as Variant
Dim result = items.LoadJSON("false")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => False
' items.InnerTypeOf() ' => "boolean"
Dim items as Variant
Dim result = items.LoadJSON(""A valid json string"")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => "A valid json string"
' items.InnerTypeOf() ' => "string"
Dim items as Variant Dim result = items.LoadJSON(25) ' result.Success ' => True ' result.ErrorMessage ' => "" ' items ' => 25 ' items.InnerTypeOf() ' => "number"
Dim items as Variant
Dim result = items.LoadJSON("[1,"abcde",true]")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => @[1, "abcde", True]
' items.InnerTypeOf() ' => "array"
Dim items as Variant
Dim result = items.LoadJSON("{"key1":"value1", "key2":12}")
' result.Success ' => True
' result.ErrorMessage ' => ""
' items ' => @{"key1" : "value1", "key2", 12}
' items.InnerTypeOf() ' => "dictionary"
Converts whatever value is inside the variant to a boolean.
See also: Truthly/Falsy topic.
Returns a Boolean.
See:
Always returns False.
Dim nil As Variant = Null nil.ToBoolean() ' => False
Returns an identical boolean.
Dim b As Variant = True b.ToBoolean() ' => True
Returns False when the number is 0 or DK, otherwise it returns True.
Dim n As Variant = 1 n.ToBoolean() ' => True
Dim n As Variant = 0 n.ToBoolean() ' => False
Dim n As Variant = 12 n.ToBoolean() ' => True
Returns False when the value is #30/12/1899 00:00:00# (Zero) or DK, otherwise it returns True.
Dim dt As Variant = #12/03/2015# dt.ToBoolean() ' => True
Dim dt As Variant =#30/12/1899 00:00:00# dt.ToBoolean() ' => False
Returns False when the string is empty, otherwise it returns True.
Dim str As Variant = "abcde" str.ToBoolean() ' => True
Dim str As Variant = "" str.ToBoolean() ' => False
Dim str As Variant = "False" str.ToBoolean() ' => True
Return False if the array is empty, otherwise it return True
Dim arr As Variant = @[0, 5, 6] arr.ToBoolean() ' => True
Dim arr As Variant = @[] arr.ToBoolean() ' => False
Returns False if the dictionary is empty, otherwise it returns True.
Dim dic As Variant = @{"key" : "value"}
dic.ToBoolean() ' => True
Dim dic As Variant = @{}
dic.ToBoolean() ' => False
Converts whatever value is inside the variant to a number.
Returns a Number.
See:
Always returns DK.
Dim nil As Variant = Null nil.ToNumber() ' => DK
Converts the boolean to its numerical representation: 0 for False and 1 for True.
Dim b As Variant = True b.ToNumber() ' => 1
Dim b As Variant = False b.ToNumber() ' => 0
Returns an identical number.
Dim n As Variant = 123 n.ToNumber() ' => 123
Dim n As Variant = 1.5 n.ToNumber() ' => 1.5
Converts the date to a number. Same as Date.ToNumber().
Dim dt As Variant = #25/03/2011 16:32:07# dt.ToNumber() ' => 40627.688969907409
Tries to convert the string to a number. Same as String.ToNumber().
Dim str As Variant = "abcde" str.Value.ToNumber() ' => DK (not a valid number)
Dim str As Variant = "123" str.ToNumber() ' => 123
Dim str As Variant = "123.99" str.ToNumber() ' => 123.99
Dim str As Variant = "123,456" str.ToNumber() ' => 123.456
Dim str As Variant = "123,456.789" str.ToNumber() ' => DK (not a valid number) ' The thousand separator generate an exception
Returns the number of items inside the array. Same as Array.Count.
Dim arr As Variant = @[12, 15, 16] arr.ToNumber() ' => 3
Dim arr As Variant = @["a", "b"] arr.ToNumber() ' => 2
Dim arr As Variant = @["123"] arr.ToNumber() ' => 1
Returns the number of dictionary keys. Same as Dictionary.Keys.Count.
Dim dic As Variant = @{"key1" : "value1", "key2" : "value2"}
dic.ToNumber() ' => 2
Dim dic As Variant = @{}
dic.ToNumber() ' => 0
Converts whatever value is inside the variant to a date.
Returns a Date.
Returns DK when the conversion fails.
See:
Always returns DK.
Dim nil As Variant = Null nil.ToDate() ' => DK
Always returns DK.
Dim b As Variant = True b.ToDate() ' => DK
Dim b As Variant = False b.ToDate() ' => DK
Converts the number to a date.
Dim n As Variant = 40627.688969907409 n.ToDate() ' => #25/03/2011 16:32:07#
Returns an identical date.
Dim dt As Variant = #25/03/2011 16:32:07# dt.ToDate() ' => #25/03/2011 16:32:07#
Tries to convert the string to a date, as with String.ToDate().
Dim str As Variant = "22/03/2011" str.ToDate() ' => #22/03/2011#
Dim str As Variant = "2011-03-22" str.ToDate() ' => #22/03/2011#
Dim str As Variant = "abcde" str.ToDate() ' => DK (Invalid date)
Always returns DK.
Dim arr As Variant = @[#12/03/2015#, #14/02/2015#] arr.ToDate() => DK
Always returns DK.
Dim dic As Variant = @{"key1" : #12/03/2015#}
dic.ToDate() => DK
Converts whatever value is inside the variant to a string.
Returns a String.
See:
Converts the null to a string. Same as Null.ToString().
Dim nil As Variant = Null nil.ToString() ' => "null"
Converts the boolean to a string. Same as Boolean.ToString().
Dim b as Variant = True b.ToString() ' => "true"
Dim b as Variant = False b.ToString() ' => "false"
Converts the number to a string. Same as Number.ToString().
Dim n As Variant = 123 n.ToString() ' => "123"
Dim n As Variant = 1.5 n.ToString() ' => "1.5"
Converts the date to a string. Same as Date.ToString().
Dim dt As Variant = #25/03/2011 16:32:07# dt.ToString() ' => "25/03/2011 16:32:07" or "3/25/2011 04:32:07 PM" ' depending on the regional settings
Returns an identical string.
Dim str As Variant = "abcde" str.ToString() ' => "abcde"
Converts the array to a string representation. Same as Array.ToString().
Dim arr As Variant = @[1, 2, 3] arr.ToString() ' => "1,2,3"
Dim arr As Variant = @["a", "b", "c"] arr.ToString() ' => "a,b,c"
Dim arr As Variant = @[#21/03/2009#, #23/07/2010#, #26/12/2011#] arr.ToString() ' => "21/03/2009,23/07/2010,26/12/2011"
Converts the dictionary to a string representation. Same as Dictionary.ToString().
Dim dic As Variant = @{"key1": "value1", "key2": 12, "key3": true, "key4": null}
dic.ToString() ' => "{"key1":"value1","key2":12,"key3":true,"key4":null}"
Dim dic As Variant = @{}
dic.ToString() ' => "{}"
Converts whatever value is inside the variant to an array of variants.
Returns an array of variants.
See:
Returns an empty array.
Dim nil As Variant = Null nil.ToArray() ' => @[]
Returns an array with the boolean as a first and unique value.
Dim b As Variant = True b.ToArray() ' => @[True]
Dim B As Variant = False b.ToArray() ' => @[False]
Returns an array with the number as a first and unique value.
Dim n As Variant = 25 n.ToArray() ' => @[25]
Dim n As Variant = DK n.ToArray() ' => @[DK]
Returns an array with the date as a first and unique value.
Dim dt As Variant = #25/01/2017# dt.ToArray() ' => @[#25/01/2017#]
Returns an array with the string as a first and unique value.
Dim str As Variant = "abcde" str.ToArray() ' => @["abcde"]
Returns an identical array.
Dim arr As Variant = @[1, 2] arr.ToArray() ' => @[1, 2]
Returns an array with the dictionary as a first and unique value.
Dim dic As Variant = @{"key" : "value"}
dic.ToArray() ' => @[{"key" : "value"}]
Those methods doesn't modify the object in place.
Converts whatever value is inside the array to an array of numbers
Return an Array of Number
dim arr = {2;4;5;2;3;4}
return arr.ToNumberArray() " => {2;4;5;2;3;4}
dim arr = {"b";"03";"e";"4";"c"}
return arr.ToNumberArray() " => {DK;3;DK;4;DK}
dim arr = @[2,4,"b","006","2",2,"a"]
return arr.ToNumberArray() ' => {2;4;DK;6;2;2;DK}
Those methods doesn't modify the object in place.
Converts whatever value is inside the array to an array of strings
Return an Array of String
dim arr = {2;4;5;2;3;4}
return arr.ToStringArray() " => {"2";"4";"5";"2";"3";"4"}
dim arr = {"b";"03";"e";"4";"c"}
return arr.ToStringArray() " => {"b";"03";"e";"4";"c"}
dim arr = @[2,4,"b","006","2",2,"a"]
return arr.ToStringArray() ' => {"2";"4";"b";"006";"2";"2";"a"}
Converts whatever value is inside the variant to a dictionary.
Returns a dictionary.
See:
Returns an empty dictionary.
Dim nil As Variant = Null
nil.ToDictionary() ' => @{}
Returns an empty dictionary.
Dim b As Variant = True
b.ToDictionary() ' => @{}
Dim B As Variant = False
b.ToDictionary() ' => @{}
Returns an empty dictionary.
Dim n As Variant = 12
n.ToDictionary() ' => @{}
Returns an empty dictionary.
Dim dt As Variant = #12/01/2016#
dt.ToDictionary() ' => @{}
Returns an empty dictionary.
Dim str As Variant = "abcde"
str.ToDictionary() ' => @{}
Returns an empty dictionary.
Dim arr As Variant = @[1, 2]
arr.ToDictionary() ' => @{}
Returns an identical dictionary.
Dim dic As Variant = @{"key" : "value"}
dic.ToDictionary() ' => @{"key" : "value"}
Returns the basic value type held by the Variant. It will be one of the following, depending on the value type:
Returns a String.
Dim questions = Range(q1, q5) questions[1].Value.InnerTypeOf() ' => "string" (with open-ended question) questions[2].Value.InnerTypeOf() ' => "number" (with numeric question) questions[3].Value.InnerTypeOf() ' => "date" (with date question) questions[4].Value.InnerTypeOf() ' => "number" (with single-closed question) questions[5].Value.InnerTypeOf() ' => "numberarray" (with multi-coded question)
Always returns "variant".
Returns a String.
Dim questions = Range(q1, q5) questions[1].Value.TypeOf() ' => "variant"
All of the following operators may be used on a Variant without a conversion being required:
=, <>, Has, HasNone, HasAll, HasAndNoOther, HasAllAndNoOther, In, IsIncludedIn
If the InnerTypeOf doesn't support the operators, the comparison will fail (returns False or True accordingly). For example:
Dim myVariant As Variant = @[1, 2] myVariant Has @[1] ' => True
Dim myVariant As Variant = "abcde" myVariant Has "abcde" ' => False because the string doesn't support the HAS operator
Dim myVariant As Variant = "abcde" myVariant HasNone "abcde" ' => True because the string doesn't support the HASNONE operator
Comparisons with Variant are strict. The InnerTypeOf is checked first, except for comparisons between Boolean and Number.
Dim myVariant As Variant = 23 Dim isEqual = (myVariant = "23") Return isEqual ' => False because the inner types are different
Dim myVariant As Variant = True Dim isEqual = (myVariant = 1) Return isEqual ' => True