Home | Forums | Contact | Search | Syndication  
 
 [login] [create account]   Friday, April 19, 2024 
 
Using Classes in VBScript  
Description:  SalesLogix v6 opens up a whole new door for SalesLogix developers. Now, with VBScript, you have in your arsenal a new set of tools with the ability to use all that VBScript has to offer - all from inside of SalesLogix. One of the best new things we can now use (in my opinion) is using classes in scripts. This article will cover how to use classes in VBScript for making some routine tasks easier to use and more reusable.

Category:  SalesLogix VBScript Articles
Author:  Ryan Farley
Submitted:  11/14/2002
   
Stats: 
Article has been read 55634 times

Rating: - 4.9 out of 5 by 19 users
 

fiogf49gjkf0d
Using Classes in VBScript

SalesLogix v6 opens up a whole new door for SalesLogix developers. Now, with VBScript, you have in your arsenal a new set of tools with the ability to use all that VBScript has to offer - all from inside of SalesLogix. One of the best new things we can now use (in my opinion) is using classes in scripts. This article will cover how to use classes in VBScript for making some routine tasks easier to use and more reusable.


Introduction

Let's take a look at what a class or object really is (If you are already familiar with the concept of a class or object, you may want to skip over this section). First, let's look at a couple of terms:

  • What is an object?
    An object is basically a "code" container. It contains variables, functions, etc, and is normally used to represent an entity of some kind.
  • What is an entity?
    An entity is literally a "thing". Ok, not too descriptive, is it? I suppose what I mean about a "thing" is some sort of idea or maybe a tangible item. Like a "product", or even the "sale" of a product could be this "thing" or entity. An entity could be a history item, or even a person.

Let's explore the idea of having a "sale" entity. You would need to know several things about this entity, such as which product they purchased, who purchased it, who the sales person was, etc. It may seem simple enough to get all of this data, but all of these pieces that make up this "sale" entity could potentially be stored in different tables - each with possibly it's own query to the database, which is all still doable, but wouldn't it be nice to work with one single item that represented all of this information? Helloooo, object. Your code will be cleaner, it will be easier to use, and you can reuse it whenever you need to represent this "sale" entity. If you need to change a calculation or something in the sale object, you change it only in the class that makes up the object and it is affected everywhere it is used.


More About Objects

An object, or really the class that makes up, or describes, the object, mainly contains two things. Properties and Methods.

  • Properties
    Properties are really just facts, or attributes that the entity has. For example, in our example above, the "sale" entity would have several properties such as Sale Date, Sales Person, Product, etc.
  • Methods
    Methods are really actions in the entity that can yield results or change something about the entity. For example, in our "sale" entity, there could potentially be methods to process a sale, which would deduct the product from inventory, and charge the customer. Possibly calculate sales tax (for new sales). Or maybe to add payments against the sale. Methods in terms of VBScript are either subroutines or functions.

Example syntax for properties & methods would look something like this:

'property
objSale.SalesDate = Now

'method
amtRemaining = objSale.AddPayment("25.99")    


Creating Classes

Ok, enough talk already, let's look at some code! Creating classes are really simple, what might take some time is getting yourself to think about code as separate, reusable entities. Obviously, since this site is dedicated to SalesLogix development, from here on we'll focus on how to do this in respect to SalesLogix (although most of what is covered here will still work in other VBScript environments).

In the SalesLogix Architect, let's create a new VBScript plugin. We don't need a Sub Main or anything like that (so take that out of the VBScript window). The class does not need an entry point since it is not "invoked" or "run". Instead it is "instanciated". Ideally, how you will want to build classes in SalesLogix, is to create them as a separate VBScript plugin. Although you could create the class in the code behind a form, it is not reusable that way. If we create it in a separate VBScript plugin, we can simply "include" it in the script we want to use the class in by using the cool new feature to include scripts (see Using Classes section later on in this article). For our example that follows, we'll focus on building a class to add a history item in SalesLogix. So thinking in terms of objects and entities, the "History Item" is our entity. It will have properties for things like the ContactID it is for, the date, etc. We'll make the assumption that it will be used for adding history items to contacts only

Basic syntax of a class is to name the class with a 'Class' and 'End Class'. Here's an example.

Class History
End Class

