Procedures

In this chapter, you will see how VBScript procedures can be used to improve the overall organization and manageability of your scripts. You will learn about the two types of procedures supported by VBScript, subroutines and functions. This chapter will cover how to use procedures to control variable scope by defining local and global variables. You will also learn how to create event handlers that react to browser events and will examine the types of browser events to which VBScript can react. Finally, you will examine VBScript's complete collection of built-in functions.

Organizing VBScript into Procedures

VBScript procedures provide the basic building blocks of VBScript organization. Procedures allow you to create modular scripts that organize statements into logical groups that can be executed as a unit. VBScript supports two different types of procedures:

Procedures have two main benefits: First, they provide a means of organizing VBScripts into a more manageable format. Second, procedures allow you to create reusable code and reduce the overall size of scripts.

Enhanced Script Maintenance

Procedures allow you to create scripts that are easier to maintain by allowing you to group related statements together and to execute them as a unit. Therefore, as a general rule, you should use procedures as the primary organization construct for your VBScripts. By developing modular code using VBScript, you make your scripts easier to read and maintain. For example, by grouping related statements together in a procedure, you make them easier to find. You also make the script easier to update, allowing individual modules or procedures to be updated without having to make substantial changes to other parts of the script.

By making scripts easier to manage, procedures allow you to add more complexity without necessarily making them more difficult for you to work with or maintain. As suggested in Chapter 2, "Errors, Constants, and Variables," when developing scripts that will be run using the WSH, consider developing a VBScript template similar to that in the following example.

'************************************************************************* 'Script Name: ScriptName.vbs 'Author: Author Name 'Created: mm/dd/yyyy 'Description: Place a brief description of the script here '************************************************************************* 'Initialization Section 'Main Processing Section 'Procedure Section

Using this template, you would place all subroutines and functions in the Procedure section. This provides a consistent organization to your scripts by providing a predictable location for storing and finding procedures. The important thing is to group your procedures together where you can easily find them in your VBScripts. Most VBScript programmers choose to store their subroutines and procedures at the end of their scripts.

When developing VBScripts that are embedded inside HTML pages, most programmers generally locate their subroutines and functions in a VBScript placed in the HEAD section. This helps to ensure that all procedures have been initialized before being called upon by VBScripts or event handlers located in the HTML page's BODY section.

Reusable Code

Functions and subroutines help make for smaller scripts by allowing the creation of reusable modules of code that can be called upon as many times as necessary from any location within a script. Therefore, functions and subroutines should be used in any situation where a particular task needs to performed more than once within a script.

Procedures also make script maintenance easier because you only have to modify the code located in one procedure instead of making the same change over and over again to code that would otherwise be duplicated throughout a script.

Subroutines vs Functions

Subroutines and functions perform nearly identical roles within VBScripts. Both provide a means for grouping and executing collections of related statements. Both provide a means of limiting variable scope, which is discussed later in this chapter. They even share a similar syntax. Where they differ is in their ability to return data back to the statement that calls them. Functions provide this capability, whereas subroutines cannot return a result back to their calling statement.

Subroutines

Subroutines are used to execute a collection of statements without returning a result to a calling statement. Once executed, a subroutine returns processing control back to the statement that follows its calling statement.

Subroutines are created using the VBScript Sub statement. The Sub statement defines the name of the subroutine and any arguments that it expects to receive. The syntax for the Sub statement is shown below.

[Public | Private] Sub name [(arglist)] statements End Sub

Public and Private are optional keywords. The Public keyword specifies that the subroutine can be called upon by other procedures located within the script. The Private keyword specifies that the subroutine cannot be called upon by other procedures within the script. Name is the name assigned to the subroutine and must be unique within the script. Arglist is a list of comma delineated arguments that can be passed to the subroutine when it is called.

To call a subroutine, you type its name in the following format:

SubroutineName()

The closing parentheses characters () are required. You can call a subroutine and pass it arguments by specifying the arguments, separated by commas, within the parentheses, as demonstrated below.

SubroutineName(arg1, arg2, arg3, ... argn)

For example, the following VBScript statement defines a subroutine called AboutRoutine().

Sub AboutRoutine() MsgBox "UserAcctMgr.vbs" & vbCrLf & vbCrLf & _ "Copyright Jerry Ford 2003" & vbCrLf & vbCrLf & _ "For more information about UserAcctMgr.vbs please contact " & _ "jlf04@yahoo.com", ,"About Sample Script" End Sub

