VBScript is a Basic-like language that many popular applications (e.g., Microsoft Outlook, Internet Explorer—IE) and many developer products (e.g., Microsoft Visual Studio—VS) use. VBScript descends from Visual Basic for Applications (VBA), which is the language Visual Basic (VB) and Microsoft Office products rely on. Although Microsoft initially designed VBScript as a scripting language for the Web, VBScript has become a popular language for writing Windows-oriented batch files through the Windows Scripting Host (WSH). With WSH, the Windows OS treats a VBScript file as an executable—in other words, like a batch (.bat) or executable (.exe) file. As a result, you can use VBScript's rich and powerful functions and syntax to compose system-level scripts.
In this five-part series, I'll provide you with a global look at VBScript's evolution in the Windows-based scripting scenario. I'll also delve deep into all the aspects of the language. In this first installment, I give you an overview of the system context in which VBScript works and introduce you to the WSH and ActiveX scripting environments. Then, I describe three basic syntax elements: variables, constants, and data types, or simply types.
How VBScript Fits in the Script Scenario
VBScript is a scripting language that many people consider the modern version of MS-DOS batch files. However, because VBScript inherited VBA's rich syntax and expressivity, VBScript is more akin to a programming language than a simpler scripting language. Unlike programming languages, VBScript doesn't use a compiler, but it still processes code fairly quickly. Overall, VBScript offers the power and design of a programming language while maintaining a scripting language's ease of use.
In the Windows world, you can use VBScript within one of four technologies or environments: WSH, Web-based shell views, Active Server Pages (ASP), and IE. You typically use VBScript code within Web-based shell views, ASP, and IE to produce HTML pages. You typically use VBScript within WSH to automate systems administration tasks. Thus, this series will cover VBScript within WSH only.
The Roles of WSH and ActiveX
WSH is the system module that transforms a VBScript file into a Windows executable file. WSH is readily available for the various Windows OSs. In Windows 2000 (Win2K), WSH is a standard OS component. In Windows 98, WSH is an optional component that you can select during setup. For Windows NT 4.0 and Win95, WSH is available as an add-on.
WSH consists of a Windows-based host (wscript.exe), a console-based host (cscript.exe), the WSH object model (wshom.ocx), the VBScript scripting engine (vbscript.dll), and the JScript scripting engine (jscript.dll). Both wscript.exe and cscript.exe work as a runtime engine that manages and executes VBScript files. The WSH object model is a runtime library of built-in COM objects. The presence of COM is an important aspect of WSH and VBScript. Because VBScript can create an instance of, or instantiate, COM objects, WSH's extensibility has no limits. As a result, you can write scripts that access any system feature and that provide any kind of behavior. The VBScript and JScript scripting engines parse and interpret VBScript and JScript code, respectively.
The underlying technology that enables WSH to run VBScript, JScript, and other language files is ActiveX Scripting. ActiveX Scripting is a COM-based specification that lets Microsoft and third-party vendors provide runtime engines for virtually any scripting language. Any 32-bit Windows application can host an ActiveX Scripting-compliant module and manage and run script files written in various languages. In other words, the ActiveX Scripting interface lets Windows support all types of scripting languages.
For example, WSH and IE are applications that host all ActiveX Scripting-compliant engines and that natively distribute the VBScript and JScript scripting engines. The statement that WSH and IE support only VBScript and JScript means that WSH and IE deploy the parsers for those languages only. (The parser is the runtime module that actually interprets a script file, validating the syntax and processing the instructions. The presence of a runtime parser is what makes a scripting language different from a compiled language such as C++.) Other companies ship ActiveX Scripting engines for Perl, REXX, and Python, and you can use these scripting engines for IE and WSH, too.
VBA has many powerful functions and provides excellent support for variables, data types, and error handling. VBScript inherited much of VBA's functionality, including support for math operations, arrays, flow control, data conversions, COM objects, procedures, and date, time, and string manipulation. However, because Microsoft initially designed VBScript for the Web, Microsoft eliminated direct I/O functions and stripped down the support for types to increase VBScript's processing speed. As a result, VBScript doesn't support explicit types and doesn't include native commands to directly access the client machine's disk.
However, if you use VBScript locally within the WSH environment, you can use two external COM objects to supply the otherwise missing functionality: FileSystemObject, which you use to manipulate files and folders, and WScript, which you use to read and write to the system Registry and more. The scrrun.dll and wshom.ocx files include the FileSystemObject and WScript objects' runtime libraries, respectively. (Scrrun.dll is a system file in VBScript and Win98.)
In the latest version of VBScript, Microsoft has added several new functions and has introduced classes and regular expressions. These additions are moving VBScript closer toward the rank of an effective programming language. (I'll cover these additions to VBScript 5.0 in a future article.)
Three Basic Syntax Elements
VBScript's syntax includes many elements. Three important elements are variables, constants, and types. A variable is an item that holds data that can change during a script's execution, whereas a constant is an item that holds data that can't change during a script's execution. You classify the data that variables and constants hold into types. For example, long integer numbers are a type called Long, double-precision floating-point values are a type called Double, and text is a type called String.
When you use compiled programming languages, you must explicitly declare the variables you intend to use and specify those variables' types. In VBA and VB scripts, for example, you use the Dim statement with the As qualifier to declare variables and their types:
Dim x As Long
When you use VBScript, you're not required to explicitly declare your variables; if you don't declare your variables, you can't declare their type. However, implicit declaration (declaration that automatically occurs when you use a variable in a script) is a potential source of bugs because typing errors typically go undetected until a problem arises. To prevent such problems, you can add the Option Explicit command at the top of your script. The Option Explicit command forces the runtime engine to accept only those variables you explicitly declare. If you use a variable that you haven't declared, you receive an error message. You can declare variables with any of these commands:
Dim x Dim x,y Private x,y Public x,y,z
You must use the Public and Private commands at the beginning of a script; you can use Dim statements at any point. Variables that you declare at the script's start are script-level declarations that apply to all the subroutines and functions in a script. Variables that you declare within a subroutine or function are procedure-level declarations that apply only to that local subroutine or function.
Notice that the Dim, Private, and Public statements don't include the As qualifier. In VBScript, you can't explicitly declare types. If you use a statement such as Dim y As Long in your VBScript code, you'll receive an Expected end of statement error because the VBScript parser won't understand the additional information that the As qualifier contains. After a Dim, Private, or Public statement, VBScript expects to find a comma followed by another variable declaration, a colon followed by a statement, or a line return specifying the end of the statement.
The lack of a type declaration doesn't mean that VBScript doesn't support types. Rather, VBScript considers all variables the same type: Variant. As Figure 1 shows, the parser manages all the variables through the generic Variant type. If Microsoft had designed VBScript so that you had to explicitly declare types, the parser would've had to perform extensive type checking. Unlike compiled languages, VBScript performs all syntax and type checks during runtime. Thus, VBScript's assumption that all variables are the Variant type saves the parser a great deal of time.
How Variants, Types, and Subtypes Work
Stating that all variables are the same type might seem implausible, especially when some types are dissimilar, such as Long and String. However, VBScript successfully groups all variables as Variant because Variant is a generic type that provides a uniform programming interface for the other types. In other words, a Variant is a generic reference (i.e., a high-level pointer) to the types. When you specify
you're telling VBScript to create an empty Variant variable. When you specify
x = 45
you're telling VBScript to fill the Variant x variable with the numeric value of 45 and to add information that registers the value's data content as an Integer. This additional information is called the subtype. (People often refer to subtypes as variable types.) You can think of a Variant as a supertype rendered by the
Table 1 contains the VBScript subtypes. The subtypes are self-explanatory, except for the Empty and Null subtypes. A variable with the Empty subtype differs from a variable with the Null subtype. An Empty variable doesn't contain any data; a Null variable contains no valid data.
Because the Variant type is a high-level reference, you can change a variable's value and subtype fields at runtime by assigning a new value to the variable. For example, Listing 1 changes a variable's content. You begin the code by declaring Dim x and Dim y, which prompts VBScript to create two empty variables called x and y. You then set the x variable to "Hello!" In response, VBScript determines that the "Hello!" value is a String subtype and fills the x variable's value and subtype internal fields with "Hello!" and String, respectively. Similarly, when you set the y variable to 45, VBScript determines that the value of 45 is an Integer subtype and fills the y variable's value and subtype internal fields with 45 and Integer, respectively. Finally, you set the x variable to a new value—the y variable (i.e., 45)—which prompts VBScript to change the x variable's fields from "Hello!" and String to 45 and Integer. As a result, both the x and y variables now have the same value and subtype.
You need to be careful to not set ambiguous values. For example, the value of 1.0 can be a Double, Single, or Currency subtype. By default, VBScript considers 1.0 to be a Double subtype. Even more ambiguous is the value of 1. It can be a Boolean, Integer, Long, or Byte subtype. By default, VBScript considers 1 to be an Integer subtype.
Listing 2 shows you how to empty a variable and assign null data. After you declare your variable, you set the variable to null if you want no valid data or to empty if you don't want any data in the variable. You use the empty and null variables when working with COM objects. In particular, you use them to check for null return values.
Because the parser declares subtypes for you, you sometimes need to determine the subtype that the parser assigned for a particular variable. VBScript offers many functions that identify subtypes, including the TypeName function, the VarType function, and several IsXxx() functions.
TypeName. You use the TypeName function to identify the subtype name of a specific variable. Listing 3 illustrates how this function works. If you set the x variable to the number 45, TypeName returns a subtype name of Integer. If you set the same x variable to the text "Hello!", TypeName returns a subtype name of String. Finally, if you set the x variable to the date value Now, TypeName returns a subtype name of Date.
Why didn't TypeName return the subtype name of String when you set the x variable to Now? In VBScript, you set text in quotes. If you set the x variable to "Now" instead of Now, TypeName returns a subtype name of String. Without the quotes, Now is a VBScript function that returns the current date and time.
VarType. In Windows, each subtype has an ID number. You use the VarType function to identify a variable's subtype ID number. VarType works similar to TypeName except that VarType returns a number instead of a string. If you need to compare two variables' subtypes or check a subtype against a given value, using VarType is preferable because working with numbers saves you from possible typing errors. Don't dismiss this reason as silly—many seasoned developers and scriptwriters have encountered mysterious bugs only to find out later that mistyped strings were the culprit.
IsXxx(). A series of IsXxx() functions lets you determine whether a specified variable or constant is a certain subtype. To check whether a variable or constant is an Array, Date, Empty, Null, or Object subtype, you use the syntax
in which Xxx is the subtype name and expression is the variable or constant you want to check. For example, if you want to check whether the MyVar variable has the Date subtype, you specify
Like all the Is() functions, IsDate returns the Boolean value. If IsDate returns a value of true, the variable's subtype is Date. If IsDate returns a value of false, the variable's subtype isn't Date.
For numeric subtypes (e.g., Long, Integer, Double), you use the syntax
in which expression is the variable or constant you want to check.
Advanced Subtype Operations
In a programming environment with no explicit types, you might not expect to get a type mismatch error. However, if you try the code in Listing 4, you get the message box in Screen 1. This error occurs because you can't sum numbers and strings, which is what the x + y operation tries to do. When you're using VBScript, you can't forget the elementary rules about types. Although the scripting engine declares, initializes, and passes variables for you, you still need to control advanced subtype operations through conversion functions. VBScript uses an all-encompassing, undistinguished type to achieve better performance by reducing the amount of type-checking. VBScript doesn't use the undistinguished type so that users can freely mix heterogeneous data.
Conversion functions let you convert a value from one subtype to another (e.g., a Long value to a String value) or convert a value from one numeric or alphanumeric system to another (e.g., a hexadecimal value to an octal value). Table 2 describes the conversion functions that you can use. The VarType column displays the ID of the subtype involved.
When you use conversion functions, keep in mind three points. First, you can't pass an alphanumeric string to a conversion function that returns a number (e.g., CInt, CLng). If you try, you'll receive a type mismatch error. (CLng converts a string such as 3 to the Long subtype but not an alphanumeric string such as 3A.) Instead, you can use CInt, CLng, or a similar function to adapt the results of arithmetic operations.
Second, the CStr function provides great flexibility when you're converting an expression to the String subtype. For example, if the expression is a date, you receive a date string that follows your OS's short date format. In the case of a Boolean expression, the string specifies either true or false.
Third, the CDate function effectively converts a string or number to a date. However, you can avoid using a conversion function by assigning the date value to the variable. You just need to enclose the value in hashes (#):
MyDate = "#4/5/99#"
A constant is an explicit value (number, string, or other) to which VBScript or the scriptwriter assigns a name. Constants that VBScript assigns are intrinsic constants. These constants don't change. VBScript defines several categories of intrinsic constants for use in various contexts. For example, the Color category includes intrinsic constants that define various colors (e.g., vbBlack specifies the color black) and the String category includes intrinsic constants that define text-related functions (e.g., vbTab specifies a horizontal tab).
Constants that a scriptwriter assigns can't change during the lifetime of the script. You don't use constants in place of variables. Instead, you use constants in place of explicit values. Using constants is more manageable than using explicit values for two reasons. First, if you need to change a constant's value, you change it only once. Otherwise, you'd need to change that value each time it occurs in the script. Second, constants make scripts easier to read, especially if you assign a mnemonic name to the constant.
To create a constant, you use the syntax
const MyVal = 1234
in which MyVal is the constant name and 1234 is the value of that constant. The value must be explicit. You can't use a function or another constant as the value. For example, the following code isn't valid:
const CRLF = Chr(13) & Chr(10)
After you create the constant, you use the constant name in lieu of specifying that explicit value.
The Next Step
Now that you're familiar with VBScript's evolution in the Windows-based scripting environment, the roles that ActiveX and WSH play in that environment, and three basic syntax elements, you're ready to take the next step. In Part 2, I'll show you how to use VBScript syntax elements with operators, functions, and statements.