It may not look like much (because it really isn't as of yet), but we could create an instance of the class like this:

'create and instanciate the History object
Dim objHistory
Set objHistory = New History

'we could do things with it here, but we haven't defined any of that yet

'let's get rid of it
Set objHistory = Nothing

Now we'll add some properties to it. But first, there are a few things to know about properties. There are 3 kinds of properties in VBScript. Let, Set, & Get properties. Let's take a look at what those mean.

  • Let
    The Let property is your standard "pass something to the class" property. For example, if our History item has a "property" or "attribute" of completed date (which it will), then this completed data would be a Let property of the class. It would "Let" us give this value to the class.
  • Set
    The Set property is very similar to the Let property, with the exception that it is used for objects. If we have a property in our class to hold an ADO Recordset or another class object, then we would need to "Set" the reference using a Set Property. In our example, we will not use a Set property because all of our values will be strings or numbers which are used as Let properties (since they are 'value' types, not referencing an object)
  • Get
    Last but not least is the Get property. This is the one you'll use often. It is used to "get" a value from the class. For example, in our history class, we could add a Get property to get the ID of the newly created history item.

Another thing to note is scope (this applies to both properties and methods). VBScript Class members can be private or public. What this means is whether or not it is visible outside the class, or if it is hidden within the class for only the class to use. If you want something to be accessed outside the class you mark it public. Our History class will have a public "Add" method to add the history values to the history table. It will also have a private function to create a new history ID. Our class needs this internally and we don't want to expose this to the outside (if they want an ID they can create one themselves, it really wouldn't apply to our history entity).

Ready? Let's add some properties to out class. For our example, we'll keep things simple and only add the minimal number of required fields to our class for adding history items. They way a property works is to publicly access (ie: from outside the class) a private member or variable. We need to create the private variables (denoted with a 'm_' prefix) and then expose them through properties.

Private m_type
Private m_conId
Private m_startDT
Private m_completedDT
Private m_userID
Private m_desc
Private m_notes
Private m_historyID

'Here are the "writable" Let properties
Public Property Let HistoryType(ByVal val)
	m_type = val
End Property

Public Property Let ContactID(ByVal val)
	m_conId = val
End Property

Public Property Let StartDate(ByVal val)
	m_startDT = val
End Property

Public Property Let CompletedDate(ByVal val)
	m_completedDT = val
End Property

Public Property Let UserID(ByVal val)
	m_userID = val
End Property

Public Property Let Description(ByVal val)
	m_desc = val
End Property

Public Property Let Notes(ByVal val)
	m_notes = val
End Property

'Here are the "readable" Get properties
Public Property Get HistoryID
	HistoryID = m_historyID
End Property

Doesn't that look nice? We could make a property both readable and writable by adding both a Let and a Get for the same property name, but we won't do that in our example. Let's say we want to initialize some values, like the userid. A class has two methods that fire when the class is created and when the class is terminated. If you add these subroutines to your class they will automatically run when those two events happen. Here's what those special methods look like.

Private Sub Class_Initialize()
Private Sub Class_Terminate()

In our class we'll add a Class_Initialize to set the userid to the current user. The code using the class could always change it later using the property, but this way it does not need to be set, unless it is for a user other than the current one.

Private Sub Class_Initialize()
	m_userID = Application.BasicFunctions.CurrentUserID
End Sub

Now all we really have left is to create the public "Add" method to create a row in the history table. There's going to be a few other things happening here to get some other values here, such as the accountid and account name for the contactid set in the object.

Public Sub Add
Dim cn

    Set cn = Application.GetNewConnection
    m_historyID = GetNewID("history")

    cn.Execute GetInsertSQL()

    cn.Close
    Set cn = Nothing
End Sub

Private Function GetInsertSQL()
Dim sql

    sql = "insert into history (historyid, type, accountid, accountname, "
    sql = sql & "contactid, contactname, startdate, userid, timeless, duration, "
    sql = sql & "description, notes, longnotes, "
    sql = sql & "createuser, createdate, completeduser, completeddate) "
    sql = sql & "values ('"
    sql = sql & m_historyID & "', "
    sql = sql & "'" & m_type & "', "
    sql = sql & "'" & GetContactValue(m_conId, "accountid") & "', "
    sql = sql & "'" & GetContactValue(m_conId, "account") & "', "
    sql = sql & "'" & m_conId & "', "
    sql = sql & "'" & GetContactValue(m_conId, "fullname") & "', "
    sql = sql & "'" & m_startDT & "', "
    sql = sql & "'" & m_userID & "', "
    sql = sql & "'T', "
    sql = sql & "'0', "
    sql = sql & "'" & Replace(m_desc, "'", "''") & "', "
    sql = sql & "'" & Replace(Mid(m_notes, 1, 254), "'", "''") & "', "
    sql = sql & "'" & Replace(m_notes, "'", "''") & "', "
    sql = sql & "'" & Application.BasicFunctions.CurrentUserID & "', "
    sql = sql & "'" & Now & "', "
    sql = sql & "'" & m_userID & "', "
    sql = sql & "'" & m_completedDT & "')"

    GetInsertSQL = sql
