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.

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].

Featured

comments powered by Disqus

Subscribe on YouTube