Variant type

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:

Creating a variant type variable

To create a variant variable, assign a variant to a variable or declare a variable as a variant.

Assigning a Variant to a variable

Dim myValue = Q1.Value

Declaring a Variant

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:

Note: The internal value type of a variant can change during script execution. For example, you can start with a variant that holds a Number and later change its value to a String, as follows:
Dim myValue As Variant = 12
myValue.InnerTypeOf() ' => number
myValue = "Hello"
myValue.InnerTypeOf() ' => string
	
This is possible because the variable type (returned by TypeOf) is always a variant.
Note: The initial value of the variant when nothing is assigned, is Null.
Dim myValue As Variant
myValue.InnerTypeOf() ' => null

Conversion Table

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.

 

↑ Top of page ↑

Automatic casting / conversion

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:

For a mutable variable type (Array and Dictionary), if the method changes the underlying object and is not of the right type, the object is not modified.

Dim foo as Variant = 3
foo.Set("abc",5) ' => does nothing but return the variant so here 3 
Dim foo as Variant = @{"a":"b"}
foo.Push("abc") ' => does nothing but return the variant so here @{"a":"b"}

The rules for automatic casting and conversion are as follows:

  1. Is the operator/property/method exist on variant?
  2. Does the operator/property/method exist on the inner variable type?
  3. Is the operator/property/method compatible with only one variable type?
  4. Is it possible to determine the method using the arguments?
  5. Use the following priority to convert:

    Number > String > NumberArray > StringArray > Array > Date > Boolean > Dictionary > Null

↑ Top of page ↑

Examples of automatic casting/conversion

Rule 1. Variant methods

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

 

↑ Top of page ↑

Rule 2. Automatic casting

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.

 

↑ Top of page ↑

Rule 3. Automatic conversion on single matching type

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

 

↑ Top of page ↑

Rule 4. Automatic conversion on multiple matching type

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

 

↑ Top of page ↑

Rule 5. Automatic conversion using matching type priority

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

↑ Top of page ↑

Methods

LoadJSON(json)

Available from version 5.4.9.

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"

 

↑ Top of page ↑

ToBoolean()

Available from version 5.4.9.

Converts whatever value is inside the variant to a boolean.

See also: Truthly/Falsy topic.

Returns a Boolean.

See:

↑ Top of page ↑

ToBoolean() with a Null value

Always returns False.

Dim nil As Variant = Null
nil.ToBoolean() ' => False

↑ Top of page ↑

ToBoolean() with a boolean value

Returns an identical boolean.

Dim b As Variant = True
b.ToBoolean() ' => True

↑ Top of page ↑

ToBoolean() with a numeric value

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

 

↑ Top of page ↑

ToBoolean() with a date value

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

 

↑ Top of page ↑

ToBoolean() with a string value

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

 

↑ Top of page ↑

ToBoolean() with an array value

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

 

↑ Top of page ↑

ToBoolean() with a dictionary value

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

↑ Top of page ↑

ToNumber()

Available from version 5.4.2.

Converts whatever value is inside the variant to a number.

Returns a Number.

See:

↑ Top of page ↑

ToNumber() with a Null value

Always returns DK.

Dim nil As Variant = Null
nil.ToNumber() ' => DK

↑ Top of page ↑

ToNumber() with a boolean value

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

↑ Top of page ↑

ToNumber() with a numeric value

Returns an identical number.

Dim n As Variant = 123
n.ToNumber() ' => 123

 

Dim n As Variant = 1.5
n.ToNumber() ' => 1.5

↑ Top of page ↑

ToNumber() with a date value

Converts the date to a number. Same as Date.ToNumber().

Dim dt As Variant = #25/03/2011 16:32:07#
dt.ToNumber() ' => 40627.688969907409

↑ Top of page ↑

ToNumber() with a string value

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

↑ Top of page ↑

ToNumber() with an array value

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

↑ Top of page ↑

ToNumber() with a dictionary value

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

↑ Top of page ↑

ToDate()

Available from version 5.4.2.

Converts whatever value is inside the variant to a date.

Returns a Date.

Returns DK when the conversion fails.

See:

↑ Top of page ↑

ToDate() with a Null value

Always returns DK.

Dim nil As Variant = Null
nil.ToDate() ' => DK

↑ Top of page ↑

ToDate() with a boolean value

Always returns DK.

Dim b As Variant = True
b.ToDate() ' => DK

 

Dim b As Variant = False
b.ToDate() ' => DK

↑ Top of page ↑

ToDate() with a number value

Converts the number to a date.

Dim n As Variant = 40627.688969907409
n.ToDate() ' => #25/03/2011 16:32:07#

↑ Top of page ↑

ToDate() with a date value

Returns an identical date.