End Function

Private Function GetContactValue(ByVal conid, ByVal field)
Dim val

    val = GetValue(field, "contact", "contactid = '" & conId & "'")
    GetContactValue = Replace(val, "'", "''")
End Function

Private Function GetNewID(ByVal table)
Dim rs
Dim cn

    Set cn = Application.GetNewConnection
    Set rs = cn.Execute("slx_dbids('" & table & "', 1)")

    GetNewID = rs.Fields(0).Value & ""

    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Function

Private Function GetValue(ByVal field, ByVal table, ByVal where)
Dim rs
Dim cn

    Set cn = Application.GetNewConnection
    Set rs = cn.Execute("select " & field & " from " & table & " where " & where)

    If Not (rs.BOF Or rs.EOF) Then
        GetValue = rs.Fields(0).Value & ""
    Else
        GetValue = ""
    End If

    rs.Close
    Set rs = Nothing
    cn.Close
    Set cn = Nothing
End Function

That may seem like a lot, but really I just wanted to make the demo functional. If you don't understand everything that is going on there then don't worry about it. The purpose of this article is to demonstrate how to create & use classes in VBScript. There will be other articles to cover ADO basics, VBScript basics, & how to create SalesLogix IDs, etc. For now, let's move on to how to use the class. This is where you'll love it because things could not get any simpler on that end.


Using Classes

Now that we understand how to make a class, let's take a look at how to use it. Create a new Contact form and add a picklist named pklDesc (for the To-Do Regarding picklist), a memo named memNotes for the notes, and a button to instanciate the class and add the history item. In the button's Click event, place the following code:

Sub btnAddHistoryClick(Sender)
Dim objHistory

    'instanciate the history object
    Set objHistory = New History

    With objHistory
    	 'set the properties
         .HistoryType = "262147"
         .ContactID = Application.BasicFunctions.CurrentContactID
         .StartDate = Now
         .CompletedDate = Now
         .UserID = Application.BasicFunctions.CurrentUserID
         .Description = pklDesc.Text
         .Notes = memNotes.Text

         'call the history object's add method to insert the history item
         .Add

         MsgBox "History item added with ID '" & .HistoryID & "'"
    End With

    'dereference the history object
    Set objHistory = Nothing

    pklDesc.Text = ""
    memNotes.Text = ""
End Sub

Now look at that. Enough to bring tears to my eyes. Isn't that clean? Now whenever you want to add a history item, you could use this class and have the same simple syntax you see above. All you have to do is add the script, instanciate the object, set it's properties and away you go. I like it!


Including The Class VBScript

We've talked a lot about how we will use the class and they only way to go is to include the script. Just to make sure everyone knows what we mean by this, let's take a minute before we end to look at that. SalesLogix v6 has a great new feature to include a VBScript so you can use it in another script (or script behind a Form). To do this, all you have to do is click the "Include Script" button on the top right of the code window and select the VBScript that has your class in it. Take a look at this screenshot:



Easy enough. Now you can include the class VBScript whenever you need to add history items. Cool. One thing to note about adding Include Scripts. When you include a script, the script name will be automatically added as a comment at the top of your code window. This makes it easy to see that you are including a script without showing the Included Scripts pane of the code window.


Wrapping it up

Knowing how to take advantage of things available to you in VBScript will allow you to make your life as a SalesLogix developer much simpler. With classes, you can encapsulate complex or redundant code to make performing those tasks easier. The best part of all is it begs for code reuse. You can develop your own "toolbox" bundle containing all your classes that you use each time you develop in the Architect. Gotta love that!

Until next time, happy coding.
-Ryan
 

About the Author

  Ryan Farley
(SalesLogix Business Partner)
Customer FX Corporation

fiogf49gjkf0d

Ryan Farley is the Director of Development for Customer FX and creator of slxdeveloper.com. He's been blogging regularly about SalesLogix since 2001 and believes in sharing with the community. He loves C#, Javascript, Python, web development, open source, and Linux. He also loves his hobby as an amateur filmmaker.