This subroutine might be included as part of a larger script to provide information about the script. When called, AboutRoutine() uses the MsgBox() function to display information about the script. This subroutine has not been designed to accept any arguments as input and can be called from anywhere in the script using the following statement.

AboutRoutine()

When executed, this subroutine displays the pop-up dialog box shown in Figure 4.1.

Figure 4.1: Using a subroutine to display information about a script

The following example demonstrates how to define a subroutine that accepts and processes one argument when called upon to execute.

Sub DisplayMsg(strMsgText) MsgBox strMsgText, , "VBScript Subroutine Demo" End Sub

This subroutine could be added to any VBScript to provide a generic message display procedure. It accepts a single argument, which in the case of this example would be a text string passed to it by its calling statement. For example, the following statement could be used to execute the DisplayMsg() subroutine, which results in displaying the pop-up dialog box shown in Figure 4.2.

Figure 4.2: Viewing a message displayed using a generic message display subroutine

DisplayMsg("This message will be displayed by a message display subroutine.")

Functions

Functions are similar to subroutines, except that they also provide the ability to return a result to their calling statements. The syntax for functions is outlined below.

[Public | Private] Function name [(arglist)] statements End Function

Public and Private are optional keywords. The Public keyword specifies that the function can be called upon by other procedures located within the script. The Private keyword specifies that the function cannot be called upon by other procedures within the script. Name is the name assigned to the function and must be unique within the script. Arglist is a list of comma delimitated arguments that can be passed to the function when it is called.

For example, the following function represents a rewrite of a previous subroutine that displays information about a script in a pop-up dialog box.

Function AboutRoutine() MsgBox "UserAcctMgr.vbs" & vbCrLf & vbCrLf & _ "Copyright Jerry Ford 2003" & vbCrLf & vbCrLf & _ "For more information about UserAcctMgr.vbs please contact " & _ "jlf04@yahoo.com", ,"About Sample Script" End Function

This function can be called using the following statement from anywhere within the script that defines it.

AboutRoutine()

When used in this manner, there is no advantage to using a function over a subroutine. The advantage of using a function in place of a subroutine is the function's ability to return a result to its calling statement. In order to return a result back to its calling statement, a function must define a variable with the same exact name as the function and then assign the result that is to be returned to that variable. When the function stops executing, the value is then returned to the calling statement. For example, the following function might be used to collect the name of a file from the user.

Function GetFileName() GetFileName = InputBox("Please type the name of the file you wish to open.") End Function

The name of the function is GetFileName(). It uses the VBScript InputBox() function to collect the name of a file from the user and assigns the file name typed by user to a variable named GetFileName. Note that the name of the variable is exactly the same as the name of the function (less the parentheses). To execute this procedure, the calling statement can reference it, as shown below.

strFileName = GetFileName()

In this example, the name of the file that is returned by the function is assigned to a variable name strFileName. Another way to call the function would be to include a reference to it within a VBScript statement, as shown below.

MsgBox "Click on OK to delete " & GetFileName()

In this example, the MsgBox() function includes a reference to the GetFile-Name() function and substitutes the results returned by that function into the message that it has been set up to display.

Functions can also accept arguments passed to them at run time, as demonstrated below.

Function DisplayMsg(strMsgText) MsgBox strMsgText, , "VBScript Subroutine Demo" End Function

Controlling Variable Scope

Procedures provide VBScript with the ability to localize or isolate variables. Any variable defined outside of a procedure is global in scope, meaning that it can be referenced from any location within the script. A variable with a local scope, on the other hand, is one that is defined within a procedure and can be accessed only from within that procedure. Local variables exist only as long as the procedure that defined them is executing.

By localizing variable values, you eliminate the possibility of accidentally modifying a variable outside of the procedure where it was created. As a programming technique, it is generally preferable to localize variables as much as possible. The following example demonstrates the differences between local and global variables.

'************************************************************************* 'Script Name: Script 4.1.vbs 'Author: Jerry Ford 'Created: 01/04/2003 'Description: This script demonstrates global and local variable scopes '************************************************************************* 'Initialization Section Option Explicit Dim X, Y 'Main Processing Section X = 10 GetNewNumber() MsgBox "X = " & X & " Y = " & Y 'Procedure Section Function GetNewNumber() Dim Y Y = 20 End Function

In this script, two variables are defined, X and Y. The X variable and its value are both defined in the script's Main Processing Section and are global in scope. Next, the script executes the GetNewNumber() function, which defines the Y variable and sets its value. Once the GetNewNumber() function is finished, processing control returns to the Main Processing Section, which then uses the VBScript MsgBox() function to try and display the values assigned to X and Y. However, only the value of X can be displayed because the Y variable no longer exists.

