The VBScript Network and Systems Administrator's Cafe:

Variable Types

Oct 30 2008   12:00AM GMT

A new found bug in VBScript that causes if then statements to return wrong comparisons (or is it?)



Posted by: Jerry Lees
VBScript, Variable Types, string, working with variables, Integer, variant

In the past I’ve cautioned you on always initializing your variables and encouraged you to always declare your variable types, rather than using the default variant type in VBScript. I’ll be the first to admit I don’t follow my own advice in my examples! However, variants can be dangerous!

Recently I had a situation where if statements were returning completely not correct results and for the life of me I couldn’t figure it out! Here is an example that illustrates what was happening to me.

one = 1
two = 2
three = 3
OneBillion = 1000000000

MyVar = inputbox(”Enter a number”)If one < MyVar Then
     WScript.Echo (one & ” is lessthan ” & MyVar)
End If
If two < MyVar Then
     WScript.Echo (two & ” is lessthan ” & MyVar)
End If
If three < MyVar Then
     WScript.Echo (three & ” is lessthan ” & MyVar)
End If
If OneBillion < MyVar Then
     WScript.Echo (OneBillion & ” is lessthan ” & MyVar)
End If

The basis of the problem is that I was taking input from a file that was a number– however I was reading the file and it was coming into the script and being used as a string by the variant variable. I then was comparing it to a number and the comparisons were not working 100% correctly. Check it out by entering several numbers into the script. Try entering 0, 1, 2, 3, and 1000000001.

The moral of the story here is to always cast your varables as a specific type or use the cint() function to convert your variant varables to numbers before doing number comparisons with a literal number and a variant variable that is supposed to contain a number.

Sep 6 2008   11:41PM GMT

VBScript Statements: Explanation of the Public Statement



Posted by: Jerry Lees
Development, VBScript, VBScript Statements, Variable Types, Public

The VBScript Public statement creates a variable, function, subroutine, or class that is available outside the bounds of the scope it was created in and it functions very much like a global variable, except that it can be declared or initialized inside a non0-global code block.

 An example would be:

Public TestVariable


Apr 25 2008   3:19PM GMT

How VBScript variable types are represented as binary numbers



Posted by: Jerry Lees
VBScript, Variable Types

In a previous posting,  Converting variable types in VBScript from one type to another type, I discussed very briefly binary numbers and promised to write another entry with more detail. If you recall we we were discussing the size a number takes up to represent it in binary form.

Everyone is comfortable with the numbers 1 and 0, even in binary. And if you’re in IT, you’re probably even comfortable with binary 10, which isn’t Ten– it’s two. Normally we count in tens (with ten digits in each place), but computers count in twos (with only two digits in each place), which is base-2 instead of base-10 like we are used to counting.

 Consider this base-10 table with the column labels at the top and the number of each column below.

10000

1000

100

10

0

9

8

1

5

3

This might look a bit abstract the way it’s presented. But if you think back to elementary school the columns in a number represent the 10’s, 100’s, etc for the number. But the number is 98,153 or (90,000 +8000+ 100+50+3)

Now consider the following binary number, again with the column label at the top and the number of each column at the bottom:

16

8

4

2

1

1

0

1

1

1

This looks a bit more cryptic, but it’s actually simpler– we’ve just been trained to think in decimal. To do the first one we actually had to do multiplication in our head. It wasn’t (90,000 +8000+ 100+50+3)— it was actually(9* 10,000) + (8* 1000) + (1 * 100) + (5 * 10) + (3* 1)… That’s rather confusing when you spread it out, isn’t it? but with only 1’s and 0’s we don’t need to do multiplication. (Because 1 * anything is the number, and 0 times anything is 0)

So this is simply 16+4+2+1, or 23! It’s just a matter of getting to start thinking in powers of 2!

Now, Since I’ve shared with you previously that a double is larger than an integer, with respect to space, we’ll continue with that example. If you refer here you’ll notice that an integer is 2 bytes in Size where a double is 8 bytes in size. What’s 400% more space among friends, right? Quickly doubles can get out of control is you’re using bunches of them, or placing them in a Database one item at a time… This is sometimes where developers eat up all our space on the servers, in addition to the backup of the backups in the backups folder that’s stored in a Do not delete - Save this stuff folder. ;-)

The other thing that can be VERY bad! is using a variable type that is to small. Did you notice in the previous link that in Integer represents -32,768 to 32,768? What happens if you add 1 to 32,768? The answer for us is, of course, 32,769! The problem is computers can’t represent that number in an integer so you get a overflow and the number represented actually looks like -32768 to the computer!

 The moral of the story is to always try to use the right type of variable if a variant doesn’t work for you, and if you plan on using anything other than VBScript, VB, VB.NET, or VBA to create an admin tool– get accustomed to the different variable types.

Enjoy!

Extra credit: 10 in base-10 numbering is Ten, 10 in base-2 numbering is 2… what is 10 in Base-16 numbering and what is it commonly called?


Apr 13 2008   1:40AM GMT

Converting variable types in vbscript from one type to another type



