subscribe: Posts | Comments

Use of classes in VBScript

0 comments
HTML clipboard

Preamble
This tutorial is intended as an introduction to the use of VBScript classes in ASP pages. It follows from the lack of ASP developers in this field and desire to publicize a concept that is found in all languages evolved.

It is a synthesis of various articles published on this subject, mostly in English.
Despite the sake of completeness, it is possible that I forgot to address some points made. If so, thank you for making me part by MP by clicking on the link above.

I want to thank Johann Heymes and Henry Cesbron Lavau which, by their careful reading of the article, allowed me from their proposals for formulating the theoretical introduction of a clear and precise.
Summary
* A little theory
o What is a class, an object, an instance?
o Heritage
* My first class
o The scope: Private / Public
o The manufacturer: class_initialize
o The destructive: class_terminate
* The functions accessor
o Let Property
o Get Property
o Property Set
* The functions / procedures
* Case studies
o Class function
Pseudo-o legacy
* Conclusion

A little theory
What a class, an object, an instance?

A class is an encapsulation method of data: properties (variables) and methods (procedures). It is a key concept of the POO (Object Oriented Programming). The classes can build complex types that are not immediately languages; VBScript is no exception to this rule, not least because it is a weakly typed language.

Specifically, how to define a class? Imagine for example a vehicle. This vehicle has properties such as its color, weight, length, height. It also has methods: it can move forward, backward, stop. All vehicles have these characteristics: it is the concept of class. A class represents an entity, which is a computer representation of something that exists in the real world. However, my vehicle is certainly not the same as yours: different color, different weight, etc. … This introduces the concept of object: my car is an object belonging to the class vehicle, as well as yours, even if there are differences between them.
In programming, is to declare a new object class called instantiate. An object is an instance of class.

Heritage
Another important concept of the POO is the notion of inheritance. What does this mean? Take the example of the class vehicle. My car is an object of this class. But my bicycle is also an object of this class. However, there are important differences between the 2. To avoid to create an object too general, I find it possible to define a subclass will resume carcateristiques my class vehicle but will extend to add others. They talk and inheritance. Indeed my subclass (vehicule_non_motorise for example) keep the methods and properties of the base class.

Concept interesting if it is unfortunately absent in VBScript. there are other concepts that flow from that heritage, but as VBScript does not support inheritance, it is worth s'epancher greater length.

The use of classes in VBScript addresses the concepts of POO but can nevertheless not talk about Object Oriented Programming for VBscript.
The classes were introduced with version 5.0 of VBScript.

My first class
Now let's see how declare a class and how to instantiate a class.
It used to declare a class keywords and Class End Class.
<%
Class ClassTest
End Class
%>

The creation of a class is using the New keyword and assignment to a variable, as COM objects, using the keyword Set.
<%
Class ClassTest
End Class
"Creating an instance of the class ClassTest
Set instClassTest = New ClassTest
'Destruction of the body set up earlier
Set instClassTest = Nothing
%>
This class as defined at the moment does absolutely nothing. We will therefore set properties.

The scope: Private / Public
There are two cases to consider. As mentioned above, a class is an encapsulation method. Who said encapsulation said that we will define properties (variables) that will be accessible from outside the classroom, and others only inside the classroom.

If I take the example of the vehicle class, can me know how will be calculated weight, what is important is to recover the value, and only the final value, not intermediate values who have achieved it. It is the notion of reach. We will be able to declare properties (variables) public, ie available in and outside the classroom, and private property, ie only available in the classroom. As for now I only m'attache properties, it is for this reason that I failed to mention the methods, but the same principle also applies to them.

The distinction will be using the keywords Private and Public.
<%
Class Person
Public first_name
Private nickname
End Class
%>
The properties and methods of an object (but you already know) are written using the point, on the model
variable = instanceobjet.propriete
instanceobjet.propriete variable =
instanceobjet.methode ()
variable = instanceobjet.methode ()