Figure 4.3 shows the output produced when this script is executed by the WSH.

Figure 4.3: A demonstration of variable scope within and outside of VBScript procedures

Browser Event Handling

Within the context of client-side Web page development, VBScript procedures have a special role in building event handlers that respond to browser events. This adds interactivity to Web pages and allows front-end processing to be performed on the client computer. An event is an occurrence of an action within a browser. For example, a mouse click on an image, button, or link represents a click event. Other examples of events include double-clicking on Web page objects, typing text into form elements, clicking on form buttons, and moving the pointer over and off of objects. Browser events also occur when Web pages load or unload.

To react to an event, you must add event handlers to your scripts. An event handler is a trap that recognizes when an event occurs and executes one or more VBScript statements. For example, if a visitor clicks on a form's submit button, the click event associated with that button can be used to trigger the execution of an event handler that performs form validation.

By defining functions and subroutines and storing them in the head section of an HTML page, you can create a library of event handlers that can be associated with any object on a Web page.

Examining Events and Event Handlers

Table 4.1 provides a list of browser events for which you can define event handlers. Table 4.1 also provides the name of the event handler associated with each event and a description of the event and event handler. As you can see, event handlers are named by adding on to the beginning of the event name with which it is associated.

Table 4.1: Browser Events and Event Handlers

Property

Event Handler

Description

Abort

onAbort

Executes when the visitor aborts an image while it is loading

Blur

onBlur

Executes when the currently selected object loses focus

Change

onChange

Executes when the visitor changes an object

Click

onClick

Executes when the visitor clicks an object

DblClick

onDblClick

Executes when the visitor double-clicks an object

DragDrop

onDragDrop

Executes when the visitor drags and drops an object onto a frame or window

Error

onError

Executes when an error occurs on the HTML page

Focus

onFocus

Executes when a visitor selects an object

KeyDown

onKeyDown

Executes when a visitor presses down on a key

KeyPress

onKeyPress

Executes when a visitor presses and releases a key

KeyUp

onKeyUp

Executes when a visitor releases a key

Load

onLoad

Executes when an HTML page or image finishes loading

MouseDown

onMouseDown

Executes when a visitor presses a mouse button

MouseMove

onMouseMove

Executes when a visitor moves the pointer

MouseOut

onMouseOut

Executes when a visitor moves the pointer off of an object

MouseOver

onMouseOver

Executes when a visitor moves the pointer over an object

MouseUp

onMouseUp

Executes when a visitor releases a mouse button

MouseWheel

onMouseWheel

Executes when a mouse wheel is rotated

Move

onMove

Executes when the visitor moves a frame or window

Reset

onReset

Executes when a visitor clicks on a reset button

Resize

onResize

Executes when the visitor resizes a frame or window

Select

onSelect

Executes when a visitor selects the contents of a form select menu

Submit

onSubmit

Executes when a visitor clicks on a submit button

Unload

onUnload

Executes when a visitor closes the browser window or frame or loads a different URL

Setting Up Event Handlers

Events are associated with specific objects. Likewise, event handlers are associated with specific events and objects. When an event occurs, its associated event handler, if one has been written, is automatically executed. There are three different ways in which to set up the execution of an event handler. The first option is to embed the event handler inside an HTML tag, as demonstrated below.

 

In the case of this example, the onLoad event is automatically triggered when the HTML page is loaded by the browser, displaying a pop-up message. While convenient for performing tasks that require minimal coding, this option is limited. Another option provided by VBScript is to set up event handlers, as demonstrated below.

 

The third and most commonly used option is to define event handlers that call procedures stored within VBScripts located within the HTML page's HEAD section, as demonstrated below.

Sub SubmitButton_onMouseOver window.status = "Click here to submit your request." End Sub

When used in conjunction with event handlers, procedure names are created by combining the name of an object button and the name of the appropriate event handler. For example, the previous subroutine is automatically triggered whenever the pointer is moved over a form button named SubmitButton on the HTML page. When executed, it displays a text message in the browser's status bar located at the bottom of the browser.

To further demonstrate the use of VBScript procedures as constructs for storing statements that are called by event handlers, look at two more examples. In the first example shown below, an HTML page has been set up that contains a VBScript in its HEAD section. This VBScript defines a single function called ShowGreetingMsg(). This function will execute when called by the onLoad event handler specified in the

tag example, as highlighted below.

 