View Ryan's SalesLogix Mobile Seveloper Series
View Ryan's SalesLogix SData Developer Series
View Ryan's Git for the SalesLogix Developer series



View online profile for Ryan Farley
 

[ back to top] [ send to a friend]  

Rate This Article you must log-in to rate articles. [login here] 
 
Please log in to rate article.
 

Related Articles 
 - Using Classes in VBScript Sample Bundle - Submitted by: Ryan Farley

 

Comments & Discussion you must log-in to add comments. [login here] 
 
Author Article Comments and Discussion
Mike Spragg

slxdeveloper.com Forum Top 10 Poster!

So Cool !
Posted: 12/1/2002 11:03:25 AM
fiogf49gjkf0d
Suddenly, the penny drops ! This idea is going to make new projects in v6 pretty simple. Of course, the opposite of code re-use (code proliferation) is that the breakage of one class/include will break everything else too that relies on it ! At least with the "old" version you could sandbox that effect. Still, must get out of the past and into the future !!! :-)
 
Graham Macleod
 

Nice Job!
Posted: 12/21/2002 7:38:43 PM
fiogf49gjkf0d
Nicely done, Ryan, very clear and easy-to-follow. Thanks for all your efforts putting this site together!
 
Martin Draper
 

This is great! But what about future upgrades?
Posted: 9/17/2003 6:33:53 AM
fiogf49gjkf0d
This is fantastic. Finally OO Design hits SLX.
But what about future upgrades. Obviously SalesLogix 6.1 only has a handful of forms/scripts rewritten using VB Script. In future they may rewrite far more of the code. If BP's are also doing the same thing, it makes me wonder if when the next major release comes along will there be a conflict of interests when upgrading.
 
Ryan Farley

slxdeveloper.com Site Administrator
slxdeveloper.com Forum Top 10 Poster!

Re: This is great! But what about future upgrades?
Posted: 10/6/2003 1:01:54 AM
fiogf49gjkf0d
Martin, on the contrary. When ever SLX releases new versions of existing forms, there will be a conflict as you'll need to either scrap your form and use theirs to get any new functionality, or you'll need to built the new functionality into your existing form. However, encapsulating code into classes that you could use as include scripts minimizes the amount of logic you have scripted behind the actual form itself. So, your conversion process to the new form will likely be much easier since there will be less code to transfer to the new form to bring over any current customizations.

But, all in all, there is no way to avoid the need to convert as SLX releases more forms as active forms.

-Ryan
 
Peter Anton
 

It is a great !!!!!!
Posted: 12/2/2003 4:09:40 PM
fiogf49gjkf0d
Rayn

What if I use Application.BasicFunctions.LogSetGlobalID strAccountID to send the history record to all who have access to the particular account. Is it going to work.

Thanks,
Peter
 
Ryan Farley

slxdeveloper.com Site Administrator
slxdeveloper.com Forum Top 10 Poster!

Re: LogSetGlobalID
Posted: 1/9/2004 4:18:20 PM
fiogf49gjkf0d
Peter,

LogSetGlobalID is no longer required in v6. That is done automatically by the SalesLogix OLEDB Provider. So, the history record will automatically go out to the remotes who receive the related account.

-Ryan
 
Kevin Hoelzel
 

Re: Using Classes in VBScript
Posted: 6/18/2004 11:01:29 AM
fiogf49gjkf0d
Ryan, I'm having trouble with VBScript when attempting to convert what seems to be an easy function of the Legacy Basic script SLX_AcctDetail_TimeZone_WhenChange. This script is called from the Legacy Form Account:Detail when a user changes the timezone on the form. The local time is then calculated and posted to an edit box on this Detail form. I had a need to rebuild a new form in Active and can't seem to get the function to work in VBScript. What class would I use? I've tried Application.BasicFunctions.. but no luck at all. Can you help me out?


sub slx_Specific()
'*********************************************************************************************************
' subroutine
'*********************************************************************************************************
GMTNow=LocaltoGMT(Now)
Timezone=GetCleanPropertyOf("pl_timeZone","TextCode")
If Timezone = "" then
SetPropertyOf "de_LocalTime","Text", ""
else
SetPropertyOf "de_LocalTime","text",GMTToTimeZone(GMTNow,TimeZone)
end if

'*********************************************************************************************************
end sub
 
Steve Irwin
 

ByVal v ByRef
Posted: 7/4/2004 3:25:11 PM
fiogf49gjkf0d
Ryan,
I noticed that all the passed arguments were ByVal. Have you had any success trying to pass ByRef?
 
