Mr. Script
Class Rules
By digging into the advanced capabilities of classes, you can harness the power of VBScript and do some pretty darn amazing things.
- By Chris Brooke
- 07/01/2001
Last month, I discussed using a simple
class as a structure to hold data. This month,
I’m going to delve a bit deeper into classes by
looking at some advanced capabilities. Indeed,
classes can be as simple or as complex as you
choose.
I’ll start by backing up and looking
at the “big picture.” In past columns, I’ve used
the prefix “cls” (for Class) to identify variables—usually
when pertaining to ADSI—in order to keep things
clear. This description is valid. Every component
is, essentially, a class. The only difference
is that the component has been compiled into a
DLL, OCX or other binary file. I use the “all
poodles are dogs, but not all dogs are poodles”
analogy to describe classes. All components are
classes, but not all classes are components. Once
a class or component is instantiated—in VBScript,
this happens when you execute the CreateObject
statement—it becomes an object. Clear as mud?
Let’s move on.
Behold the Power!
Since the classes I’ll be creating are
written in VBScript, they’ll have the same limitations.
However, as evidenced by the “I Love You” virus,
VBScript can do some fairly amazing things. I’ll
demonstrate this by expanding my customer class
to allow the user to input a customer then add
that customer to a text file.
Class
Customer
Public
FName, LName, EMail, Company, TextFile
Public
Sub AddCustomer
Dim
objFSO, objFile, objTextStream
Set
objFSO=CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(TextFile)
Then
objFSO.CreateTextFile(TextFile)
End If
Set
objFile=objFSO.GetFile(TextFile)
Set
objTextStream=objFile.OpenAsTextStream(8)
' For appending
objTextStream.WriteLine
FName & " " & LName
objTextSteam.WriteLine
EMail
objTextStream.WriteLine
Company
Set
objTextStream=Nothing
Set
objFile=Nothing
Set
objFSO=Nothing
End Sub
End Class
I’ve taken my Customer class and
added a method—AddCustomer. It’s just a Sub that
opens the text file and appends the customer information.
So far, all I have is a class. Think of it as
a template or blueprint for functionality. It
doesn’t do anything unless I tell it to. I’ll
write a script to set this class in motion.
' AddCustomer.vbs
Option Explicit
Dim clsCustomer, bAddAnother
Set clsCustomer=New
Customer
clsCustomer.TextFile="C:\MyCustomers.txt"
Do
' Get customer data
clsCustomer.FName=InputBox("Enter
your first name")
clsCustomer.LName=InputBox("Enter
your last name")
clsCustomer.EMail=InputBox("Enter
your EMail address")
clsCustomer.Company=InputBox("Enter
your company")
clsCustomer.AddCustomer
bAddAnother=MsgBox("Add Another?",
vbOKCancel)
Loop While bAddAnother=vbOK
Wscript.Quit
'.
'.
'…Put the Customer class here
' End Script
As you can see, the actual script
is quite short. Since the functionality is embedded
in the class, all I need to do is cut and paste
the class into any script that needs this functionality.
For the purpose of saving space, the class writes
the customer information to a text file. You could
use what you learned about automation last month
to put it into a spreadsheet or even to add it
to your Contacts in Outlook.
Digging a Bit
Deeper
You may be asking, “Why use a class? Everything
you just showed us could be handled by simply
writing a Sub.” True. But there’s more to classes
than just setting properties and executing methods.
I’ll demonstrate this by clearing up some rules
for using classes.
Rule No. 1: You can’t set property
(variable) values directly inside a class—Let’s
assume that I wanted the FName and LName properties
to always default to my own name (I’m narcissistic
that way!) I can’t assign the values directly
like this…
Class
Customer
Public
LName, FName, EMail, Company
LName= "Brooke"
FName="Chris"
End Class
Remember that a class is just a template
for functionality. It doesn’t do anything unless
it’s told to. I tell it what to do by using a
procedure.
Class
Customer
Public
LName, FName, EMail, Company
Public Sub
SetInitialName
LName="Brooke"
FName="Chris"
End Sub
End Class
This still requires that I execute
the method SetInitialName in order to set these
default values. Let’s see if I can make it happen
automatically.
Class
Customer
Public
LName, FName, EMail, Company
Private
Sub Class_Initialize
LName="Brooke"
FName="Chris"
EMail="[email protected]"
Company="ComponentSource"
End Sub
End Class
VBScript classes include two built-in
events: Class_Initialize and Class_Terminate.
If I create methods to respond to these events,
I can have the class start working for me as soon
as it’s created (or just before it’s destroyed).
Whenever the class is initialized (Set clsMyClass=New
Class), the Class_Initialize event is fired. This
causes it to execute the code in the Class_Initialize
method, which, in this case, sets the default
values. The Class_Terminate event is fired whenever
your script destroys the object (Set clsMyClass=Nothing).
These built-in events are very useful for performing
housekeeping, setting required local class variables
and so on.
Rule No. 2: “Private” and “Public”
are not the same as “Dim”—Last month, I said
that the Public keyword takes the place of Dim
in setting up a property inside a class. This
isn’t entirely true. Public and Private establish
properties. However, your classes can use variables
that aren’t properties. They can only be used
internally, but they’re variables nonetheless.
I do this in the Customer class when I use Dim
to create variables for the FileSystemObject,
File object, TextStream and so on. Generally speaking,
the “standard” is to use Public or Private when
declaring global class variables and use Dim when
declaring temporary variables for use in class
methods.
Private class variables (declared
either with Private or Dim) can still be configured
to allow the value to be set externally. (Not
very “private,” is it?) They’re called Procedural
Properties and they open up a whole new can of
worms. I’ll discuss them in detail next month.
Rule No. 3: Every Class can have
one default value—This is different than using
a procedure such as the Class_Initialize method
to set default values to a bunch of different
properties. This is actually creating a special
property that’s returned whenever no specific
property is requested. The Default property is
also a procedural property, so we’ll look at it
next month as well.
Rule No. 4 through 10 (to the
24th power)—There are a lot of other rules
for dealing with classes. I’ll cover as many as
I can next month. I just love making you wait!
About the Author
Chris Brooke, MCSE, is a contributing editor for Redmond magazine and director of enterprise technology for ComponentSource. He specializes in development, integration services and network/Internet administration. Send questions or your favorite scripts to [email protected].