Script 4.2 - onLoad event handler exampleonLoad=ShowGreetingMsg()> onLoad event handler example

Figure 4.4 shows the output produced when this HTML page is loaded by Internet Explorer.

Figure 4.4: A pop-up dialog box displayed by a function that has been called by a VBScript event handler

Another popular use of event handlers is in the creation of animated rollover effects, which change the appearance of a link, image, or object in some manner whenever the pointer is moved over or off of the object. Rollovers can be created using the onMouseOver and onMouseOut events, which are listed below.

For example, the following script demonstrates how to set up an HTML page with two rollover links. One is for the Premier Press Web site and the other is for Microsoft's Web site.

 

Script 4.3 - A demo of how to creak a link rollover<a href="http://www.premierpressbooks.com" name="Premier">Premier</a>

<a href="http://www.microsoft.com" name="Microsoft">Microsoft</a>

In order to set up a rollover for each link, two functions must be set up as event handlers for each link. The first function defines the statements to be executed for the onMouseOut event handler and the second function defines the statements to be executed for the onMouseOver event handler. Notice that unlike the previous example in which the

tag explicitly called the function specified by the onLoad event handler, the functions in this example are automatically associated with links because of the manner in which their names were formulated.

When executed, these functions modify the color of the text used to display each link, depending on which event handler is being executed. Figure 4.5 shows the output produced when this HTML page is loaded by Internet Explorer. However, it is difficult to see how the rollover links work from an examination of Figure 4.5. To get a better understanding, create and run this script yourself.

Figure 4.5: Creating rollovers using event handlers

Built in Functions

In this chapter, you learned how to create your own custom functions. Using functions, you can create modular scripts and group related VBScript statements together in some logical manner. VBScript also provides a large collection of ready-to-use built-in functions that you can reference from your VBScripts. Using built-in VBScripts saves you the time and trouble required to reinvent a function to perform a task for which Microsoft has already provided a solution. This speeds up script development time while making for smaller scripts that are easier to manage. Table 4.2 provides a list of VBScript's built-in functions.

Table 4.2: VBScript Functions

Function

Description

Abs

Returns a number's absolute value

Array

Returns an array based on the supplied argument list

Asc

Returns the ANSI code of the first letter in the supplied argument

Atn

Inverse trigonometric function that returns the arctangent of the argument

CBool

Converts an expression to a Boolean value and returns the result

CByte

Converts an expression to a variant subtype of Byte and returns the result

CCur

Converts an expression to a variant subtype of Currency and returns the result

Cdate

Converts an expression to a variant subtype of Date and returns the result

CDbl

Converts an expression to a variant subtype of Double and returns the result

Chr

Returns a character based on the supplied ANSI code

Cint

Converts an expression to a variant subtype of Integer and returns the result

CLng

Converts an expression to a variant subtype of Long and returns the result

Cos

Trigonometric function that returns the cosine of the argument

CreateObject

Creates an automation object and returns a reference to it

CSng

Converts an expression to a variant subtype of Single and returns the result

Date

Returns the current date

DateAdd

Adds an additional time interval to the current date and returns the result

DateDiff

Compares two dates and returns the number of intervals between them

DatePart

Returns a portion of the specified date

DateSerial

Returns a variant (subtype Date) based on the supplied year, month, and day

DateValue

Converts a string expression into a variant of type Date and returns the result

Day

Converts an expression representing a date into a number between 1 and 31 and returns the result

Eval

Returns the results of an evaluated expression

Exp

Returns the value of an argument raised to a power

Filter

Returns an array based on a filtered set of elements using supplied filter criteria

FormatCurrency

Returns an expression that has been formatted as a currency value

FormatDateTime

Returns an expression that has been formatted as a date or time value

FormatNumber

Returns an expression that has been formatted as a numeric value

FormatPercent

Returns an expression that has been formatted as a percentage (including the accompanying %)

GetLocale

Returns the locale ID

GetObject

Returns a reference for an automation object

GetRef

Returns a reference for a procedure

Hex

Returns a hexadecimal string that represents a number

Hour

Returns a whole number representing an hour in a day (0 to 23)

InputBox

Returns user input from a dialog box

InStr

Returns the starting location of the first occurrence of a substring within a string

InStrRev

Returns the ending location of the first occurrence of a substring within a string

Int

Returns the integer portion from the supplied number

IsArray

Returns a value of True or False depending on whether a variable is an array

IsDate

Returns a value of True or False depending on whether an expression is properly formatted for a data conversion