It will therefore be able to edit and display the property name
<%
Class Person
Public first_name
Private nickname
End Class
Set instPerson= New Person
instPerson.firstname= "Jerome"
Response.Write "Hello" & instPerson.firstname
Set instPerson = Nothing
%>
If you try to do the same thing with property nickname, given that it is private, you will get the following error message:
Error Executing Microsoft VBScript error'800a01b6 '

This object does not support this property or method: 'nickname'
Some comments:
— By default, if you do not specify using the Public keyword, ie if you use the keyword Sunday to declare your variables class, the scope is public.
— It is not possible to combine Keyword Private / Public with the keyword Sunday
— It is not possible to use the keyword Redim to declare a variable of class.
— If you want to declare a variable of class as a variable table, report it with a 3 Keyword Sunday / Public / Private then resize using the keyword in a Redim procedure.
The manufacturer: class_initialize
A manufacturer is a procedure which will be called when a body will be created. This will include initialize variables in the class with a default value.

In VBScript, there is the procedure Class_Initialize ()
<%
Class Person
Public first_name
Private nickname
Private Sub Class_Initialize ()
Response.Write "The class is initialized: <br>"
first_name = "unknown"
End Sub
End Class
Set instPerson = New Person
Response.Write "Hello" & instPerson.firstname
instPersonne.prenom = "Jerome"
Response.Write "Hello" & instPerson.firstname
Set instPerson = Nothing
%>
Note: The procedure Class_Initialize () does not have arguments
The destructive: class_terminate
A destroyer is a procedure which will be called when the body will be destroyed.

In VBScript, there is the procedure Class_Terminate ()
<%
Class Person
Public first_name
Private nickname
Private Sub Class_Initialize ()
Response.Write "The class is initialized: <br>"
first_name = "unknown"
End Sub
Private Sub Class_Terminate ()
Response.Write "The class is destroyed <br>"
End Sub
End Class
Set instPerson = New Person
Response.Write "Hello" & instPerson.firstname
instPerson.firstname = "Jerome"
Response.Write "Hello" & instPerson.firstname
Set instPerson = Nothing
%>
Note: As the procedure Class_Initialize (), the procedure Class_Terminate () does not have arguments.
If you fail to explicitly destroy the body created class (which is always advisable), it will automatically at the end of the execution of the script and therefore the display caused by the procedure Class_Terminate () (instructions defined therein) will eventually document.

In VBScript, on ne parle pas builder or destructive, but events. Class_Initialize () and Class_Terminate () are the events of the class.
The functions accessor
The accessor functions are functions that will allow access (read / write) the variables of the class with a single access point, ie via a single section of code.
For example, a class that would own a property prixHT. The value that we would provide the class would be a pre-tax prices. Different functions perform calculations within the class taking whenever the price TTC, ie the price HT plus 20.6%. When the rate change, we need to change in all functions. With a function accessor, we calculate the price already TTC and this is what the class uses, so a single line of code to change when change rates.

The accessor functions in VBScript written in a way a little. See the first of them below.
Let Property

This procedure (without return value) is defined in the documentation and VBScript (brackets in the following code means that this is optional).
[Public | Private] Property Let name ([arglist,] value)
[statements]
[Exit Property]
[statements]
End Property

We must not lose sight that this is a procedure here, it therefore means that it is possible to carry out instructions (statements) as in any proceedings. Simply, they are accessed in the code as if it were a property (variable). The advantage is that you can spend more of a value ([arglist,]), the important thing is that what will be on the right of the = sign in the expression is the value (value) of the property And therefore in the definition of ownership in the classroom, we must respect the order of arguments. This property is read-only.
If one takes the code of the previous class, we can now write (slightly reworded)