Posted by: Jerry Lees
Development, VBScript, Functions, VBScript Statements, Variable Types

In a previous posting, titled Variable types in VBscript and their upper and lower limits– just prior to my Rant about CAPTCHA, we discussed the types of variables and why you might want to use them and I showed you a few scenarios where you could get unpredicatable results by not using the proper variable type. If you haven’t had a chance to read it yet, you might want to go back here before continuing.

In this installment We’ll discuss the challenge created by using these variable types specifically. Remember, I said that if you use pieces of code or a COM object written in another language it may require a certain type of variable when you call it from your script. (Note, VBScript generally does a good job of converting for you behind the scenes, but it is a best practice to do the conversion on your own first.)  You might be thinking, “Why not just use a double for everything, that covers a wide enough amount of numbers that I’ll never be able to use a number that high?”

Well, the reason is the size of the amount of data it takes because a larger number takes more bits in binary to be represented– therefor the larger the number (or more correctly the RANGE of the variable type) the more space it will take to store it. (A binary lesson may be in order, but not today.)  The last reason is related to the size as well, it takes more processing power to deal with larger numbers because the bus of the CPU is only so wide, and it must sometimes bring the number across the bus in two steps, thus taking more time. Therefore, if you use numbers to big your  scripts can run slower. When I mean slower, I’m only talking about fractions of a second for the work to be complete, but slow scripts tend to each your life away a millisecond at a time… Imagine something being a millisecond slower but you have to do it 100,000 times. Now you’re looking at almost 2 minutes eaten away.

Now, We discussed the types of variables last time, below you will find a table that shows you the function that converts one variable type to another and a link to a useful site showing you how to use the function. Yes, a function. These get fed a number of one type and return a number of another, so you’ll need to assign the return to another variable when you call them.  (Note: the site referenced uses document.write in it’s examples, to use the examples in VBScript simply replace document.write with a wscript.echo)

VBScript Type Conversion Functions

Function Description
CBool Converts any nonzero value to True and 0 (zero) to False.
CByte Converts an expression to a Byte value.
CCur Converts an expression to a Currency value.
CDate Converts an expression to a Date value.
CDbl Converts an expression to a Double value.
CInt Converts an expression to an Integer value. If the fractional part of the expression is .5, CInt will round the value to the nearest even number. For example, 3.5 will be rounded to 4, and 6.5 will be rounded to 6.
CLng Converts an expression to a Long value.
CSng Converts an expression to a Single value.
CStr Converts an expression to a String value.

This information should be very helpful to you in coverting variables from one type to another in the future. The thing to remember is that you don’t always need to do this, but if you’re getting wierd results in your script; check for uninitialized variants, variables of one type (or variant) that are being used with a external piece of code from another language, or for places where a return value is one type and you use it as another.

Enjoy!

Extra credit: What happens if you have a variable (of any type) and add enough to it to cause it to go above the maximum value of the variable type? What’s this generally called?


Apr 6 2008   12:17AM GMT

Variable types in VBscript and their upper and lower limits



Posted by: Jerry Lees
Development, VBScript, Variable Types

I just realized that the direction I’m headed with this blog (atleast a few posts from now) requires that I give you some more background information beyond what I’ve already done.

 Previously, I’ve talked about variables and given you a few types in passing– but never detailed the different types that are available to you as a script writer.

To that I say, “VBscripts default variable type is a Variant, which can hold any type of value you need to put in it without any work at all on your part.”

“WAIT?!?!!”, you say, “Here you are harping on us to be lazy and now you’re about to go through a big posting on variable types when the one you just mentioned should work fine for me!??”

Yes, a variant will work just fine for you for the most part. But it does do some funny things with variables because under the hood it does the conversion for you. Some even say using variants slows things down. Sometimes in VBscript you need to interface with an external COM dll or some other program and the other variable types will be needed because the call to the DLL will break if your variables aren’t properly cast into a type. Also, variants do funny things to numbers… take this simple example.

x = 2.0000
WScript.Echo x

 When you run this it simply prints:

2

No, No, No! I set x to 2.000 not 2. You might be thinking that 2.000 = 2 from your math days and you’d be right except some of your science folks out there will agree that sometimes you need to communicate precision as well. In science, 2.000 communicates that you’ve MEASURED something to the thousandth place to be exactly 2.000. Frankly, that can sometimes take work and if you’re lazy and you do all that work you want credit for it, right? (See how I brought that ramble back full circle? Be lazy!)

Also, It does some funky things with variables you’ve never set to a value as well. Since Variants are just that– you can use them for strings, like for a URL “http://www.360voice.com/” and numbers like 100. No problem, right? Again… Possibly it’s a problem… Consider this scenario in your script (with nothing else in the script): 

WScript.Echo y
WScript.Echo y + 1

This prints the following (between the _ characters below on two different lines to show you what happens):

_

1
_

