Constants, Variables, and Arrays
Overview
This is the second of five chapters in this book that teaches the fundamentals of VBScript. One of the key concepts that you need to understand when working with VBScript, or any programming language, is how to store, retrieve, and modify data. This chapter will teach you a number of different ways of performing these tasks. By the time you have completed this chapter you will know how to write scripts that can collect and manipulate data. Specifically, you will learn how to
- Process data passed to the script at execution time
- Store data that does not change
- Work with data that may change during script execution
- Process collections of related data as a unit
Project Preview The Story of Captain Adventure
In this chapter you will learn how to create a game that builds a comical adventure story based on user input. The game begins by collecting answers to a series of questions without telling the user how the answers will be used. Once all the information that the script needs is collected, the story will be displayed, as shown in Figures 4.1 through 4.7.
Figure 4.1: The story's initial splash screen
Figure 4.2: The user will be the star of the story.
Figure 4.3: The story will begin anywhere the user specifies.
Figure 4.4: The user must specify the object that provides our hero with his superpowers.
Figure 4.5: The user specifies the story's co-star.
Figure 4.6: Finally, the user specifies a magic word.
Figure 4.7: Once the script has all the information it needs, the story is told.
Through the development of this story-building game you will learn a number of important programming techniques, including how to collect, store, and reference data. In addition, you will learn how to control the presentation of script output.
Understanding How Scripts View Data
VBScript, like other programming languages, needs a way of storing data so that it can be accessed throughout the execution of a script. Up to this point in the book you have seen a number of examples of how VBScript temporarily stores and references data. Now I'll explain how this works.
Definition
Data is information that a computer program collects, modifies, stores, and retrieves during execution.
VBScript supplies a number of different statements that allow you to define several different types of data. These VBScript statements are outlined in Table 4.1.
Statement |
Description |
---|---|
Const |
Defines a VBScript constant |
Dim |
Defines a VBScript variable or array |
ReDim |
Defines a dynamic VBScript array |
The Const statement is used to define data that never changes throughout the execution of a script. For example, in this book you will sometimes see constants used to define strings that are used to define a standard greeting message in popup dialogs. The Dim statement is used to define a variable. A variable stores an individual piece of data such as a name, number, or date. The ReDim statement is used to create an array. Arrays are used to store groups of related information. For example, instead of defining 20 different variables in order to store information about 20 different people, a single array could be defined and then information about each person can be stored in it. Each of these statements will be examined in greater detail throughout the rest of this chapter.
Working with Data That Never Changes
Data should be defined within a script according to the manner in which it will be used. If the script only needs to reference a piece of data that has a value that is known during script development, then the data can be defined as a constant. An example of a constant is the mathematical value of PI. Other examples of constants include specific dates of history, the name of places, and so on.
There are two sources of constants within scripts. First, you can define your own constants within your scripts. Another option is to reference a built-in collection of readily available constants provided by VBScript.
Assigning Data to Constants
If you're going to write a script and know for a fact that you need to reference one or more values that will not change during the execution of the script, then you can define each piece of data as a constant. One of the nice features of constants is that, once defined, their value cannot be changed. This prevents their values from being accidentally modified during the execution of the script.
HINT |
If your script attempts to modify the value assigned to a constant after it has been initially assigned, you will see an "Illegal assignment: 'XXXXXXXX'" error message when the script executes. XXXXXXXX will reference the name of the constant. Open your script and do a search on this word, and look for the statements that have attempted to modify its value to find the source of the error. |
To define a constant within a VBScript you must use the Const statement. This statement has the following syntax:
[Public | Private] Const cConstName = expression
Public and Private are optional keywords and are used to determine the availability of constants throughout a script. Defining a constant as Public makes it available to all procedures within the scripts. Defining a constant as Private makes it available only within the procedure that defines it. cConstName is the name of the constant being defined, and expression is the value that identifies the data being defined. To make sense of all this, let's look at an example.
Definition
A procedure is a collection of script statements that are processed as a unit. In Chapter 7, "Using Procedures to Organize Scripts," you will learn how to use procedures in order to improve the overall organization of your scripts and to create reusable units of code.
'************************************************************************* 'Script Name: LittlePigs.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script demonstrates how to use a constant to create a 'standardized titlebar message for popup dialogs displayed by the script '************************************************************************* 'Specify the message to appear in each popup dialog titlebar Const cTitleBarMsg = "The Three Little Pigs" 'Display the story MsgBox "Once upon a time........", vbOkOnly, cTitleBarMsg MsgBox "There were 3 little pigs", vbOkOnly, cTitleBarMsg MsgBox "Who liked to build things.", vbOkOnly, cTitleBarMsg
In this example, I wrote a small VBScript that tells a very brief story about three little pigs. The script begins by defining a constant named cTitleBar. I then used three MsgBox() statements to display the text that makes up the story. The first argument in each MsgBox() statement is a text message, which is then followed by a VBScript MsgBox() constant vbOkOnly. This constant tells VBScript to only display the OK button on the popup dialog (a complete listing of MsgBox() constants is available in Chapter 3, "VBScript Basics"). The last part of each MsgBox() statement is the cTitleBarMsg constant. VBScript will automatically substitute the value assigned to the cTitleBarMsg constant whenever the script executes. Figure 4.8 shows how the first popup dialog appears when the script is executed.
Figure 4.8: By referencing the value assigned to a constant you can create a standard titlebar message for every popup dialog displayed by your script.
HINT |
I strongly recommend that you apply a naming convention for your constants that will uniquely identify them within your scripts. A good naming convention will make your constants easy to locate and identify and will improve the overall readability of your scripts. For example, in this book I will use the following constant naming convention:
|
Other examples of tasks related to working with constants include assigning values such as number, string, and dates. For example, the following statement assigns a value of 1000 to a constant called cUpperLimit:
Const cUpperLimit = 1000
To define a text string, you must place the value being assigned within a pair of quotes, like this:
Const cMyName = "Jerry Lee Ford, Jr."
In a similar fashion, you must use a pair of pound signs to store a date value within a constant, like this:
Const cMyBirthday = #11-20-64#
VBScript Run Time Constants
VBScript supplies you with an abundance of built-in constants. In Chapter 3 you learned about the constants associated with the MsgBox() function. For example, the following VBScript statement executes the MsgBox() function using the vbOkOnly constant:
MsgBox "Welcome to my VBScript game!", vbOkOnly
This statement displays a popup dialog that contains a single OK button. In addition to these constants, VBScript supplies constants that help when you're working with dates and times. VBScript also supplies a number of constants that can help you manipulate the display of text output and test the type of data stored within a variable.
Using Date and Time Constants
Table 4.2 lists VBScript Date and Time constants.
Constant |
Value |
Description |
---|---|---|
vbSunday |
1 |
Sunday |
vbMonday |
2 |
Monday |
vbTuesday |
3 |
Tuesday |
vbWednesday |
4 |
Wednesday |
vbThursday |
5 |
Thursday |
vbFriday |
6 |
Friday |
vbSaturday |
7 |
Saturday |
vbFirstFourDays |
2 |
First full week with a minimum of 4 days in the new year |
vbFirstFullWeek |
3 |
First full week of the year |
vbFirstJan1 |
1 |
Week that includes January 1 |
UseSystemDayOfWeek |
0 |
Day of week as specified by the operating system |
The following script demonstrates how the vbFriday constant, listed in Table 4.2, can be used to determine if the end of the workweek is here:
'************************************************************************* 'Script Name: HappyHour.vbs 'Author: Jerry Ford 'Created: 10/26/02 'Description: This script tells the user if it's Friday '************************************************************************* 'Perform script initialization activities Dim TodaysDate ' Weekday is a VBScript function that gets the day of the week TodaysDate = Weekday(Date) If TodaysDate = vbFriday then MsgBox "Hurray, it is Friday. Time to get " & _ "ready for happy hour!"
TRICK |
You may have noticed the use of the & character in the previous example. The & character is a VBScript string concatenation operator. It allows you to combine two pieces of text into a single piece of text. |
The first two lines of the script define a variable (we'll discuss variables in detail in the next section). The third line assigns a numeric value to the variable. In this case, the script used the VBScript Weekday() function to execute the VBScript Date() function. The Date() function retrieves the current date from the computer. The Weekday() function then provides a numeric value to represent the weekday for the date. Table 4.2 provides a list of the possible range of values in its Value column. If the current day of the week is Friday, then the value returned by the Weekday() function will be 6. Since the vbFriday constant has a value of 6, all that has to be done to determine if it is Friday is to compare the value returned by the Weekday() function to the vbFriday. If the two values are equal, a popup dialog displays the message "Hurray, it is Friday. Time to get ready for happy hour".
Using String Constants
Another group of constants that you may find useful is the VBScript string constants listed in Table 4.3.
Constant |
Value |
Description |
---|---|---|
vbCr |
Chr(13) |
Executes a carriage return |
vbCrLf |
Chr(13) and Chr(10) |
Executes a carriage return and a line feed |
vbFormFeed |
Chr(12) |
Executes a form feed |
vbLf |
Chr(10) |
executes a line feed |
vbNewLine |
Chr(13) and Chr(10) |
Adds a newline character |
vbNullChar |
Chr(0) |
Create a 0 or null character |
vbNullString |
String with no value |
Creates an empty string |
vbTab |
Chr(9) |
Executes a horizontal tab |
vbVerticalTab |
Chr(11) |
executes a vertical tab |
Using the constants shown in Table 4.3, you can control the manner in which output text is displayed. For example, take a look at the following script:
'************************************************************************* 'Script Name: MsgFormatter.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script demonstrates how to use VBScript string constants 'to control how text messages are displayed. '************************************************************************* 'Specify the message to appear in each popup dialog titlebar Const cTitleBarMsg = "The three little pigs" 'Specify variables used by the script Dim StoryMsg 'Specify the text of the message to be displayed StoryMsg = "Once upon a time there were 3 little pigs" & vbCrLf & _ "who liked to build things." & vbCrLf & vbCrLf & _ vbTab & "The End" 'Display the user to the story MsgBox StoryMsg, vbOkOnly + vbExclamation, cTitleBarMsg
The text message displayed by the script is
Once upon a time there were 3 little pigs who liked to build things. The End
Notice how the vbCrLf and vbTab constants have been placed throughout the text in order to specify how VBScript should display message text. Figure 4.9 shows the output that is displayed when this script is executed.
Figure 4.9: Using VBScript string constants to manipulate the display of text in popup dialogs
If the vbCrLf and vbTab constants were removed from the formatted message, the text displayed in the popup dialog would look completely different, as shown in Figure 4.10.
Figure 4.10: Displaying the same output as the previous example without the use of the vbCrLf and vbTab constants
HINT |
For more information about VBScript constants, go to http://www.msdn.microsoft.com and click on the VBScript Documentation link. |
Storing Data That Changes During Script Execution
Most programs that you write will have data in them that will need to be modified. For example, you may write a script that asks the user for input and then modifies the data while processing it. In this situation you can define variables.
There are two categories of variables available to your scripts: variables that you define within your scripts and environment variables that are maintained by Windows but which your scripts can reference. I'll demonstrate how to work with both categories of variables in the sections that follow.
VBScript Data Types
Unlike many other programming languages, VBScript only supports one type of variable, called a variant. However, a variant is very flexible and can be used to store a number of different types of data. Table 4.4 lists variant data types supported by VBScript.
Subtype |
Description |
---|---|
Boolean |
A variant with a value of True or False |
Byte |
An integer whose value is between 0 and 255 |
Currency |
A currency value between -922,337,203,685,477.5808 and 922,337,203,685,477.5807 |
Date |
A number representing a date between January 1, 100 and December 31, 9999 |
Double |
A floating-point number with a range of -1.79769313486232E308 and -4.94065645841247E-324 or 4.94065645841247E-324 and 1.79769313486232E308 |
Empty |
A variant that has not been initialized |
Error |
A VBScript error number |
Integer |
An integer with a value is between -32,768 and 32,767 |
Long |
An integer whose value is between -2,147,483,648 and 2,147,483,647. |
Null |
A variant set equal to a null value |
Object |
An object |
Single |
A floating-point number whose value is between -3.402823E38 and -1.401298E-45 or 1.401298E-45 and 3.402823E38 |
String |
A string up to two billion characters long |
Definition
A variant is a type of variable that can contain any number of different types of data.
Variants automatically recognize the types of data that are assigned to them and act accordingly. In other words, if a date value is assigned to a variant, then your script can use any of VBScript's built-in date functions to work with it. Likewise, if a text string is assigned to a variant, then your script can use any of VBScript's built-in string functions to work with it.
Like constants, VBScript provides you with some control over the way in which it identifies the types of values stores in a variant. For example, if you assign 100 as the variable value, then VBScript will automatically interpret this value as a number. But if you enclose the value in quotation marks, VBScript will treat it like a string.
VBScript also provides the ability to convert data from one type to another using built-in VBScript functions. You can use these functions within your scripts to change the way VBScript views and works with data. For example, the following VBScript statement defines a variable named MyBirthday and assigns it a text string of "November 20, 1964":
Definition
The term string and text string are used synonymously throughout this book to refer to text-based data or other types of data that has been enclosed within a pair of quotations.
MyBirthday = "November 20, 1964"
VBScript views this variable's value as a text string. However, using the Cdate() function, you can covert the string value to date format.
MyBirthday = CDate(MyBirthday)
Now, instead of seeing the variable's value as "November 20, 1964", VBScript sees it as 11/20/1964.
HINT |
VBScript provides a large number of conversion functions that you can use to convert from one data type to another. These functions include: Asc(), Cbool(), Cbyte(), Cbur(), Cdate(), CDbl(), Chr(), Cint(), CLng(), CSng(), and CStr(). For more information about how to use these functions, see Chapter 7, "Using Procedures to Organize Scripts." |
Defining Variables
VBScript provides two ways of defining variables: dynamically and formally, using the Dim statement. To dynamically create a variable within a script you simply need to reference it like this:
MyBirthday = #November 20, 1964#
Using this method of programming, you can define variables anywhere within your script. However, I strongly recommend against creating variables in this manner. It is much better to formally define any variables used in a script all at once at the beginning of the script. This helps keep things organized and easier to read. In addition, I also strongly suggest that you use the Dim statement. The syntax of the Dim statement is as follows:
Dim VariableName
VariableName is the name of the variable being defined. For example, the following statement defines a variable named MyBirthday:
Dim MyBirthday
Once a variable has been defined, you can assign a value to it, like this:
MyBirthday = #November 20, 1964#
Always use the Dim statement to make your code more readable and to explicitly show your intentions. You can define multiple variables within your scripts using multiple Dim statements.
Dim MyBirthday Dim MyName Dim MyAge
However, to reduce the number of lines of code in your scripts, you have the option of defining more than one variable at a time using a single Dim statement, by separating each variable with a comma and a space.
Dim MyBirthday, MyName, MyAge
As I already stated, it is better to formally define a variable before using it. One way to make sure that you follow this simple rule is to place the Option Explicit statement at the beginning of your scripts. The Option Explicit statement will generate an error during script execution if you attempt to reference a variable without first defining it. Therefore, Option Explicit helps remind you to follow good programming practices when working with variables.
To test the use of the Option Explicit statement lets take a look at another example.
'************************************************************************* 'Script Name: BigBadWolf.vbs 'Author: Jerry Ford 'Created: 02/29/02 'Description: This script demonstrates how to use the Option Explicit 'statment '************************************************************************* 'For the explicit declaration of all variables used in this script Option Explicit 'Create a variable to store the name of the wolf Dim WolfName 'Assign the wolf's name to the variable WolfName = "Mr. Wiggles" 'Display the story MsgBox "Once upon a time there was a big bad wolf named " & WolfName & _ "who liked to eat little pigs", vbOkOnly
In this example, the Option Explicit statement is the first statement in the script. By making it the first statement in the script, Option Explicit will affect all variables that follow. The next statement defines a variable representing the name of the wolf. The statement after that assigns a name to the variable, which is then used by the script's final statement to tell the story. Run the script, and you will see that everything works fine. Then modify the script by placing a comment in front of the Dim statement, and run the script again. This time, instead of executing properly, the error shown in Figure 4.11 will appear, indicating that the script attempted to reference an undefined variable.
Figure 4.11: Use the Option Explicit statement in all your scripts to prevent the use of undefined variables.
To summarize, the following list provides the guidelines that you should follow when working with variables:
- Define your variables at the beginning of your scripts in one location.
- Use the Option Explicit statement to enforce formal variable declaration.
- Use the Dim statement to define each variable.
Up to this point in the chapter, I have not been following these rules because I had not gotten to them yet. However, from this point on, you'll find them applied consistently in every script that uses variables.
TRICK |
There is one exception to the set of rules that I want to point out. In certain cases you may limit the availability of a variable and its value to a specific portion of your scripts. This is called creating a local variable and can be useful when manipulating a sensitive variable and you want to make sure that its value is not accidentally modified by other parts of the script. I'll provide more information about local variables a little later in this chapter. |
Variable Naming Rules
Another important issue that merits attention is the proper naming of variables. VBScript has a number of rules that you must follow in order to avoid errors from inappropriately named variables. These rules include
- Variable names must be less than 256 characters long.
- Variable names must begin with an alphabetic character.
- Only letters, numbers, and the _ character can be used when creating variable names.
- Reserved words cannot be used as variable names.
- Variable names cannot contain spaces.
- Variable names must be unique.
One more important thing to know about VBScript variables is that they are case-insensitive. This means that capitalization does not affect VBScript's ability to recognize a variable. Therefore, if a script defines a variable as Dim MyBirthday and then later references it as MYBIRTHDAY, VBScript will recognize both spellings of the variable name as the same. However, mixing cases in this manner can be confusing, and you should do your best to use a consistent case throughout your scripts.
HINT |
I recommend that you assign descriptive variable names in your scripts. This will make them easier to identify and understand. I also recommend that you select a standard approach in the way that you use case in the spelling of your variables. For example, throughout this book I have elected to define variables using complete words or parts of words, and to begin each word or part of a word with a capital letter, as in Dim MyBirthday. |
Variable Scope
Another key concept that you need to understand when working with variables is that of variable scope. In this context, scope refers to the ability to reference a variable and its assigned value from various locations within a script.
VBScript supports two different variable scopes, global and local. A variable with a global scope can be accessed from any location within the script. However, a variable with a local scope can only be referenced from within the procedure that defines it. VBScript supports two types of procedures, subroutines and functions, both of which are discussed in detail in Chapter 7, "Using Procedures to Organize Scripts."
As you know, a procedure is a collection or group of statements that is executed as a unit. Without getting too far ahead of myself, for now I'll just state that a variable defined outside of a procedure is global in scope, meaning that it can be accessed from any location within the script, including from within the script's procedures. A variable that is local in scope is a variable that is defined within a procedure.
Modifying Variable Values with Expressions
Throughout this chapter you have seen the equals sign (=) used to assign value to variables, like this:
MyName = "Jerry Lee Ford, Jr."
To change the value assigned to a variable, all you have to do is use the equals sign again, along with a new value, like this:
MyName = "Jerry L. Ford, Jr."
The two previous examples set and then modified the value assigned to a text variable. However, this same approach works just as well for other types of variables, such as those that contain numeric values.
Option Explicit Dim MyAge MyAge = 37 MyAge = 38
In this example, the variable is defined and then assigned a numeric value. The value assigned to that value is then modified to a different number. VBScript provides additional ways of modifying the value of numeric variables using the equals sign and VBScript arithmetic operators. Table 4.5 lists the VBScript arithmetic operators.
Operator |
Description |
---|---|
+ |
Addition |
- |
Subtraction |
* |
Multiplication |
/ |
Division |
- |
Negation |
^ |
Exponentiation |
Integer division |
|
Mod |
Modulus |
The best way to explain how these arithmetic operators are used is to show you an example. Take a look at the following script:
'************************************************************************* 'Script Name: MathDemo.vbs 'Author: Jerry Ford 'Created: 02/29/02 'Description: This script demonstrates how to use various VBScript 'arithmetic operators '************************************************************************* 'Force the explicit declaration of all variables used in this script Option Explicit Create a variable to store the name of the wolf Dim MyAge 'Assign my initial starting age MyAge = 37 WScript.Echo "I am " & MyAge 'Next year I will be MyAge = MyAge + 1 WScript.Echo "Next year I will be " & MyAge 'But I am not that old yet MyAge = MyAge - 1 WScript.Echo "But I still am " & MyAge 'This is how old I'd be if I were twice as old as I am today MyAge = MyAge * 2 WScript.Echo "This is twice my age " & MyAge 'And if I took that value, divided it by 5, added 3 and multiplied it by 10 MyAge = MyAge / 5 + 3 * 10 WScript.Echo "This says that I will be " & MyAge
If you run this script, you'll see the results shown in Figure 4.12.
Figure 4.12: Using VBScript arithmetic operators to modify numeric variables
The first four calculations should be fairly easy to understand. In the first calculation, I took the value of MyAge and added 1 to it. Similarly I subtracted 1 in the next calculation and then multiplied MyAge times 2 in the third statement. But the final calculation requires a little more explanation. You may have been surprised by this calculation's result. At first glance, it appears that VBScript will try to solve the equation as follows:
Step 1: Divide MyAge, which is currently 74 by 5 yielding 14.8 Step 2: Add 14.8 to 3 getting 17.8. Step 3: Multiple 17.8 and 10 getting as the final result 178
However, VBScript says that the answer is actually 44.8. How could this be? The answer lies in something called the Order of Precedence, which tells VBScript the order in which to perform individual calculations within an equation or expression. Table 4.6 outlines the order in which VBScript Order or Precedence occurs.
Operator |
Description |
---|---|
^ |
Exponentiation |
- |
Negation |
* |
Multiplication |
/ |
Division |
Integer division |
|
Mod |
Modulus |
+ |
Addition |
- |
Subtraction |
Note: Operators appearing at the beginning of the table have precedence over operators appearing later in the table. |
Exponentiation occurs before Negation. Negation occurs before multiplication, and so on. So when applied to the last calculation in the previous example, VBScript solves the equation as follows:
Step 1: Multiple 3 * 10 to get 30 Step 2: Divide MyAge by 5 to get 14.8 Step 3: Add 14.8 to 30 getting as the final result of 44.8
You can add parentheses to your VBScript expressions to exercise control over the order in which individual calculations are performed. For example, you could rewrite the last expression in the previous example as follows:
MyAge = ((MyAge / 5) + 3) * 10
VBScript will now perform individual calculation located within parentheses first, like this:
Step 1: Divide MyAge by 5 to get 14.8 Step 2: Add 14.8 and 3 to get 17.8 Step 3: Multiple 17.8 times 10 to get a final result of 178
Using the WSH to Work with Environment Variables
Thus far, the scripts that you have worked with in this chapter have used variables that are defined by the scripts themselves. A second type of variable, known as an environment variable, is also available to your VBScripts. Windows operating systems automatically create and maintain environment variables. There are two types of environment variables, user and computer. User environment variables are created during user login and provide information specific to the currently logged on user. Computer environment variables, on the other hand, are created based on what Windows learns about the computer; they are available at all times, as opposed to user variables, which are only available when you're logged in to the computer.
HINT |
You may end up writing scripts that are designed to run when no one is logged on to the computer. This can be done using the Windows Scheduler Service to automate the execution scripts. In this case, user environment variables will not be available to your scripts, and it will be up to you to make sure that your scripts do not depend on them. |
User and computer environment variables can be viewed from the Windows Environment Variables dialog. For example, on Windows XP you can access this dialog using the following procedure:
- Click Start.
- Right click on My Computer and select Properties. The System Properties dialog will appear.
- Select the Advanced property sheet.
- Click Environment Variables. The Environment Variables dialog will appear, as shown in Figure 4.13.
Figure 4.13: Examining Windows environment variables
Examples of user environment variables include
- TEMP. A folder where temporary files can be stored.
- TMP. Another folder where temporary files can be stored.
Examples of computer environment variables include
- ComSpec. Specifies the location of the Windows shell.
- NUMBER_OF_PROCESSORS. Displays a value of 1 for single processor computers.
- OS. Displays the operating system's name.
- Path. Specifies the current search path.
- PATHEXT. Specifies a list of extensions that identify executable files.
- PROCESSOR_ARCHITECTURE. Identifies the computer's processor type.
- PROCESSOR_IDENTIFIER. Displays a detailed description of the computer's processor.
- PROCESSOR_LEVEL. Displays the processor's stepping level.
- PROCESSOR_REVISION. Displays the processor's revision number.
- TEMP. A folder in which temporary files can be stored.
- TMP. Another folder in which temporary files can be stored.
- Windir. Identifies the location of the Windows folder.
In order to access environment variables you will need to use the WSH. For example, take a look at the following script:
'************************************************************************* 'Script Name: ComputerAnalyzer.vbs 'Author: Jerry Ford 'Created: 02/29/02 'Description: This script demonstrates how to use access environment 'variables using the WSH '************************************************************************* 'Force the explicit declaration of all variables used in this script Option Explicit 'Create a variable to store the name of the wolf Dim WshObject 'Set up an instance of the WScript.WshShell object Set WshObject = WScript.CreateObject("WScript.Shell") 'Use the WScript.Shell object's ExpandEnvironmentScrings() method to view 'environment variables MsgBox "This computer is running a version of " & _ WshObject.ExpandEnvironmentStrings("%OS%") & vbCrLf & "and has " & _ WshObject.ExpandEnvironmentStrings("%NUMBER_OF_PROCESSORS%") & _ " processor(s)."
The first statement in this example creates an instance of the WSH WScript.Shell object using the WScript's CreateObject() method. The next part of the script uses the WScript.Shell object's ExpandEnvironmentStrings() method to display the value of specific environment variables.
IN THE REAL WORLD
While the script demonstrates how to access environment variables, it really is not very useful. Another use for environment variables might be to validate the operating system on which the script has been started and to terminate script execution if it has been started on the wrong operating system like this:
If WshObject.ExpandEnvironmentStrings("%OS%") <> "Windows_NT" Then MsgBox "This script is designed to only run on Windows NT, 2000, XP or .NET" WScript.Quit End If
In this example, the first line of code checks to see if the script is being run on an NT, 2000, XP, or .NET system. If it is not, then the second and third lines of code execute, informing the user of the situation and terminating the script's execution.
Working with Collections of Related Data
When using variables, you can store an incredible amount of information during the execution of your scripts; you're limited only by the amount of memory available on your computer. However, keeping up with large numbers of variables can be difficult and may make your scripts difficult to maintain.
Often, data items processed by a script have a relationship to one another. For example, if you write a script that collects a list of names from the user in order to generate a list of personal contacts, wouldn't it be more convenient to store and manage the list of names as a unit instead of as a collection of individual names? VBScript provides support for arrays so that such a task may be performed.
For example, you can think of an array as being like a collection of numbered index cards, where each card contains the name of a person who has been sent an invitation to a party. If you assigned a name of ItsMyParty to the collection of cards, you could then programmatically refer to any card in the collection as ItsMyParty(index#), where index# is the number written on the card.
Definition
An array is an indexed list of related data. The first element, or piece of data, stored in the array is assigned an index position of 0. The second element is assigned an index position of 1 and so on. Thus by referring to an element's index position you can access its value.
The ItsMyParty collection is an example of a single-dimension array. VBScript is capable of supporting arrays with as many as 60 dimensions. In most cases, all you'll need to work with are single dimension arrays, so that's where I will focus most of my attention.
Single Dimension Arrays
To create a single-dimension array you use the Dim statement. When used in the creation of an array, the Dim statement has to have the following syntax:
Dim ArrayName(dimensions)
Dimensions is a comma-separated list of numbers that specify the number of dimension that make up the array. For example, the following VBScript statement can be used to create a single-dimension array named ItsMyParty that can hold up to ten names:
Dim ItsMyParty(9)
Notice that I used the number 9 to define an array that can hold up to ten elements. This is because the first index number in the array is automatically set to zero, thus allowing the array to store ten elements (that is, 0 through 9).
Once an array is defined it can be populated with data.
HINT |
As the first element stored in an array has an index of 0, its actual length is equal to the number supplied when the array is first defined, plus one. |
The following VBScript statements demonstrate how you can assign data to each element in the array:
ItsMyParty (0) = "Jerry" ItsMyParty (1) = "Molly" ItsMyParty (2) = "William" ItsMyParty (3) = "Alexander" . . . ItsMyParty (9) = "Mary"
As you can see, to assign a name to an element in the array I had to specify the element's index number. Once you have populated the array, you can access any array element by specifying its index number, like this:
MsgBox ItsMyParty(1)
In this example, ItsMyParty(1) equates to Molly.
Multiple Dimension Arrays
As I previously stated, VBScript can support arrays with as many as 60 dimensions, though one or two dimensions are usually sufficient. Let's take a look at how to define a two-dimensional array, which you can think of as being like a two-column table. The first column will contain the name of the guests invited to the party and the second column will store the guest's phone numbers.
Dim ItsMyParty(3,1) ItsMyParty(0,0) = "Jerry" ItsMyParty(0,1) = "550-9933" ItsMyParty(1,0) = "Molly" ItsMyParty(1,1) = "550-8876" ItsMyParty(2,0) = "William" ItsMyParty(2,1) = "697-4443" ItsMyParty(3,0) = "Alexander" ItsMyParty(3,1) = "696-4344"
In this example, a two-dimensional array is created that is four rows deep and two columns wide, allowing it to store up to eight pieces of data. To refer to any particular element in this two-dimension array, you must supply both its row and column coordinates, like this:
WScript.Echo ItsMyParty(1,0) WScript.Echo ItsMyParty(1,1)
The first of the two previous statements refer to the Molly element. The second statement refers to the phone number associated with Molly.
Processing Array Contents
So far, in all the examples I've shown, I have accessed each array element by specifically referencing its index position. This works fine as long as the array is small, but it's not a practical approach for processing the contents of large arrays, which may contain hundreds or thousands of entries. In order to handle arrays of this size, a different approach is needed. VBScript's solution to this issue is the For...Each...Next loop. The syntax of the For...Each...Next loop is as follows:
For Each element In group Statements . . . Next [element]
Element is a variable that the loop uses to iterate through each array element. Group identifies the name of the array. Statements are the VBScripts statements that you add to process the contents of each array element. The For...Each...Next loop continues processing until every element in the array has been examined.
The For...Each...Next loop lets your scripts process the entire contents of an array using just a few statements. The number of statements required does not increase based on array size. Therefore, you can use a For...Each...Next loop to process extremely large arrays with very little programming effort. For example, the next script defines an array named GameArray() and populates it with five elements. It then processes the entire array using just one line of code located within a For...Each...Next loop.
'************************************************************************* 'Script Name: ArrayDemo.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script demonstrates how to store and retrieve data 'using a single-dimension VBScript array. '************************************************************************* 'Perform script initialization activities Option Explicit 'Define variables used in the script Dim i 'Variable used to control a For...Each loop Dim Message 'Message to be displayed in a popup dialog Message = "The array contains the following default game information: " & _ vbCrLf & vbCrLf Dim GameArray(4) 'Define an array that can hold 5 index elements GameArray(0) = "Joe Blow" 'The Default User name GameArray(1) = "Nevada" 'A Place worth visiting GameArray(2) = "Soda Can" 'An interesting object GameArray(3) = "Barney" 'A close friend GameArray(4) = "Pickle" 'A favorite desert For Each i In GameArray Message = Message & i & vbCrLf Next WScript.Echo Message
If you run this script using the CScript.exe execution host, you receive the output shown in Figure 4.14.
Figure 4.14: Iteratively processing all the contents of an array
These same few lines of code can just as easily process the array, even if it has a hundred or a thousand elements. The alternative to the For...Each...Next loop is to write an individual statement to access each element stored within the array, like this:
'Display the contents of the array WScript.Echo Message WScript.Echo GameArray(0) WScript.Echo GameArray(1) WScript.Echo GameArray(2) WScript.Echo GameArray(3) WScript.Echo GameArray(4)
While writing statements for individual access array contents may not seem like a lot of work in a small program, imagine trying to process an array with 1,000 elements.
HINT |
For more information on how to work with the For...Each...Next loop, see Chapter 6, "Processing Collections of Data." |
Resizing Arrays
Sometimes it is impossible to know how many elements an array will need to store when developing your scripts. For example, you might develop a script that uses the InputBox() function to prompt the user to specify the data to be stored in the array. While you might expect the user to specify only a few pieces of data, the user may have an entirely different idea. To handle this type of situation, you need a way of resizing the array to allow it to store the additional data.
One way of dealing with this situation is to define the array without specifying its size, like this:
Dim GameArray()
This lets you define the array's size later in the script. For example, you might want to define the array and later ask the user how many pieces of data he or she intends to provide. This is accomplished by using the ReDim statement.
ReDim GameArray(9)
This ReDim statement has set up the array to store up to ten elements. Once its size has finally been defined, you can begin populating the array with data.
TRAP |
If you use the ReDim statement to set up a new array by accidentally specifying the name of an existing array, the data stored in the existing array will be lost. |
Another, more flexible, way of setting up an array so that it can later be resized is to replace the array's original Dim definition statement with the ReDim statement. For example, the following statement will set up a new array capable of holding up to ten elements:
ReDim TestArray(9)
However, if you populate this array with data and then later attempt to resize it, as shown next, you will lose all the data originally stored in the array.
ReDim TestArray(19)
To prevent this from happening, you can add the Preserve keyword to the ReDim statement, like this:
ReDim Preserve TestArray(19)
This statement instructs VBScript to expand the size of the array while preserving its current contents. Once the array is expanded, you can then add additional elements to it. For example, take a look at the next script. It defines an array with the ability to store five elements and then resizes the array to increase its storage capacity to eight elements. The script then uses a For...Each...Next loop to display the contents of the expanded array.
'************************************************************************* 'Script Name: ResizeArray.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script demonstrates how to resize an array during 'execution '************************************************************************* 'Perform script initialization activities Option Explicit 'Define variables used in the script Dim i 'Variable used to control a For...Each loop Dim Message 'Message to be displayed in a popup dialog Message = "The array contains the following default game information: " & _ vbCrLf & vbCrLf ReDim GameArray(4) 'Define an array that can hold 5 index elements GameArray(0) = "Joe Blow" 'The default user name GameArray(1) = "Nevada" 'A place worth visiting GameArray(2) = "Soda Can" 'An interesting object GameArray(3) = "Barney" 'A close friend GameArray(4) = "Pickle" 'A favorite desert 'Insert additional script code here........ ReDim Preserve GameArray(7) 'Change the array to hold 8 entries GameArray(5) = "Lard Tart" 'Default villain name GameArray(6) = "Water Gun" 'Default villain weapon GameArray(7) = "Earth" 'Planet the villain wants to conquer 'Display the contents of the array For Each i In GameArray Message = Message & i & vbCrLf Next WScript.Echo Message
TRAP |
Be careful not to accidentally lose any data if you decide to resize an array to a smaller size. For example, if you defined an array that can hold 100 elements and then later resize it to hold 50 elements using the Preserve keyword, only the first 50 elements in the array will actually be preserved. |
Processing Data Passed to a Script at Run Time
Up to this point, every script you have seen in this chapter expects to have its data hard-coded as constants, variables, and arrays. Another way for a script to access data for processing is to set up the script so that the user can pass it arguments for processed at execution time.
Definition
An argument is a piece of data passed to the script at the beginning of its execution. For example, a script that is designed to copy a file from one location to another might accept the name of the file to be copied as an argument.
Passing Arguments to Scripts
In order to pass arguments to a script, you must start the script from the command line, as follows:
CScript DisplayArgs.vbs tic tac toe
In the previous statement, the CScript.exe execution host is used to start a VBScript named DisplayArgs.vbs. Three arguments have been passed to the script for processing. Each argument is separated by a blank space.
The next example shows a slight variation of the statement. In this case, the script still passes three arguments; but as the second argument contains a blank space, it must be enclosed in quotations marks.
CScript DisplayArgs.vbs tic "super tac" toe
Of course, in order for a script to be able to accept and process arguments at execution time, it must be set up to do so, as demonstrated in the next section.
Designing Scripts That Accept Argument Input
In order to set a script up to accept arguments, as demonstrated in the previous section, you can use the WSH's WshArguments object as shown in the following script:
'************************************************************************* 'Script Name: ArgumentProcessor.vbs 'Author: Jerry Ford 'Created: 02/29/02 'Description: This script demonstrates how to work with arguments passed 'to the script by the user at execution time '************************************************************************* 'For the explicit declaration of all variables used in this script Option Explicit 'Define variables used during script execution Dim WshArgs, FirstArg, SecondArg, ThirdArg 'Set up an instance of the WshArguments object Set WshArgs = WScript.Arguments 'Use the WshArguments object's Count property to verify that 3 arguments 'were received. If 3 arguments are not received, then display an error 'message and terminate script execution. If WshArgs.Count <> 3 then WScript.Echo "Error: Invalid number of arguments." WScript.Quit End IF 'Assign each argument to a variable for processing FirstArg = WshArgs.Item(0) SecondArg = WshArgs.Item(1) ThirdArg = WshArgs.Item(2) 'Display the value assigned to each variable WScript.Echo "The first argument is " & FirstArg & vbCrLf &_ "The second argument is " & SecondArg & vbCrLf & _ "The third argument is " & SecondArg & vbCrLf
In order to use the WshArguments object, the script must first create an instance of it, like this:
Set WshArgs = WScript.Arguments
Next, the script uses the WshArguments object's Count property to make sure that three arguments have been passed to the script. If more or fewer than three arguments have been received, an error message is displayed and the script terminates its execution. Otherwise, the script continues and assigns each of the arguments to a variable. Each argument is stored in an indexed list by the WshArguments object and is referenced using the object's Item() method. Item(0) refers to the first argument passed to the script. Item(1) references the second argument, and Item(2) refers to the third argument.
Finally, the WScript.Echo method is used to display each of the arguments passed to the script. The following output shows how the script's output appears when executing using the CScript.exe execution host and three arguments (tic, tac, and toe):
C:>CScript.exe ArgumentProcessor.vbs tic tac toe Microsoft (R) Windows Script Host Version 5.6 Copyright (C) Microsoft Corporation 1996–2001. All rights reserved. The first argument is tic The second argument is tac The third argument is toe C:>
Similarly, the following output shows what happens when only two arguments are passed to the script:
C:>CScript.exe ArgumentProcessor.vbs tic tac Microsoft (R) Windows Script Host Version 5.6 Copyright (C) Microsoft Corporation 1996–2001. All rights reserved. Error: Invalid number of arguments. C:>
Back to the Story of Captain Adventure
It is now time to return to the chapter's programming project, the Story of Captain Adventure. In this programming project, you will develop a script that displays a story describing how the story's hero, Captain Adventure, first gets his superpowers. Through the development of this script, you will have the opportunity to put your knowledge of how to work with VBScript constants, variables, and string formatting constants to the test.
Designing the Game
The basic design of this project is to ask the user a bunch of questions (without telling him what his answers will be used for), and then to use the information provided by the user to build a comical action story about a fictional hero named Captain Adventure.
This project will be completed in five steps.
- Add the standard documentation template and fill in its information.
- Define the constants and variables that will be used by the script.
- Create the splash screen that welcomes the user to the story.
- Use the InputBox() function to create variables that store user-supplied data.
- Write the story, adding the data stored in the script's variables and constants. In addition, use VBScript string constants to control the manner in which the story text is formatted before finally displaying the story using the MsgBox() function.
Beginning the Captain Adventure Script
The first step in putting this project together, now that an outline of the steps involved has been defined, is to open your editor and set up your script template as follows:
'************************************************************************* 'Script Name: CaptainAdventure.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script prompts the user to answer a number of questions 'and then uses the answers to create a comical action adventure story. '************************************************************************* 'Perform script initialization activities Option Explicit
This template, introduced in the last chapter, provides you with a place to provide some basic documentation about the script that you're developing. In addition, the template also includes the Option Explicit statement, based on the assumption that just about any script that you'll develop will use at least one variable.
Setting up Constants and Variables
The next step in creating the Captain Adventure script is to specify the constants and variables that will be used by the script.
'Specify the message to appear in each popup dialog titlebar Const cGameTitle = "Captain Adventure" 'Specify variables used by the script Dim WelcomeMsg, Name, Vacation, Object, Friend, Food, Story
The first line of code defines a constant name cGameTitle. This constant will be used to define a message that will be displayed in the titlebar area of any dialogs displayed by the script. This allows you to define the titlebar message just once, and to apply it as needed throughout the script without having to retype it each time.
The last line of code defines seven variables that the script will use. The first variable, WelcomeMsg, will store the message text that will be displayed in a splash screen displayed when the script first executes.
IN THE REAL WORLD
Sometimes splash screens are used to remind the user that she needs to register the application. In other instances, splash screens are meant to distract the user when applications take a long time to load or may be used to advertise the Web site of the application or script developer. Adding a splash screen to your script gives you the chance to communicate with the user before the script begins its execution, and it can be used to display instructions or other useful information.
The next five variables (Name, Vacation, Object, Friend, and Food) are used to store data collected from the user; they will be used later in the script in assembling the Captain Adventure story. The last variable, Story, is used to store the fully assembled Captain Adventure story.
Creating a Splash Screen
As I said, adding a splash screen to your script gives you an opportunity to display your Web site, game instructions, or other information you think will be useful to the user.
The following statements show one way of building a splash screen. The WelcomeMsg variable is used to define the text that will be displayed in the splash screen. The message text to be displayed is formatted using VBScript string constants in order to make it more attractive.
'Specify the message to be displayed in the initial splash screen WelcomeMsg = "Welcome to the story of ................" & vbCrLf & _ vbCrLf & "CCC" & space(14) & "A" & vbCrLf & _ "C" & space(17) & "AAA" & vbCrLf & _ "CCCaptain A Adventure gets his super powers" & _ vbCrLf ' Welcome the user to the story MsgBox WelcomeMsg, vbOkOnly + vbExclamation, cGameTitle
Finally, the VBScript MsgBox() function is used to display the splash screen. In this case, the vbOkOnly + vbExclamation MsgBox() constants instruct VBScript to display only the OK button and the exclamation mark graphic on the popup dialog.
In addition, the cGameTitle constant has been added in order to display the script's custom titlebar message.
Collecting User Input
The next five lines of code use the VBScript InputBox() function to collect data provided by the user. This code asks for the following information:
- What is your name?
- Name a place you would like to visit.
- Name a strange object.
- Type the name of a close friend.
- Type the name of your favorite dessert.
'Collect story information from the user Name = InputBox("What is your name?", cGameTitle," Joe Blow") Vacation = InputBox("Name a place you would like to visit.", cGameTitle," Nevada") Object = InputBox("Name a strange object.", cGameTitle," Soda Can") Friend = InputBox("Type the name of a close friend.", cGameTitle," Barney") Food = InputBox("Type the name of your favorite dessert.", cGameTitle," Pickle")
Notice that the user is only given a little bit of information about the type of information that the script is looking for. This is intentional, and is meant to provide a certain amount of unpredictability to the story line.
You may have also noticed the final argument on each of the InputBox() statements. I have added the argument so that each dialog that is displayed by the script will automatically display a default answer. Providing a default answer in this way helps the user, by giving her an idea of the kind of information you're trying to collect.
Assembling and Displaying the Story
The last step in putting together the Captain Adventure script is to assemble the story. This is done by typing out the story's text while inserting references to the script's variables at the appropriate locations in the story. In addition, the vbCrLf string constant is used to improve the display of the story.
The entire story is assembled as a single string, which is stored in a variable called Story. Finally, the completed story is displayed using the VBScript MsgBox() function.
' Assemble the Captain Adventure story Story = "Once upon a time ..........." & vbCrLf & vbCrLf & _ Name & " went on vacation in the faraway land of " & Vacation & ". " & _ " A local tour guide suggested cave exploration. While in the cave " & _ Name & " accidentally became separated from the rest of the tour " & _ "group and stumbled into a part of the cave never visited before. It " & _ "was completely dark. Suddenly a powerful light began to glow. " & Name & _ "saw that it came from a mysterious " & Object & " located in the " & _ "far corner of the cave room. " & Name & " picked it up and a flash of " & _ "light occurred and " & Name & " was instantly transported to a faraway " & _ "world. There in front of him was " & Friend & ", the ancient God of " & _ "the legendary cave people. " & Friend & " explained to " & Name & _ "that destiny had selected him to become Captain Adventure!. He was " & _ "then returned to Earth and told to purchase a Winnebago and travel the " & _ "countryside looking for people in need of help. To activate the " & _ "superpowers bestowed by " & Friend & "all that " & Name & "had to " & _ "do was pick up the " & Object & " and say " & Food & " three times " & _ "in a row." & vbCrLf & vbCrLf & _ "The End" 'Display the story MsgBox Story, vbOkOnly + vbExclamation, cGameTitle
The Final Result
Okay, now that you've written all of the various parts of the program, put them all together into a single script, as follows:
'************************************************************************* 'Script Name: CaptainAdventure.vbs 'Author: Jerry Ford 'Created: 02/28/02 'Description: This script prompts the user to answer a number of questions 'and then uses the answers to create a comical action adventure story. '************************************************************************* 'Perform script initialization activities Option Explicit 'Specify the message to appear in each popup dialog titlebar Const cGameTitle = "Captain Adventure" 'Specify variables used by the script Dim WelcomeMsg, Name, Vacation, Object, Friend, Food, Story 'Specify the message to be displayed in the initial splash screen WelcomeMsg = "Welcome to the story of ................" & vbCrLf & _ vbCrLf & "CCC" & space(14) & "A" & vbCrLf & _ "C" & space(17) & "AAA" & vbCrLf & _ "CCCaptain A Adventure gets his superpowers" & _ vbCrLf ' Welcome the user to the story MsgBox WelcomeMsg, vbOkOnly + vbExclamation, cGameTitle 'Collect story information from the user Name = InputBox("What is your name?", cGameTitle," Joe Blow") Vacation = InputBox("Name a place you would like to visit.", cGameTitle," Nevada") Object = InputBox("Name a strange object.", cGameTitle," Soda Can") Friend = InputBox("Type the name of a close friend.", cGameTitle," Barney") Food = InputBox("Type the name of your favorite dessert.", cGameTitle," Pickle") ' Assemble the Captain Adventure story Story = "Once upon a time ..........." & vbCrLf & vbCrLf & _ Name & " went on vacation in the faraway land of " & Vacation & ". " & _ " A local tour guide suggested cave exploration. While in the cave " & _ Name & " accidentally became separated from the rest of the tour " & _ "group and stumbled into a part of the cave never visited before. It " & _ "was completely dark. Suddenly a powerful light began to glow. " & Name & _ "saw that it came from a mysterious " & Object & " located in the " & _ "far corner of the cave room. " & Name & " picked it up and a flash of " & _ "light occurred and " & Name & " was instantly transported to a faraway " & _ "world. There in front of him was " & Friend & ", the ancient God of " & _ "the legendary cave people. " & Friend & "explained to " & Name & _ "that destiny had selected him to become Captain Adventure!. He was " & _ "then returned to Earth and told to purchase a Winnebago and travel the " & _ "countryside looking for people in need of help. To activate the " & _ "superpowers bestowed by " & Friend & " all that " & Name & " had to " & _ "do was pick up the " & Object & " and say " & Food & "three times " & _ "in a row." & vbCrLf & vbCrLf & _ "The End" 'Display the story MsgBox Story, vbOkOnly + vbExclamation, cGameTitle
Now, run the script and test it to make sure that everything works as expected. Be aware that this script pushes the string length allowed by VBScript to the limit. If the information that you supply to the script is too long, some of the story may end up truncated.
Summary
You covered a lot of ground in this chapter. You now know how to define and work with constants and variables, including VBScript's built-in constants and Windows environment variables. In addition, you learned how to apply VBScript string constants to script output in order to control the manner in which output is displayed. You also learned about the VBScript variant and how to use built-in VBScript functions to convert data from one variant subtype to another. Finally, you learn how to store related collections of data in arrays for more efficient storage and processing and to develop scripts that can process input passed to them at execution time.
Challenges
- Modify the Captain Adventure story by collecting additional user input and adding more text to the story line.
- Try using an array to store the user input collected in the Captain Adventure story instead of storing data in individual variables.
- Develop your own story for someone you know, and e-mail it to him or her as a sort of living greeting card.
- Experiment with the VBScript string constants when developing your own story in order to improve the format and presentation of your story's output.