<%
Class Person
Private PrStrPrenom
Private PrStrSurnom
Private Sub Class_Initialize ()
Response.Write "The class is initialized: <br>"
PrStrPrenom = "unknown"
PrStrSurnom = "unknown"
End Sub
Private Sub Class_Terminate ()
Response.Write "The class is destroyed <br>"
End Sub
Public Property Let name (StrPrenom)
PrStrPrenom = StrPrenom
End Property
Public Property Let Nickname (StrSurnom)
PrStrSurnom = StrSurnom
End Property
End Class
Set instPerson = New Person
instPerson.firstname = "Jerome"
instPerson.Surnom = "goldorak 'goldorak is not my real nickname, it's just for example;))
Set instPersonne = Nothing
%>

I used here only the value and no argument. Consider an example that has no interest in itself but will understand how to use arguments:
<%
Class Person
Private PrStrPrenom
Private PrStrSurnom
Private PrStrTitreNom
Private Sub Class_Initialize ()
Response.Write "The class is initialized: <br>"
PrStrPrenom = "unknown"
PrStrSurnom = "unknown"
End Sub

Private Sub Class_Terminate ()
Response.Write "The class is destroyed <br>"
End Sub

Public Property Let SexSitNom (StrSexe, BlnMarie, StrNom)
'StrSexe can take the values "m", "M", "f", "F"
'BlnMarie is a boolean and can therefore take the values True or False
Sunday StrTitre 'local variable to the function
If Lcase (StrSexe) = "m" Then
StrTitre = "Mr"
Else
If Then BlnMarie
StrTitre = "Ms."
Else
StrTitre = "Miss"
End If
End If
PrStrTitreNom = StrTitre & "" & PrStrPrenom & "" & StrNom
End Property

Public Property Let name (StrPrenom)
PrStrPrenom = StrPrenom
End Property

Public Property Let Nickname (StrSurnom)
PrStrSurnom = StrSurnom
End Property
End Class

Set instPersonne = New Person
instPersonne.Prenom = "Jerome"
instPerson.SexSitNom ( "m", False) = "Sauvain"
instPerson.Surnom = "goldorak 'goldorak is not my real nickname, it's just for example;))
Set instPersonne = Nothing
%>
As things stand, there is no way to recover the values that have been seized, nor any changes that were made on them. Indeed, the variables PrStrPrenom, PrStrSurnom and PrStrTitreNom which contain the values entered are declared as private and thus available only in the classroom.

So, let's see how to access these values.
Property Get
This procedure (with return value) is defined in the documentation and VBScript (brackets in the following code means that this is optional).
[Public [Default] | Private] Property Get name [(arglist)]
[statements]
[[Set] name = expression]
[Exit Property]
[statements]
[[Set] name = expression]
End Property
The operation is substantially the same as for Let, the difference now that you are going to handle the property right of equal sign in a speech. It allows us to assign a value to a variable script (outside or in the classroom) or display this value.
It is common to use as the name for a procedure Get the name already given to a procedure Let, so that these procedures meet fully their role as a gateway.

However, it is important to note that in this case, you must have the same number of arguments (arglist) declared in the procedure Get as you stated in the procedure Let. This property is write alone.
<%
Class Person
Private PrStrPrenom
Private PrStrSurnom
Private PrStrTitreNom
Private Sub Class_Initialize ()
Response.Write "The class is initialized: <br>"
PrStrPrenom = "unknown"
PrStrSurnom = "unknown"
End Sub

Private Sub Class_Terminate ()
Response.Write "The class is destroyed <br>"
End Sub

'*************** LET **************
Public Property Let SexSitNom (StrSexe, BlnMarie, StrNom)
'StrSexe can take the values "m", "M", "f", "F"
'BlnMarie is a boolean and can therefore take the values True or False
Sunday StrTitre 'local variable to the function
If Lcase (StrSexe) = "m" Then
StrTitre = "Mr"
Else
If Then BlnMarie
StrTitre = "Ms."
Else
StrTitre = "Miss"
End If
End If
PrStrTitreNom = StrTitre & "" & PrStrPrenom & "" & StrNom
End Property

Public Property Let name (StrPrenom)
PrStrPrenom = StrPrenom
End Property