Ryan Farley

slxdeveloper.com Site Administrator
slxdeveloper.com Forum Top 10 Poster!

Re: Using Classes in VBScript
Posted: 7/10/2004 1:30:54 PM
fiogf49gjkf0d
Steve,

Sure, I use ByRef parameters when needed, however they would not have been needed in this example. ByRef works the same in VBScript as it does in regular VB.

-Ryan
 
Jiho Han
 

Re: Using Classes in VBScript
Posted: 9/22/2004 11:57:50 AM
fiogf49gjkf0d
One thing that really sucked the juice out of me for the longest time in using classes in VBScript is that you never know when the referred class is going to be picked up by the garbage collector and disposed of. This has some implications in how you would code.

You see, I had an error handling on the client - the "user" of the class - and this function checked for a certain error code and if not in the range, it simply exited so the error would be propagated to the next tier. The thing is that the error was disappearing as soon as the function exited and where I expected an error to be caught by the next tier, there was none. You see, I had error handling routine in the Class_Terminate sub in the class I was using. So, the On Error Resume Next in the sub basically erased my previous error that I was looking for.

One work around other than not doing error handling in your Class_Terminate, is to set all class objects to Nothing before you exit. Before that though, you would have copied the error info somewhere otherwise you'd still lose it. Then when the objects are set to Nothing - this does not mean they are disposed though, it only means Class_Terminate is called -, you can rethrow the error. This is not a cure-all either though since if you have classes that use other classess that use yet other classes, and so on, it can get very hairy and almost impossible to manage. So, don't use error handling in Class_Terminate if you don't have to although I know sometimes you can't avoid it.

Thank God for the exception system in .NET...
 
Christopher Harper
 

Public Functions on Forms
Posted: 12/1/2004 1:36:54 PM
fiogf49gjkf0d
Any idea how to access public subs or functions in forms? In my case, I have written a public function I have written on frmAccountDetails but can't find a way to reference the form that gets me access to the function.
 
Ryan Farley

slxdeveloper.com Site Administrator
slxdeveloper.com Forum Top 10 Poster!

Re: Using Classes in VBScript
Posted: 12/1/2004 1:43:19 PM
fiogf49gjkf0d
Christopher,

To be clear, this really does not have to do with classes in VBScript. However, there is a way to do what you are looking for. I am not sure which version this was introduced in, it might be 6.1.1 (I know it works in 6.2, just not sure if it works in prior versions). The form reference will have a 'Script' property which will give you access to the script on that form.

So you get a reference to the form and use it like this:

Application.Forms("System:MyForm").Script.MySub

to access the sub "MySub" on the form "System:MyForm". Got it?

-Ryan
 
Christopher Harper
 

Re: Using Classes in VBScript
Posted: 12/1/2004 3:23:45 PM
fiogf49gjkf0d
True, it is not quite classes except forms are a class. It seemed close enough to give it a shot.

BTW, bless you, the horse you rode in on, its saddle, etc.. I'll be giving the "Script" property a shot instantanter.

Where in the documentation does that gem live?
 
Ryan Farley

slxdeveloper.com Site Administrator
slxdeveloper.com Forum Top 10 Poster!

Re: Using Classes in VBScript
Posted: 12/1/2004 3:27:30 PM
fiogf49gjkf0d
Hehe. Thanks Christopher. BTW, I don't believe it is documented (if it is I have not come across it yet)

-Ryan
 
tripti88
 

Re: Using Classes in VBScript
Posted: 4/13/2008 6:54:46 AM
fiogf49gjkf0d
hello
how can I download SalesLogix v6.2 Service Pack 1?
 
Mike Spragg

slxdeveloper.com Forum Top 10 Poster!

Re: Using Classes in VBScript
Posted: 4/13/2008 7:26:37 AM
fiogf49gjkf0d
You need to approach your Business Partner. If you have a valid Support & Maintenance contract you can get this for free from them.
 
 

       Visit the slxdeveloper.com Community Forums!
Not finding the information you need here? Try the forums! Get help from others in the community, share your expertise, get what you need from the slxdeveloper.com community. Go to the forums...
 



 slxdeveloper.com is brought to you courtesy of Ryan Farley & Customer FX Corporation.
 This site, and all contents herein, are Copyright © 2024 Customer FX Corporation. The information and opinions expressed here are not endorsed by Sage Software.

code of conduct | Subscribe to the slxdeveloper.com Latest Article RSS feed
   
 
page cache (param): 4/19/2024 1:38:44 AM