Dim dt As Variant = #25/03/2011 16:32:07#
dt.ToDate() ' => #25/03/2011 16:32:07#

↑ Top of page ↑

ToDate() with a string value

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)

↑ Top of page ↑

ToDate() with an array value

Always returns DK.

Dim arr As Variant = @[#12/03/2015#, #14/02/2015#]
arr.ToDate() => DK

↑ Top of page ↑

ToDate() with a dictionary value

Always returns DK.

Dim dic As Variant = @{"key1" : #12/03/2015#}
dic.ToDate() => DK

↑ Top of page ↑

ToString()

Available from version 5.4.2.

Converts whatever value is inside the variant to a string.

Returns a String.

See:

↑ Top of page ↑

ToString() with a Null value

Converts the null to a string. Same as Null.ToString().

Dim nil As Variant = Null
nil.ToString() ' => "null" 

↑ Top of page ↑

ToString() with a boolean value

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"

↑ Top of page ↑

ToString() with a number value

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"

↑ Top of page ↑

ToString() with a date value

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

↑ Top of page ↑

ToString() with a string value

Returns an identical string.

Dim str As Variant = "abcde"
str.ToString() ' => "abcde"

↑ Top of page ↑

ToString() with an array value

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"

↑ Top of page ↑

ToString() with a dictionary value

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() ' => "{}"

↑ Top of page ↑

ToArray()

Available from version 5.4.9.

Converts whatever value is inside the variant to an array of variants.

Returns an array of variants.

See:

↑ Top of page ↑

ToArray() with a null value

Returns an empty array.

Dim nil As Variant = Null
nil.ToArray() ' => @[]

↑ Top of page ↑

ToArray() with a boolean value

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]

↑ Top of page ↑

ToArray() with a number value

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]

↑ Top of page ↑

ToArray() with a date value

Returns an array with the date as a first and unique value.

Dim dt As Variant = #25/01/2017#
dt.ToArray() ' => @[#25/01/2017#]

↑ Top of page ↑

ToArray() with a string value

Returns an array with the string as a first and unique value.

Dim str As Variant = "abcde"
str.ToArray() ' => @["abcde"]

↑ Top of page ↑

ToArray() with an array value

Returns an identical array.

Dim arr As Variant = @[1, 2]
arr.ToArray() ' => @[1, 2]

↑ Top of page ↑

ToArray() with a dictionary value

Returns an array with the dictionary as a first and unique value.

Dim dic As Variant = @{"key" : "value"}
dic.ToArray() ' => @[{"key" : "value"}]

↑ Top of page ↑

 

ToNumberArray()

Available from version 5.4.9

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}
 

↑ Top of page ↑

 

ToStringArray()

Available from version 5.4.9

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"}
 

↑ Top of page ↑

ToDictionary()

Available from version 5.4.9.

Converts whatever value is inside the variant to a dictionary.

Returns a dictionary.

See:

↑ Top of page ↑

ToDictionary() with a null value

Returns an empty dictionary.

Dim nil As Variant = Null
nil.ToDictionary() ' => @{}

 

↑ Top of page ↑

ToDictionary() with a boolean value

Returns an empty dictionary.

Dim b As Variant = True
b.ToDictionary() ' => @{}

 

Dim B As Variant = False
b.ToDictionary() ' => @{}

↑ Top of page ↑

ToDictionary() with a number value 

Returns an empty dictionary.

Dim n As Variant = 12
n.ToDictionary() ' => @{}

↑ Top of page ↑

ToDictionary() with a date value

Returns an empty dictionary.

Dim dt As Variant = #12/01/2016#
dt.ToDictionary() ' => @{}

↑ Top of page ↑

ToDictionary() with a string value

Returns an empty dictionary.

Dim str As Variant = "abcde"
str.ToDictionary() ' => @{}

↑ Top of page ↑

ToDictionary() with an array value

Returns an empty dictionary.

Dim arr As Variant = @[1, 2]
arr.ToDictionary() ' => @{}

↑ Top of page ↑

 
ToDictionary() with a dictionary value

Returns an identical dictionary.

Dim dic As Variant = @{"key" : "value"}
dic.ToDictionary() ' => @{"key" : "value"}

↑ Top of page ↑

InnerTypeOf()

Available from version 5.4.2.

Returns the basic value type held by the Variant. It will be one of the following, depending on the value type:

Returns a String.

Examples
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)

↑ Top of page ↑

TypeOf()

Available from version 5.4.2.

Always returns "variant".

Returns a String.

Example
Dim questions = Range(q1, q5)
questions[1].Value.TypeOf() ' => "variant"

↑ Top of page ↑

Operators

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

↑ Top of page ↑

Create your own Knowledge Base