Public Property Let Nickname (StrSurnom)
PrStrSurnom = StrSurnom
End Property

'*************** GET **************
Public Property Get TitreNom () 'here parentheses may be omitted
TitreNom = PrStrTitreNom
End Property

Public Property Get Nickname () 'here obviously
Nickname = PrStrSurnom
End Property
End Class

Set instPersonne = New Person
instPersonne.Prenom = "Jerome"
instPersonne.SexSitNom ( "m", False) = "Sauvain"
instPerson.Surnom = "goldorak 'goldorak is not my real nickname, it's just for example;))

Response.Write "Hello" & instPerson.TitreNom
Response.Write ", or perhaps you prefer that I call you '" & & instPerson.Surnom'? <br> "
Set instPersonne = Nothing
%>
This will give the result on the screen:
The class is initialized:
Hello Mr jerome Sauvain, or perhaps you prefer that I call you 'goldorak'?
The class is destroyed

Some comments:
— If we define a procedure Get with the name SexSitNom should therefore declare 2 arguments, not necessarily the same as in the procedure Let, ie not necessarily mean the same or similar treatment of these arguments 2 may be totally different. Therefore, when using property in the script should go 2 values:
<%
Class Person

'*************** LET **************
Public Property Let SexSitNom (StrSexe, BlnMarie, StrNom)

End Property


'*************** GET **************
Public Property Get SexSitNom (arg1, arg2)
SexSitNom = arg1 & PrStrTitreNom & arg2
End Property

End Class
Set instPerson = New Person
instPerson.firstname = "Jerome"
instPerson.SexSitNom ( "m", False) = "Sauvain"
instPerson.Surnom = "Goldorak"

Response.Write instPerson.SexSitNom ("|", "|") & "<br>"
Set instPerson = Nothing
%>
On-screen display:
The class is initialized:
| Mr Jerome Sauvain |
The class is destroyed
— There is no requirement that the procedure Get Property does not behave as real property, it means that it is right in a speech. It suffices that it will not return any value. However, for reasons of clarity and understanding of the code, I strongly advises you to use this way
<%
Class Person

'*************** GET **************
Public Property Get First ()
PrStrTitreNom = PrStrTitreNom & "blah blah"
Response.Write PrStrPrenom & "<br>"
End Property

End Class

Set instPerson = New Person
instPerson.firstname = "Jerome"
instPerson.SexSitNom ( "m", False) = "Sauvain"
instPerson.Surnom = "Goldorak"
instPerson.firstname
Response.Write instPerson.SexSitNom ("|", "|") & "<br>"
Set instPersonne = Nothing
%>
On-screen display:
The class is initialized:
Jerome
| Mr Sauvain jerome bla bla |

— The use of keyword Set in the definition of the procedure will help define the property as object type and non-type Variant. For example:
<%
Class ClsFichier

Public Property Get FSO ()
Set FSO = Server.CreateObject ( "Scripting.FileSystemObject")
End Property
End Class
Set instClsFichier = New ClsFichier
Set FSO = instClsFichier.FSO
Set instClsFichier = Nothing
%>

Property Set
This procedure (without return value) is defined in the documentation and VBScript (brackets in the following code means that this is optional).
[Public | Private] Property Set name ([arglist,] reference)
[statements]
[Exit Property]
[statements]
End Property
As for Let the procedure Property Set will help define a property in reading, meaning that we will write to the left of the = sign in a speech. The big difference with Let, is that we will not assign a value type Variant but a reference to an object. This object may be a COM object (as an object ADO connection), or an instance of class.