IsEmpty

Returns a value of True or False depending on whether a variable is initialized

IsNull

Returns a value of True or False depending on whether an expression is set to Null

IsNumeric

Returns a value of True or False depending on whether an expression evaluates to a number

IsObject

Returns a value of True or False depending on whether an expression has a valid reference for an automation object

Join

Returns a string that has been created by concatenating the contents of an array

Lbound

Returns the smallest possible subscript for the specified array dimension

Lcase

Returns a lowercase string

Left

Returns characters from the left side of a string

Len

Returns a number or string's character length

LoadPicture

Returns a picture object

Log

Returns the natural log of the specified argument

LTrim

Trims any leading blank spaces from a string and returns the result

Mid

Returns a number of characters from a string based on the supplied start and length arguments

Minute

Returns a number representing a minute within an hour in the range of 0 to 59

Month

Returns a number representing a month within a year in the range of 1 to 12

MonthName

Returns a string containing the name of the specified month

MsgBox

Returns a value specifying the button that users click on in a dialog box

Now

Returns the current date and time

Oct

Returns a string containing an octal number representation

Replace

Returns a string after replacing occurrences of one substring with another substring

RGB

Returns a number that represents an RGB color

Right

Returns characters from the right side of a string

Rnd

Returns a randomly generated number

Round

Returns a number after rounding it by a specified number of decimal positions

RTrim

Trims any trailing blank spaces from a string and returns the result

ScriptEngine

Returns a string identifying the current scripting language

ScriptEngineBuildVersion

Returns the scripting engine's build number

ScriptEngineMajorVersion

Returns the scripting engine's major version number

ScriptEngineMinorVersion

Returns the scripting engine's minor version number

Second

Returns a number representing a second within a minute in the range of 0 to 59

Sgn

Returns the sign of the specified argument

Sin

Trigonometric function that returns the sine of the argument

Space

Returns a string consisting of a number of blank spaces

Split

Organizes a string into an array

Sqr

Returns a number's square root

StrComp

Returns a value that specifies the results of a string comparison

String

Returns a character string made up of a repeated sequence of characters

Tan

Trigonometric function that returns the tangent of the argument

Time

Returns a variant of subtype Date that has been set equal to the system's current time

Timer

Returns a value representing the number of seconds that have passed since midnight

TimeSerial

Returns a variant of subtype Date that has been set equal to containing the specified hour, minute, and second

TimeValue

Returns a variant of subtype Date that has been set using the specified time

Trims

Returns a string after removing any leading or trailing spaces

TypeName

Returns a string that specified the variant subtype information regarding the specified variable

Ubound

Returns the largest subscript for the specified array dimension

Ucase

Returns an uppercase string

VarType

Returns a string that specified the variant subtype information regarding the specified variable

Weekday

Returns a whole number in the form of 1 to 7, which represents a given day in a week

WeekdayName

Returns a string identifying a particular day in the week

Year

Returns a number specifying the year

As a quick example of the benefit of using a built-in VBScript function to save time and simplify your VBScripts, look at the following custom function, which consists of five VBScript statements.

Function SqrRootSolver() intUserInput = InputBox ("Type a number", "Custom Square Root Function") X = 1 For Counter = 1 To 15 X = X - ((X^2 - intUserInput) / (2 * X)) Next MsgBox "The square root of " & intUserInput & " is " & X End Function

The five statements contained in the function ask the user to type a number and then use a For…Next loop to determine the square root of that number using some fairly sophisticated math. Figures 4.6 and 4.7 demonstrate the operation of this function.

Figure 4.6: Creating a custom function that determines the square root on an input number

Figure 4.7: Displaying the results of the square root calculation

Using VBScript's built-in Sqr() function, you can perform the same task with just two lines of code, as shown below.

UserInput = InputBox ("Type a number", "Square Root Calculator") MsgBox "The square root of " & UserInput & " is " & Sqr(UserInput)

Not only does using the built-in VBScript Sqr() function reduce the number of lines of code, but it also greatly reduces the complexity of the script, thus reducing the amount of time that it takes to develop it.

Summary

In this chapter, you learned how to enhance your VBScripts by organizing them into subroutines and functions. This included developing an understanding of the differences between these two types of procedures and how to leverage the power and convenience provided by VBScript's built-in collection of functions. In addition to making scripts easier to read and maintain, procedures provide a mechanism for limiting variable scope. You also learned how to call VBScript procedures using event handlers in order to develop VBScripts that can react dynamically to both user and browser activity.

Категории