Until recently, the only way you could write reusable VBScript code was to import external files through VBScript's Include function or through parser-specific features, such as the server-side include (SSI) directive of Active Server Pages (ASP) or the source (SRC) attribute of <SCRIPT> blocks in HTML. Today, you have two elegant yet powerful options: Windows Script Components (WSC) and VBScript classes.
WSC leverages a standard, fixed binary module that hard-codes a few COM interfaces. A client module connects to this engine and asks for the functions the COM interfaces provide. The code that executes isn't binary code but rather interpreted VBScript (or JScript) code. Apart from this layered internal architecture, each component in WSC is a typical COM object. (I'll discuss WSC in a future article. If you don't want to wait, you can read "ASP and Windows Script Components," Microsoft Internet Developer, December 1999, or Andrew Clinick, "Windows Script Components—They Get Around," http://msdn.microsoft.com/workshop/languages/clinic/ scripting091399.asp.)
VBScript classes are ASCII modules that VBScript internally implements as COM objects. Like WSC, you can use VBScript classes to invoke methods and properties. Unlike WSC, VBScript classes don't support events. However, you can use pseudoevents in classes. The sidebar "A Workaround for Events," page 2, explains how.
Another difference between VBScript classes and WSC is that VBScript classes offer better performance at creation time. Instantiating a class is slightly faster than instantiating a component because you use different instantiation approaches. To instantiate a component, you must use the CreateObject method. This method requires the language parser to pass through the system's Registry and the COM infrastructure, which adds processing time. To instantiate a class, you use the New keyword, which Microsoft added in VBScript 5.0. This keyword doesn't require the language parser to pass through the system's Registry and the COM infrastructure, so VBScript classes enjoy the advantage of better performance.
To reuse VBScript classes, you can import them with Windows Scripting Host (WSH) 2.0 or with WSH 1.0 and a VBScript 5.0 runtime evaluation function. You can also reuse VBScript classes by adapting, or porting, them into Visual Basic (VB) code.
Importing Classes with WSH 2.0
After you create a VBScript class, you can import that class across client files and applications. (If you're unfamiliar with how to create a class, see "Creating Classes with VBScript 5.0," December 1999.) Importing classes is easy with WSH 2.0 because WSH 2.0 has a new file format (.ws) to include files. You can download WSH 2.0 at http://www.microsoft.com/msdownload/ vbscript/scripting.asp.
To import a class with WSH 2.0, you need to isolate the class code in a separate .vbs file and use the code in Listing 1. This code, which goes into the .ws file you use to import the class, contains WSH 2.0's new <job> and <script> elements. You use the <job> element to specify the particular job. (You can have more than one job in a script.) The <job> element's syntax is
' Job code goes here.
where JobID is the job's unique identifier. You use the <script> element to specify the scripting language and the SRC. The <script> element's syntax is
' Script goes here.
where "language" is the scripting language and "strFile" is the script's filename. In Listing 1, you see two <script> tags. The first tag imports the VBScript code from an external file, and the second tag specifies the use of that code. (You can find the details about the new WSH 2.0 file format in Andrew Clinick, "If It Moves, Script It," http://msdn.microsoft.com/workshop/languages/clinic/scripting061499.asp.)
For example, suppose you want to import the VBScript class FileList.vbs, which manages files that meet a certain filename specification in a folder. (You can find FileList.vbs on the Win32 Scripting Journal Web site at http://www.winntmag.com/newsletter/scripting.) Listing 2 shows how you import that class in a WSH 2.0 script. After you specify the scripting language and the class file, you use the New keyword to create an instance of that class.
At this point, you use the class in the same way you use any other COM object. In this case, you're returning the list of the files that match the filename specification *.sys in an array named aFiles. Next, you use the For Each...Next statement to walk through the array and append all its elements to a null-separated string for display. When you run this code, the selected files will come from the C drive, even if the client application doesn't explicitly set the folder path. This situation occurs because VBScript assigns default values to the class properties during class initialization.
Importing Classes with WSH 1.0
If you use WSH 1.0, you need to use the VBScript 5.0 runtime evaluation function ExecuteGlobal to import a VBScript class. Specifically, you need to isolate the class code in a separate .vbs file and use a subroutine such as that in Listing 3.
This subroutine uses the Include function to obtain the .vbs file, then uses the Microsoft Scripting Run-Time Library's FileSystemObject (FSO) to read in that file's content. The subroutine ends with the ExecuteGlobal function evaluating the string (str) you pass to it. If str contains a class declaration, the effect is the same as including all the class file's content at the top of a script.
At the beginning of any WSH 1.0 script in which you want to import the class, you must embed the line
where "MyClass.vbs" is the name of the .vbs file containing the class code. You also need to embed the Include subroutine at the end of the script. For example, Listing 4 shows how you import FileList.vbs in a WSH 1.0 script. Callouts A and B in Listing 4 highlight the code you need to embed.
Porting VB and VBScript Classes
VBScript is a language derived primarily from Visual Basic for Applications (VBA)—the core language of the VB development tool. In VBA, you don't need to comply with any particular syntax to define a new class. You just define a class in a separate .cls file and tell the VB environment (i.e., the IDE) to add that new class to the appropriate VB project. The IDE then creates and adds the new .cls file to that project. You don't use the New keyword to define the class because the IDE stores all the meta-information about the class in the .cls file.
In VBScript, you don't use projects. A .vbs file is self-contained, so you must create a class without relying on an external file such as the .cls file. Consequently, you use the Class keyword to identify a class.
Aside from these differences, VBScript and VBA classes are similar. Thus, you can port a VBA class into VBScript code. In most cases, you need only to wrap the VBA class code in a VBScript Class statement with code such as
' VBA class code goes here.
where NameOfTheClass is the name of the VBScript class. However, you need to remember that a VBScript class doesn't support events. In addition, syntax differences exist. For example, only VBA supports the Friend and Static keywords. (For more information about the differences between VBA and VBScript, see the Microsoft articles "VBScript Features Not in Visual Basic for Applications" and "Visual Basic for Applications Features Not in VBScript." Go to http://msdn.microsoft.com/scripting/ default.htm?/scripting/vbscript/techinfo/vbsdocs.htm, and click Language and Run-Time Reference. The links to both articles appear in the Feature Information drop-down list.)
You can also port a VBScript class into VBA code. You need to copy the VBScript class code, paste it in a .cls file that you've opened in a VB project, and make any necessary syntax modifications. For an example of how to port a VBScript class into VBA code, see the Web-exclusive sidebar "Porting the FileList Class to a VB 6.0 Project" on the Win32 Scripting Journal Web site.
Recycle Your Code
If you isolate your VBScript classes in separate .vbs files, you can import the classes' functionality wherever you need it—whether that's in a different file or a different application. You can also port your existing VBA classes to VBScript code and vice versa. Whether you import or port classes, the end result is the same. You save time and effort because you can reuse already-proven code.