This property is read-only.
Let's use the following example: this class will make it possible to instantiate an object FileSystem, write a line of text in a file, and read the contents of this file. It is not the best possible implementation but this is an example I think enough speaking.
<%
Class ClsFichier
Private file, scfso
Public Property Set FSO (RefFSO)
Set scfso = RefFSO
End Property
Public Property Let OpenFile (IOMode, CreateIfNotExist, Filename)
Set file = scfso.OpenTextFile (Filename, IOMode, CreateIfNotExist)
End Property
Public Property Let WriteTexte (Text)
file.writeline Text & "" & Now ()
End Property
Public Property Get ReadTexte ()
ReadTexte = file.readall
End Property
End Class
Set instClsFichier = New ClsFichier
Set insClsFichier.FSO = Server.CreateObject ( "Scripting.FileSystemObject")
insClsFichier.OpenFile (8, true) = "c: file.txt"
= insClsFichier.WriteTexte "Toto"
insClsFichier.OpenFile (1, true) = "c: file.txt"
Response.Write insClsFichier.ReadTexte
Set insClsFichier = Nothing
%>
The functions / procedures
The functions (procedure with return value: Function) and procedures (without return value: Sub), whether declared private or public, will be the methods of the class.

As for all other statements made in class, they are public by default unless you specify with the keyword in front of the Private Keyword Function / Sub.

It could, echoing the preceding example, write a method CloseFile which would close the file and destroy the body set up this file in the classroom, and referring an error message or confirmation. It could also rewrite OpenFile to make either a property but a method.
<%
Class ClsFichier
Private file, scfso
Public Property Set FSO (RefFSO)
Set scfso = RefFSO
End Property
Public Property Let WriteTexte (Text)
file.writeline Text & "" & Now ()
End Property
Public Property Get ReadTexte ()
ReadTexte = file.readall
End Property
Public Sub OpenFile (Filename, IOMode, CreateIfNotExist)
Set file = scfso.OpenTextFile (Filename, IOMode, CreateIfNotExist)
End Sub
Public Function CloseFile ()
On Error Resume Next
file.Close
Set file = Nothing
If Err.Number Then
CloseFile = "Error No." & Err.Number & "when closing the file:" & Err.Description
Else
CloseFile = "File closed"
End If
End Function
End Class
Set instClsFichier = New ClsFichier
Set insClsFichier.FSO = Server.CreateObject ( "Scripting.FileSystemObject")
insClsFichier.OpenFile "c: file.txt", 8, true 'no brackets because it is a procedure
insClsFichier.WriteTexte = "Toto"
Response.Write insClsFichier.CloseFile () & "<br>"
insClsFichier.OpenFile "c: file.txt", 1, true
Response.Write insClsFichier.ReadTexte
Set insClsFichier = Nothing
%>
We would have pu make the procedure OpenFile function with a return value in the same manner as CloseFile.

General note: At no point in all codes is given instruction Exit procedure or proceeding may be Property / Sub / Function. However, be aware (if not) that this instruction allows you to stop treating the procedure in question and leave.
Case studies

Class function
An interesting possibility offered classes is to fill a gap in VBScript. Indeed, the functions / procedures VBScript not accept the arguments optional. Thanks to classes, you can fill this gap. This means that we construct a class containing only variables class public (or private with procedures Public Property), an event initialization, and a procedure (with or without return value).
<%
Class ClsFonction
Public Name, Name
Private Sub Class_Initialize ()
PrStrPrenom = "Pifou"
PrStrNom = "dog"
End Sub
Public Sub Welcome ()
Response.Write "Hello" First & & "" & & Name "<br>"
End Sub
End Class
Set instClsFonction = New ClsFonction
instClsFonction.Nom = "Sauvain"
instClsFonction.Welcome
Set instClsFonction = Nothing
%>

Pseudo-legacy
Attention, I speak well of pseudo-inheritance and no inheritance, inheritance, as stated in the introduction, does not exist in VBScript. What I then by pseudo-legacy? Quite simply the possibility of declaring an instance of class A inside of a class B and thus be able to use the properties and methods of classes A and B with an object of class B. You do not understand? Here is a very simple example which will help clarify my remarks.
<%
Class ClsPere
Private PNom
Private Sub Class_Initialize ()
PNom = "father"
End Sub
Public Property Let LetPNom (un_nom)
PNom = un_nom
End Property
Public Property Get GetPNom ()
GetPNom = PNom
End Property
End Class
Class ClsFils
Private instClsPere, FNom
Private Sub Class_Initialize ()
Set instClsPere = New ClsPere 'instantiating an object of class father in the class son
End Sub
Public Property Let LetFNom (un_nom)
FNom = un_nom
End Property
Public Property Get GetFNom ()
If IsEmpty (FNom) Then

