This chapter describes:
- Variable Inspection
- Variable Inspection Example
- Parsing Long Integers
Notes and samples in this chapter are based Visual Basic 6.0.
Variable Inspection
If are writing a function, and receiving a variable from the calling code, you can not always assume that the variable is of certain type and has value assigned. If you code your function with such assumptions, your code will crash if the calling code failed to meet those assumptions.
To better protect your code, you want to inspect the variable first, and write your code based on the result of the inspection. Variable inspection can be performed at 3 different levels:
1. Determine the structure type of the variable like: object, array, or single data.
2. Determine the data type of the variable like, integer, long, double, date, Boolean, or String.
3. Determine the status of the data like, empty or not empty.
VB offers a number of built-in functions to help you to inspect a variable:
- IsArray(variable) - Returns True if the specified variable is an array
- IsDate(variable) - Returns True if the specified variable can be converted to a date
- IsEmpty(variable) - Returns True if the specified variable is Empty
- IsNull(variable) - Returns True is the specified variable is Null
- IsNumeric(variable) - Returns True if the specified variable can be converted to a number
- IsObject(variable) - Returns True if the specified variable is an object
- TypeName(variable) - Returns the type name of the specified variable
Variable Inspection Example
To show you how those inspection function work, I wrote the following example, variant_subtype_detection.html:
<html>
<body>
<!-- variable_inspection.html
Copyright (c) 2006 by Dr. Herong Yang. http://www.herongyang.com/
-->
<pre>
<script language="vbscript">
document.writeln(" ")
document.writeln("Checking variants with value:")
document.writeln("V1 " & GetVarInfo(777) & " (777)")
document.writeln("V2 " & GetVarInfo(777777) & " (777777)")
document.writeln("V3 " & GetVarInfo(3.14) & " (3.14)")
document.writeln("V4 " & GetVarInfo(3.3e200) & " (3.3e200)")
document.writeln("V5 " & GetVarInfo("Hello") & " (""Hello"")")
document.writeln("V6 " & GetVarInfo(TRUE) & " (TRUE)")
document.writeln("V7 " & GetVarInfo(#31-Dec-1999#) _
& " (#31-Dec-1999#)")
document.writeln(" ")
document.writeln("Checking strings with value:")
document.writeln("S1 " & GetVarInfo("777") & " (""777"")")
document.writeln("S2 " & GetVarInfo("3.14") & " (""3.14"")")
document.writeln("S3 " & GetVarInfo("True") & " (""True"")")
document.writeln("S4 " & GetVarInfo("#31-Dec-1999#") _
& " (""#31-Dec-1999#"")") document.writeln(" ")
document.writeln("Checking arrays:")
Dim aFixed(5)
document.writeln("A1 " & GetVarInfo(aFixed) & " (Fixed)")
aFixed(5) = 555
document.writeln("A2 " & GetVarInfo(aFixed) & " (Fixed/Val.)")
Dim aDynamic()
document.writeln("A3 " & GetVarInfo(aDynamic) & " (Dyn.)")
ReDim aDynamic(3)
document.writeln("A4 " & GetVarInfo(aDynamic) & " (Dyn./Set)")
aDynamic(3) = "Dog"
document.writeln("A5 " & GetVarInfo(aDynamic) & " (Dyn./Set/Val.)")
document.writeln(" ")
document.writeln("Checking emptiness:")
vNull = Null
document.writeln("E1 " & GetVarInfo(vNull) & " (Null)")
vEmpty = Empty
document.writeln("E2 " & GetVarInfo(vEmpty) & " (Empty)")
document.writeln(" ")
document.writeln("Checking objects:")
document.writeln("O1 " & GetVarInfo(Document) & " (Document)")
Function GetVarInfo(vAnyThing)
If IsObject(vAnyThing) Then
sObject = "Obj=Y"
Else
sObject = "Obj=N"
End If
If IsArray(vAnyThing) Then
sArray = "Array=Y"
Else
sArray = "Array=N"
End If
If IsDate(vAnyThing) Then
sDate = "Date=Y"
Else
sDate = "Date=N"
End If
If IsNumeric(vAnyThing) Then
sNumeric = "Num=Y"
Else
sNumeric = "Num=N"
End If
If IsNull(vAnyThing) Then
sNull = "Null=Y"
Else
sNull = "Null=N"
End If
If IsEmpty(vAnyThing) Then
sEmpty = "Empty=Y"
Else
sEmpty = "Empty=N"
End If
sType = TypeName(vAnyThing)
GetVarInfo = sObject & " " & sArray & " " & sDate _
& " " & sNumeric & " " & sNull & " " & sEmpty & " " & sType
End Function
</script>
</pre>
</body>
</html>
Here is the output:
Checking variants with value:
V1 Obj=N Array=N Date=N Num=Y Null=N Empty=N Integer (777)
V2 Obj=N Array=N Date=N Num=Y Null=N Empty=N Long (777777)
V3 Obj=N Array=N Date=N Num=Y Null=N Empty=N Double (3.14)
V4 Obj=N Array=N Date=N Num=Y Null=N Empty=N Double (3.3e200)
V5 Obj=N Array=N Date=N Num=N Null=N Empty=N String ("Hello")
V6 Obj=N Array=N Date=N Num=Y Null=N Empty=N Boolean (TRUE)
V7 Obj=N Array=N Date=Y Num=N Null=N Empty=N Date (#31-Dec-1999#)
Checking strings with value:
S1 Obj=N Array=N Date=N Num=Y Null=N Empty=N String ("777")
S2 Obj=N Array=N Date=Y Num=Y Null=N Empty=N String ("3.14")
S3 Obj=N Array=N Date=N Num=N Null=N Empty=N String ("True")
S4 Obj=N Array=N Date=N Num=N Null=N Empty=N String ("#31-Dec-1999#")
Checking arrays:
A1 Obj=N Array=Y Date=N Num=N Null=N Empty=N Variant() (Fixed)
A2 Obj=N Array=Y Date=N Num=N Null=N Empty=N Variant() (Fixed/Val.)
A3 Obj=N Array=Y Date=N Num=N Null=N Empty=N Variant() (Dyn.)
A4 Obj=N Array=Y Date=N Num=N Null=N Empty=N Variant() (Dyn./Set)
A5 Obj=N Array=Y Date=N Num=N Null=N Empty=N Variant() (Dyn./Set/Val.)
Checking emptiness:
E1 Obj=N Array=N Date=N Num=N Null=Y Empty=N Null (Null)
E2 Obj=N Array=N Date=N Num=Y Null=N Empty=Y Empty (Empty)
Checking objects:
O1 Obj=Y Array=N Date=N Num=N Null=N Empty=N HTMLDocument (Document)
There are a number of interesting notes here:
- Line V3 shows that (3.14) is reported as (Double). I was expecting Single.
- Line V6 shows that (TRUE) is reported as (Num=Y). What number TRUE will be converted to?
- Line S1 shows that ("777") is reported as (String) and (Num=Y). That is reasonable.
- Line S2 shows that ("3.14") is reported as (String), (Num=Y) and (Date=Y). What date "3.14" will be converted to?
- Line A3 shows that a dynamic-size array is not Empty even before calling ReDim to set its size.
- Lines A1 to A5 show that arrays will never be Empty or Null.
- Lines E1 to E2 show that Empty and Null are independent data types and data literals.
- Line E2 shows that Empty is reported as (Num=Y). What number Empty will be converted to?
- Line O1 shows that (document) is an object of "HTMLDocument" type. This object is created by IE and passed the IE VB script environment.
Parsing Long Integers
A common task of handling user input is to convert user entered data into a long integer. This sounds like an easy task. But not really, if you allow the user to type in anything. I have tried my best in the following example to convert the input data as much as possible into a long integer, parsing_integer.html:
<html>
<body>
<!-- parsing_integer.html
Copyright (c) 2006 by Dr. Herong Yang. http://www.herongyang.com/
-->
<pre>
<script language="vbscript">
document.writeln(" ")
document.writeln("Converting variants to integers:")
document.writeln(" 777 = " & GetInteger(777))
document.writeln(" ""777"" = " & GetInteger("777"))
document.writeln(" 3.14159 = " & GetInteger(3.14159))
document.writeln(" ""3.14159"" = " & GetInteger("3.14159"))
document.writeln(" ""Hello"" = " & GetInteger("Hello"))
document.writeln(" True = " & GetInteger(True))
document.writeln(" Empty = " & GetInteger(Empty))
document.writeln(" Null = " & GetInteger(Null))
document.writeln(" ""1+2"" = " & GetInteger("1+2"))
document.writeln(" 777777 = " & GetInteger(777777))
document.writeln(" 3.3e200 = " & GetInteger(3.3e200))
document.writeln(" ""3.3e20000"" = " & GetInteger("3.3e20000"))
Function GetInteger(vAnyThing)
If IsNumeric(vAnyThing) Then
' GetInteger = CInt(vAnyThing) 'Error 1: overflow on 777777
' GetInteger = CLng(vAnyThing) 'Error 2: overflow on 3.3e200
GetInteger = CDbl(vAnyThing)
If Abs(GetInteger) < 2147483647 Then
GetInteger = CLng(GetInteger)
Else
GetInteger = -2147483648
End If
Else
GetInteger = -2147483648
End If
End Function
</script>
</pre>
</body>
</html>
Here is the output:
Converting variants to integers: 777 = 777 "777" = 777 3.14159 = 3 "3.14159" = 3 "Hello" = -2147483648 True = -1 Empty = 0 Null = -2147483648 "1+2" = -2147483648 777777 = 777777 3.3e200 = -2147483648 "3.3e20000" = -2147483648
Note that:
- I used IsNumeric() to filter out all other data that could not be converted into a number.
- Then I used CDbl() to get the converted number.
- Comments marked with "Error 1" and "Error 2" show that using "CInt()" or "CLng()" may result overflow error.
- Converting a Double number to Long number is relatively easy as shown in my code.
Conclusions
- "TypeName()" and "VarType()" are powerful tools to help you to determine the data structure and data type of any given variable.
- "IsNumeric() and CDbl()" are also useful to convert any given variable to a number.
discuss this topic to forum