See it? The first echo of y appears blank– yet when I add it to the number 1, I get 1!  That’s because if you don’t put a value in a variant variable it treats it is 0 if it is used in the context of a number and as an empty string (or NULL (Not “”, or the empty string) for you C/C++ programmers out there) if you use it in the context of a string. Big difference huh? Same Y, but two different values– empty and 0! (On a side note, think about empty with respect to a file’s contents– Empty takes no space at all and 0 (zero) takes a whole byte in a file.)

Now that you see some slight differences, consider the following types of variables in the table below: 

Subtype Description
Empty Variant is uninitialized. Value is 0 for numeric variables or a zero-length string (””) for string variables.
Null Variant intentionally contains no valid data.
Boolean Contains either True or False.
Byte Contains integer in the range 0 to 255.
Integer Contains integer in the range -32,768 to 32,767.
Currency -922,337,203,685,477.5808 to 922,337,203,685,477.5807.
Long Contains integer in the range -2,147,483,648 to 2,147,483,647.
Single Contains a single-precision, floating-point number in the range -3.402823E38 to -1.401298E-45 for negative values; 1.401298E-45 to 3.402823E38 for positive values.
Double Contains a double-precision, floating-point number in the range -1.79769313486232E308 to -4.94065645841247E-324 for negative values; 4.94065645841247E-324 to 1.79769313486232E308 for positive values.
Date (Time) Contains a number that represents a date between January 1, 100 to December 31, 9999.
String Contains a variable-length string that can be up to approximately 2 billion characters in length.
Object Contains an object.
Error Contains an error number.

All these number types… I’m betting your head is swimming if you haven’t encountered this before. Have no fear… we’ll go over them more a little later. Atleast, for now you see what I’m talking about. Next time, I’ll go over conversion functions to convert number types.

Extra Credit: Think about if I had a payroll script I was working on– and you were actually going to get paid by it. You worked 40.5 hours (or if your salary your check should be $1201.62) Would you mind terribly if I fed this to the payroll department after converting these numbers to an Integer first?


Mar 12 2008   5:38PM GMT

Use of option explicit and the DIM statement in VBSCRIPT.



Posted by: Jerry Lees
Development, VBScript, VBScript Statements, Variable Types, Error control

As an answer to the extra credit portion of my posting a few days ago:

DIM in a script declares a variable to be used. It just simply creates the variable, nothing more. By default, vbscript will create variables on the fly for you as you use them the first time you use them.

There are other ways to create a variable as well, but create specific types of variables. Here are a few I can think of off the top of my head.

Const  - creates a Constant Variable, while it may seem line an oxymoron, they are sometimes very useful rather than risking typing a long value over and over again. Consider these examples Please note, they are abbreviated here for display purposes— please do not use them in code to launch a rocket to Mars ;-) .

Const Pi = 3.14159265358979323846264338327950288419716939937510582097494459230 ‘ Pi
Const GC = 0.62432998854355087099293638310083724417964262018052 ‘ The Golomb Constant
Const AC = 0.37395581361920228805472805434641641511162924860615  ‘ Artins Constant

By doing this we can type this in our code: 

Answer = Pi * GC * AC

Instead of:

Answer = 3.14159265358979323846264338327950288419716939937510582097494459230 * 0.62432998854355087099293638310083724417964262018052 * 0.37395581361920228805472805434641641511162924860615

And just imagine the mistakes we’d make if we had to type it a bunch of times!

Also there is This command:

Redim  - used to create a single or multi-dimensional array.

For example:

Redim StudentQuarterlyGrades(4) ‘ single dimensional array for grades for a student
Redim ClassQuarterlyGrades(4,13) ‘ a multidimensional array for quarterly grades for a class of 13

Enough of that tangent of extra information! The last  extra credit item was:

option explicit, which forces the writer of a script to declare their variables before they use them.

This can be very valuable and a huge time saver– though it requires a little extra work on the from side declaring variables before you use them. In fact, most programming languages, like c/c++, java, and others, require you to declare the variables prior to use as well as decalre what kind of value you will be putting in them.

Consider this code, without using OPTION EXPLICIT:

StudentFinalGrade = 100
StudentHomeworkGrade = 100

StudentCourseGrade = ((StudentFialnGrade + StudentHomeworkGrade)/200)*100

Do you see the problem? I spelled final wrong in the last line StudentFialnGrade.

Some poor student will get a F (50%), instead of an A (100%) because of that mistake. However, The same code with option explicit and proper DIM statements below (yes, you can declare multiple variables on one line with a comma):

Option Explicit
Dim StudentFinalGrade, StudentHomeworkGrade

StudentFinalGrade = 100
StudentHomeworkGrade = 100

StudentCourseGrade = ((StudentFialnGrade + StudentHomeworkGrade)/200)*100

Yields the following error, pointing to the line and the variable that is either misspelled or not decalred:

… Untitled4.vbs(7, 1) Microsoft VBScript runtime error: Variable is undefined: ‘StudentFialnGrade’
 

Notice how easy that is. Trust me on this. Get into the habit of starting every script with option explicit and using DIM to declare your variables… while it may not matter for 20 -40 line scripts, you will notice it in 100 or 1000 line scripts– and wish you had done it when you spend several hours tracing down why a calculation or string value is coming out differently than you expected!