'If the variable FNom has not been explicitly defined using the property LetFNom, it returns the value contained in the ownership of Class GetPNom father
GetFNom = instClsPere.GetPNom
Else
GetFNom = Fnom
End If
End Property
Private Sub Class_Terminate ()
Set instClsPere = Nothing
End Sub
End Class
Set instClsFils = New ClsFils
Response.Write "hello" & & instClsFils.GetFNom "<br>"
instClsFils.LetFNom = "son"
Response.Write "hello" & & instClsFils.GetFNom "<br>"
Set instClsFils = Nothing
%>

Tel what defined the class son, unfortunately we can not use methods and properties of class father outside the classroom son, meaning it is not possible to write:
Response.Write "hello" & & instClsFils.GetPNom "<br>"

To write this kind of code would define property GetPNom inside the classroom son, the latter being an interface to access the property GetPNom of class father … or it would have VBScript supports inheritance. Specifically in relation to this code, it would suffice to rename the property GetFNom class son of a GetPNom. However, this is very heavy as it should do the same for all properties and methods of class father, which ultimately would almost rewrite (not quite anyway) class father within the class son . In other words, why do two classes?

The solution is to provide the class son of a property which provides access to class father (outside the classroom) and therefore all of its properties and methods. We just have to add the following property in class son:
Public Property Get GetinstClsPere ()
Set GetinstClsPere = instClsPere
End Property

We can now use the properties and methods of two classes, however, writing code to manipulate those of the class father via an object of class son will be a little different:
Set instClsFils = New ClsFils
Response.Write "hello" & & instClsFils.GetinstClsPere.GetPNom "<br>"
instClsFils.GetinstClsPere.LetPNom = "papa"
Response.Write "hello" & & instClsFils.GetinstClsPere.GetPNom "<br>"
Response.Write "hello" & & instClsFils.GetFNom "<br>"
instClsFils.LetFNom = "son"
Response.Write "hello" & & instClsFils.GetFNom "<br>"
Set instClsFils = Nothing
%>

Conclusion
The examples presented here are relatively simple. However, your classes can be far more complex, possess a whole battery of procedures and other procedures Property Sub and Function.

You can instantiate inside the same class of COM objects, other classes, objects incorporated ASP language, brief only your imagination and use that you'll make your class limit its complexity.

The examples presented combine in the same script the definition of class and its instantiation. This is obviously not common usage. It is better to separate the two and write code definition of the class in a file (nomdelaclasse.asp) to be able to use this class in several scripts, and therefore to include this file in every script that requires the use of class.

The classes do not replace COM components (dll and exe) that are faster implementation (because they operate in a process different from that of the page), but they are sometimes necessary:
— Your host does not have any particular component and refuses to install, then you fend for yourself and a class is certainly the best solution
— If you have the objective of creating a component (especially if you write in Visual Basic), it allows you to test the validity of the code very easily and quickly (no need to compile, store and restart whenever IIS) and make the changes necessary
— It also gives you a code portable as independent components installed on the server hosting your application, so you can easily move your application from one server to another
The main disadvantages compared to a COM component are less powerful and less timeliness.
Another disadvantage is the persistence of non classes. A class (or rather an object of class) exists only in the script that uses it, its properties are lost from one page to another. Also it is not possible to place an object class in a variable session or application. See in this regard this article (in English) which proposes various methods to get a pseudo-persistence.
To sum up (very) quickly, classes can perform complex operations through a simple interface, so … your keyboards.