VBScript allows you to use the plus (+) operator to concatenate strings. However, this usage of plus (+) operator should be avoided. This is because the plus (+) operator, when used to concatenate strings, can cause unwanted implicit type coercion. Try this code:
Dim strFirst
Dim lngSecond
strFirst = CStr(50)
lngSecond = CLng(100)
MsgBox strFirst + lngSecond
The resulting dialogue box will display the number 150, which means that it added the two numbers mathematically rather than concatenating them. Now, this is admittedly a very silly example, but it illustrates that the plus (+) operator has different effects when you are not using it in a strictly mathematical context. The plus (+) operator uses the following rules when deciding what to do.
If both variables have the String subtype, the VBScript will concatenate the.
If both variables have any of the numeric subtype, then VBScript will add them.
If one of the variable has a numeric subtype, and the other has the String subtype, then VBScript will attempt to add them. If the variable with the String subtype does not contain a number, then a "Type Mismatch" error will occur.
Your best bet is to not worry about these rules and remember only the following:
Use the plus (+) operator only when you explicitly want to perform math on numeric values.
Always use the & operator to concatenate strings.
Never use the plus (+) operator to concatenate strings.
First
Another Coercion Example
Run the following code in Windows Script Host:
Dim intTest
intTest = CInt(100)
MsgBox "TypeName after initialization to 100: " & _
TypeName(intTest)
intTest = intTest + 1000000
MsgBox "TypeName after adding 1,000,000: " & _
TypeName(intTest)
intTest = intTest + 10000000000
MsgBox "TypeName after adding another 10,000,000,000: " & _
TypeName(intTest)
Notice that we initialized the variable with a value of 100, and use the CInt ( ) function to coerce the subtype into Integer. The first call to the TypeName ( ) function reflects String. Then we added 1,000,000 to the variable. The next call to the TypeName ( ) function reveals that VBScript coerced the subtype to Long. Why did it do this? Because we exceeded the upper limit of the Integer subtype, which is 32,767. VBScript will promote numeric subtype when the value exceeds the upper or lower limits of the current numeric subtype. Finally, we add another ten billion to the variable. This exceeds the upper limit of the Long subtype, so VBScript upgrades the subtype to Double.
First
Next
Dim intTest
intTest = CInt(100)
MsgBox "TypeName after initialization to 100: " & _
TypeName(intTest)
intTest = intTest + 1000000
MsgBox "TypeName after adding 1,000,000: " & _
TypeName(intTest)
intTest = intTest + 10000000000
MsgBox "TypeName after adding another 10,000,000,000: " & _
TypeName(intTest)
Notice that we initialized the variable with a value of 100, and use the CInt ( ) function to coerce the subtype into Integer. The first call to the TypeName ( ) function reflects String. Then we added 1,000,000 to the variable. The next call to the TypeName ( ) function reveals that VBScript coerced the subtype to Long. Why did it do this? Because we exceeded the upper limit of the Integer subtype, which is 32,767. VBScript will promote numeric subtype when the value exceeds the upper or lower limits of the current numeric subtype. Finally, we add another ten billion to the variable. This exceeds the upper limit of the Long subtype, so VBScript upgrades the subtype to Double.
First
Next
Long Coerced into String
Dim lngTest
lngTest = CLng(100)
MsgBox "Type after initialization: " & TypeName(lngTest)
lngTest = lngTest + 1000
MsgBox "TypeName after adding 1000: " & TypeName(lngTest)
lngTest = lngTest * 50
MsgBox "TypeName after multiplying the 50: " & TypeName(lngTest)
lngTest = "Hello"
MsgBox "TypeName after assigning value of 'Hello': " & TypeName(lngTest)
If you run this code using Windows Script Host, you'll see that the first three calls to the TypeName ( ) function reveal that the subtype is Long. Then, after we changed the value of the variable to "Hello", the subtype is automatically coerced into String. What this code illustrates is that, once the subtype is established as Long, it stays Long as long as we keep changing the value to other numbers. VBScript has no reason to change it, because the values we put in it remain in the range of the Long subtype. However, when we place text in the variable, VBScript sees that the new value is not appropriate for the Long subtype, so it changes it to String.
First
Next
lngTest = CLng(100)
MsgBox "Type after initialization: " & TypeName(lngTest)
lngTest = lngTest + 1000
MsgBox "TypeName after adding 1000: " & TypeName(lngTest)
lngTest = lngTest * 50
MsgBox "TypeName after multiplying the 50: " & TypeName(lngTest)
lngTest = "Hello"
MsgBox "TypeName after assigning value of 'Hello': " & TypeName(lngTest)
If you run this code using Windows Script Host, you'll see that the first three calls to the TypeName ( ) function reveal that the subtype is Long. Then, after we changed the value of the variable to "Hello", the subtype is automatically coerced into String. What this code illustrates is that, once the subtype is established as Long, it stays Long as long as we keep changing the value to other numbers. VBScript has no reason to change it, because the values we put in it remain in the range of the Long subtype. However, when we place text in the variable, VBScript sees that the new value is not appropriate for the Long subtype, so it changes it to String.
First
Next
Subtype Change
Din lngAge
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
While you have to aware of implicit type coercion, there is no reason to fear it. VBScript is not going to arbitrarily go around changing subtypes on you. Implicit type coercion only happens when you assign a new value to a variable that does not fit the current subtype. Generally, once a Variant variable has a subtype (based on the value first placed within it, or based on a subtype that your code explicitly coerced), it will keep that subtype as you place new value in the variable.
Where do you need to watch out for implicit type coercion is when you are dealing with a mixture of data types. I saw this in the example: when the data comes back from the InputBox ( ) function, it was a string. Then we did soem math on it, which turned it into a number. Give this code a try:
Dim lngTest
lngTest = CLng(100)
MsgBox "Type after initialization: " & TypeName(lngTest)
lngTest = lngTest + 1000
MsgBox "TypeName after adding 1000: " & TypeName(lngTest)
lngTest = lngTest * 50
MsgBox "TypeName after multiplying the 50: " & TypeName(lngTest)
lngTest = "Hello"
MsgBox "TypeName after assigning value of 'Hello': " & TypeName(lngTest)
First
Next
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
While you have to aware of implicit type coercion, there is no reason to fear it. VBScript is not going to arbitrarily go around changing subtypes on you. Implicit type coercion only happens when you assign a new value to a variable that does not fit the current subtype. Generally, once a Variant variable has a subtype (based on the value first placed within it, or based on a subtype that your code explicitly coerced), it will keep that subtype as you place new value in the variable.
Where do you need to watch out for implicit type coercion is when you are dealing with a mixture of data types. I saw this in the example: when the data comes back from the InputBox ( ) function, it was a string. Then we did soem math on it, which turned it into a number. Give this code a try:
Dim lngTest
lngTest = CLng(100)
MsgBox "Type after initialization: " & TypeName(lngTest)
lngTest = lngTest + 1000
MsgBox "TypeName after adding 1000: " & TypeName(lngTest)
lngTest = lngTest * 50
MsgBox "TypeName after multiplying the 50: " & TypeName(lngTest)
lngTest = "Hello"
MsgBox "TypeName after assigning value of 'Hello': " & TypeName(lngTest)
First
Next
Double Subtype - TWO
Din lngAge
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
In the example above, VBScript automatically knew that we wnated the value the variable to be a number because our code added 50 to the variable. VBScript says, "Oh, we're doing math. I better change the subtype to a numeric one before I do the math, because I can't do math on Strings." This is pretty straightforward. What isn't so straightforward is that it chose the Double subtype instead of Long or Integer or Bytes.
We may never know the exact reason why VBScript chooses a Double in this situation, but it is probably a prevention measure. Other than the Decimal subtype, which is rarely used and only then for extremely large or extremely small number, the Double subtype is the most capable of holding large numbers. Rather than go to the trouble of figuring out the result of the math first, and then deciding on a subtype, VBScript just picks the most accommodating subtype, Double, so that it can be reasonably sure that the result of the math will fit in the variable. In other words, VBScript makes the safest choice.
First
Next
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
In the example above, VBScript automatically knew that we wnated the value the variable to be a number because our code added 50 to the variable. VBScript says, "Oh, we're doing math. I better change the subtype to a numeric one before I do the math, because I can't do math on Strings." This is pretty straightforward. What isn't so straightforward is that it chose the Double subtype instead of Long or Integer or Bytes.
We may never know the exact reason why VBScript chooses a Double in this situation, but it is probably a prevention measure. Other than the Decimal subtype, which is rarely used and only then for extremely large or extremely small number, the Double subtype is the most capable of holding large numbers. Rather than go to the trouble of figuring out the result of the math first, and then deciding on a subtype, VBScript just picks the most accommodating subtype, Double, so that it can be reasonably sure that the result of the math will fit in the variable. In other words, VBScript makes the safest choice.
First
Next
Double Subtype - ONE
Din lngAge
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
However, does it really matter that VBScript coerced the variable into Double instead of a Long? There are both numeric subtypes, and the math has exactly the same result. Why care? Well, it's not the end of the world, except that the Double subtype theoretically takes a little bit more processing power than the Long, because the Double is a floating point, numeric subtype (floating point numbers require a greater degree of accuracy, and therefore the processor has to work a little harder to ensure that accuracy). If you were explicitly coercing the subtype, as in the code I started with, you might not choose the Double, because the Double is generally only used for very large or small numbers. You might choose Integer, or Long, or even Byte. That said, sometimes you need to care what the subtype is because you are planning to pass the variable to a method of a COM object that expects an explicit subtype.
The point of this little exercise is not to debate one numeric subtype is better than another, rather to illustrate implicit type coercion. VBScript automatically knew that we wanted the value the variable to be a number.
First
Next
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
However, does it really matter that VBScript coerced the variable into Double instead of a Long? There are both numeric subtypes, and the math has exactly the same result. Why care? Well, it's not the end of the world, except that the Double subtype theoretically takes a little bit more processing power than the Long, because the Double is a floating point, numeric subtype (floating point numbers require a greater degree of accuracy, and therefore the processor has to work a little harder to ensure that accuracy). If you were explicitly coercing the subtype, as in the code I started with, you might not choose the Double, because the Double is generally only used for very large or small numbers. You might choose Integer, or Long, or even Byte. That said, sometimes you need to care what the subtype is because you are planning to pass the variable to a method of a COM object that expects an explicit subtype.
The point of this little exercise is not to debate one numeric subtype is better than another, rather to illustrate implicit type coercion. VBScript automatically knew that we wanted the value the variable to be a number.
First
Next
Second Call TypeName ( ) Function
Din lngAge
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
The second call to the TypeName ( ) function comes after we add 50 to it, and shows that the subtype is Double. Wait a minute - Double? Why Double? Why not once of the whole number subtypes, such as Integer or Long? I didn't introduce any decimal places in this math? Why would VBScript implicitly coerce the subtype into Double? The answer is because VBScript determined that this was the best thing to do. Since we did not use a conversion function to explicitly tell VBScript to change the variable to one subtype or another, it evaluated the situation and chose the subtype that it thought was best. You have to be careful, because it can be tricky to predict exactly which subtype VBScript will choose.
First
Next
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
The second call to the TypeName ( ) function comes after we add 50 to it, and shows that the subtype is Double. Wait a minute - Double? Why Double? Why not once of the whole number subtypes, such as Integer or Long? I didn't introduce any decimal places in this math? Why would VBScript implicitly coerce the subtype into Double? The answer is because VBScript determined that this was the best thing to do. Since we did not use a conversion function to explicitly tell VBScript to change the variable to one subtype or another, it evaluated the situation and chose the subtype that it thought was best. You have to be careful, because it can be tricky to predict exactly which subtype VBScript will choose.
First
Next
First Call TypeName ( ) Function
Din lngAge
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
The first call to the TypeName ( ) function shows that the subtype is String. That is because data coming back form the InputBox function is always treated as String data, even when the user types in a number. Remember that the String subtype can hold just about any kind of data. However, when number and dates and Boolean True/False values are stored in a variable with the String subtype, they are not treated simple as strings of text with no special meaning. This is why, when our code tries to do math on the String value, VBScript must first coere the subtype to a numeric one.
First
Next
lngAge = InputBox("Plese enter your age in years")
MsgBox "TypeName After InputBox: " & TypeName(lngAge)
If IsNumeric(lngAge) Then
lngAge = lngAge + 50
MsgBox "TypeName after Adding 50: " &TypeName(lngAge)
MsgBox "In 50 years you will be " & lngAge & "years old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
The first call to the TypeName ( ) function shows that the subtype is String. That is because data coming back form the InputBox function is always treated as String data, even when the user types in a number. Remember that the String subtype can hold just about any kind of data. However, when number and dates and Boolean True/False values are stored in a variable with the String subtype, they are not treated simple as strings of text with no special meaning. This is why, when our code tries to do math on the String value, VBScript must first coere the subtype to a numeric one.
First
Next
Implicit Type Coercion
Implicit type coercion is when a Variant variable changes its subtype automatically. Sometimes, this can work in your favor, and sometimes it can present a problem.
He is a code that asks the user for his age:
Dim lngAge
lngAge = InputBox("Plese enter your age in years")
If IsNumeric(ingAge) Then
lngAge = CLng(lngAge)
lngAge = lngAge + 50
MsgBox "In 50 years, you will be " & CStr(lngAge) & " years Old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
Notice how we use the CLng ( ) and CStr ( ) functions to explicitly coerce the subtype. Well, in the case of this particular code, these functions are ot strictly necessary. The reason is that VBScript's inplicit type coercion would have done approximately the same thing for us. Here is the code again, without the conversion functions.
Dim lngAge
lngAge = InputBox("Plese enter your age in years")
If IsNumeric(ingAge) Then
lngAge = lngAge + 50
MsgBox "In 50 years, you will be " & lngAge & " years Old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
Because of implicit type coercion, this code works the same way as the original code. Take a look at the fifth line. We did not explicitly coerce the subtype to Long, but the math still works as you would expect. Let us run the same code, but with some TypeName ( ) functions thrown in so that we can watch the subtypes change.
Next
He is a code that asks the user for his age:
Dim lngAge
lngAge = InputBox("Plese enter your age in years")
If IsNumeric(ingAge) Then
lngAge = CLng(lngAge)
lngAge = lngAge + 50
MsgBox "In 50 years, you will be " & CStr(lngAge) & " years Old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
Notice how we use the CLng ( ) and CStr ( ) functions to explicitly coerce the subtype. Well, in the case of this particular code, these functions are ot strictly necessary. The reason is that VBScript's inplicit type coercion would have done approximately the same thing for us. Here is the code again, without the conversion functions.
Dim lngAge
lngAge = InputBox("Plese enter your age in years")
If IsNumeric(ingAge) Then
lngAge = lngAge + 50
MsgBox "In 50 years, you will be " & lngAge & " years Old."
Else
MsgBox "Sorry, but you did not enter a valid number."
End If
Because of implicit type coercion, this code works the same way as the original code. Take a look at the fifth line. We did not explicitly coerce the subtype to Long, but the math still works as you would expect. Let us run the same code, but with some TypeName ( ) functions thrown in so that we can watch the subtypes change.
Next
Is Functions - IsDate
Dim datBirth
datBirth = InputBox("Please enter the date on which you were born")
If IsDate(datBirth) Then
datBirth = CDate(datBirth)
MsgBox "You were born on day " & Day(datBirth) & _
" of month "& Month (datBirth) & " in the year " & _
year(datBirth) & "."
Else
MsgBox "Sorry, but you did not enter a valid date."
End If
Day ( ), Month ( ), and year ( ) are built-in VBScript functions that you can use to return the different parts of a date. Not however, that not all of the "Is" functions work strictly on the values, as IsNumeric ( ) and IsDate ( ) do. The function IsEmpty ( ), IsNull ( ), and IsObject ( ) examine the subtype of the variable, not the value.
First
datBirth = InputBox("Please enter the date on which you were born")
If IsDate(datBirth) Then
datBirth = CDate(datBirth)
MsgBox "You were born on day " & Day(datBirth) & _
" of month "& Month (datBirth) & " in the year " & _
year(datBirth) & "."
Else
MsgBox "Sorry, but you did not enter a valid date."
End If
Day ( ), Month ( ), and year ( ) are built-in VBScript functions that you can use to return the different parts of a date. Not however, that not all of the "Is" functions work strictly on the values, as IsNumeric ( ) and IsDate ( ) do. The function IsEmpty ( ), IsNull ( ), and IsObject ( ) examine the subtype of the variable, not the value.
First
Subscribe to:
Posts (Atom)