VBScript Functions
Functions are special blocks of VBScript's program code that can be activated (or called) by name. A function can be given data to operate on, and it always returns a value to the part of the script that called it. The technical term for a value passed to a function is an argument.
For example, the built-in UCase function takes a string variable, constant, or expression as its argument and returns a string with all the letters set to uppercase. Now, check out this example:
str1 = "my file.dat" str2 = Ucase(str1)
In this script, the variable str2 calls the UCase function, which converts the value of str1 to all uppercase and then assigns that value, "MY FILE.DAT", into variable str2. The original variable, str1, is left untouched.
We'll cover many examples of functions in the coming chapters. If this doesn't make sense now, the examples will make it clearer as we go.
Calling Functions and Subroutines
In the example I gave earlier, I showed how functions are called by specifying their arguments in parentheses. For example, I might call the MsgBox function this way:
selectedbutton = MsgBox("Do you want to continue?", vbYesNo)
The function MsgBox displays a text message in a pop-up dialog box and returns a value indicating which button the script's user clicked.
In VBScript, if you don't care about and don't intend to use the value returned by a function, you can omit the parentheses. In this case, you're treating the function as a subroutine, which is a fancy name for a function that does something useful but doesn't need to return an answer to the program that called it.
The following example illustrates this idea with the function MsgBox. I might use MsgBox to display a useful message, but I don't care which button the user clicked. Because I am not going to use the value MsgBox returns, I can call it using the subroutine form, without parentheses:
MsgBox "The script has finished", vbOK
In the rest of this chapter, I'll show functions used both ways. Just remember that parentheses are used when you're using the value returned by the function, and they are omitted when you're not.
By the way, in VBScript, parentheses can also be omitted when a function doesn't take any arguments. You may see functions called this way in Microsoft's VBScript documentation. The built-in function Now(), which returns the current date and time, is an example. Both lines in this script do the same thing:
wscript.echo "The date and time are:", Now() wscript.echo "The date and time are:", Now
The second line is actually calling function Now and printing the returned value. I find this confusing: Is Now a variable or a function?
Documentation and Syntax
About 100 predefined functions are available in VBScript, provided for your convenience as a programmer. These functions manipulate strings, perform complex math functions (such as square roots), and calculate dates and times.
All these functions are listed in the summary at the end of this chapter, and they are completely explained in the VBScript documentation at Microsoft's Web site (http://msdn.microsoft.com/Scripting). To give you an introduction to the type of functions and their applications, I'll go through some of them in this chapter. But first, I should explain what you'll see in the online documentation.
The VBScript documentation shows the syntax (that is, the required formatting and wording) for each function and statement in the language. For example, the syntax for the MsgBox function looks like this:
MsgBox(prompt[, buttons][, title][, helpfile, context])
The parentheses tell you that MsgBox is a function. The list inside the parentheses shows that MsgBox can take five arguments. The square brackets ([ and ]) around some of the arguments aren't meant to be taken literally; that is, you don't type them. Instead, they indicate that the arguments are optional. Anything shown inside [ and ] can be omitted.
The documentation's explanation of each argument tells you what the argument signifies, what values are permitted, and what value is assumed if you don't supply one. The assumed-if-missing value is called the default value.
In the case of MsgBox, you can see that prompt is the only required argument. All the other arguments are shown surrounded by left and right brackets, so the rest are optional. The simplest use of MsgBox would look like this:
x = MsgBox("This is a message to display on the screen")
However, you could also use MsgBox with three arguments, like this:
x = MsgBox("This is a message to display", vbOK, "This is the title")
If you want to specify some of the arguments without specifying the ones in between, you can use commas with nothing between them. For example, you could write
x = MsgBox("This is a message to display", , "This is the title")
to specify the prompt and title arguments without specifying buttons. In this case, the MsgBox program would use the default value for buttons.
Finally, notice that the helpfile and context arguments are surrounded by a single set of brackets, which indicates that you can use both or neither.
Don't worry too much about these details right now. This example is just to show how the documentation works.
String-Manipulation Functions
Most of the work you'll probably want to do with VBScript will involve manipulating strings such as filenames and usernames, so it's helpful that VBScript has a rich complement of built-in functions to work with strings.
Searching for Strings with InStr() and InStrRev()
I've found that the most common task I perform when working with strings is to determine whether a string contains some other string. For example, if your script is to scan through the contents of a directory looking for DAT files, it needs a way of finding out whether the string ".DAT" occurs in any given filename.
The InStr function does this job. The expression
InStr(filename, ".DAT")
has the value 0 if .DAT can't be found in the string filename. The value will be equivalent to the character position where .DAT starts, if it does occur. Here's an example:
filename = "TEST.DAT" pos = InStr(filename, ".DAT")
In this case, pos will be set to 5, because .DAT occurs starting at the fifth character in filename. If .DAT didn't occur in filename, pos would be set to 0. Here's how a program might take advantage of this:
if InStr(filename, ".DAT") > 0 then msgbox filename & " is a .DAT file!" end if
Keep in mind that InStr is case sensitive. For example, it would say that ".DAT" can't be found in the string "somefile.dat". So, when filename might contain both upper-and lowercase characters, the correct way to write the test would be as follows:
if InStr(Ucase(filename), ".DAT") > 0 then ...we know it's a .DAT file end if
The UCase function returns a string identical to the string it's passed, except that lowercase characters are turned to uppercase. Then, InStr looks for the uppercase .DAT.
If the first argument to InStr is a numeric value, it's interpreted as the starting character for the search. In this case, you have to pass three arguments to InStr. The following expression returns the value 4:
InStr(2, "ABCABC", "AB")
AB occurs at positions 1 and 4 in the string "ABCABC", but you told InStr to start looking at position 2. Therefore, the first occurrence was skipped.
Function InStrRev() is similar to InStr(), except that it searches starting from the right end of the string. The following line returns 4 because it finds the rightmost "AB":
InStrRev("ABCABC", "AB")
Extracting Parts of Strings with Left(), Right(), and Mid()
VBScript has several functions to pull pieces out of strings based on the starting position and length of the desired piece, as shown here:
Function |
Returns |
Left(string, length) |
The leftmost length characters from string |
Right(string, length) |
The rightmost length characters from string |
Mid(string,start) |
That part of string from character position start onward |
Mid(string,start,length) |
length characters of string from position start |
The following are a few examples:
Expression |
Returns |
Left("ABCDEF", 3) |
"ABC" |
Right("ABCDEF", 3) |
"DEF" |
Mid("ABCDEF", 3) |
"CDEF" |
Mid("ABCDEF", 3, 2) |
"CD" |
In real life, you will use these functions with variables, not fixed strings such as "ABC". For example, to find the base name of a filename without its file type or extension, you could use this VBScript code:
filename = "My file.DAT" dot = InStr(filename, ".") basename = Left(filename, dot-1)
This code sets dot to the position of the period in the filename, and basename to that part of the filename up to, but not including, the period. In this case, basename would be set to My file. (If you find this at all confusing, you might want to work this out with paper and pencil to see that it's true).
But what happens if filename doesn't have a period in its name? We have a problem: dot would be set to zero, and VBScript would stop with an error message when you tried to set basename to the leftmost –1 characters! Good programming practice requires that you handle this situation as follows:
In the better version of this script, we use the entire filename if it doesn't contain a period; otherwise, we extract just the base name. If you're curious, try this yourself with files named "test.file", "test.", and "test".
Other String Operations
The following are some more string manipulation functions you'll find handy:
Function |
Returns |
Len(string) |
The length of string in characters |
Lcase(string) |
The same string but with all alphabetic characters in lowercase |
Ucase(string) |
string, with all alphabetic characters in uppercase |
Trim(string) |
string, with leading and trailing spaces removed |
Ltrim(string) |
string, with leading spaces removed |
Rtrim(string) |
string, with trailing spaces removed |
Here are a few examples:
Expression |
Returns |
Len("ABC") |
3 |
Lcase("My Documents") |
"my documents" |
Ucase("My Documents") |
"MY DOCUMENTS" |
Trim(" ABC ") |
"ABC" |
Ltrim(" ABC ") |
"ABC " |
Rtrim(" ABC ") |
" ABC" |
Date and Time Functions
As you would expect, because computers frequently refer to the date and time, VBScript has a number of built-in functions to make it easy to work with dates and times.
Reading the Clock with Date(), Time(), and Now()
The Date() and Time() functions return the current calendar date and local clock time, respectively, as determined by the operating system. For example, to display the current date and time in a message box, you can use the following code:
' example file script0209.vbs MsgBox "The current date is " & Date() & " and the time is " & Time()
The Now() function returns the current time and date combined.
Dates and times are actually stored as numbers. The date is stored as an integer number of days since January 1, 0099, and times are stored as decimal fractions of a day (1 second equals 0.0000115741). You don't need to worry about how this is done, but it's helpful to know because you can manipulate dates using the arithmetic + operator. For example, the following line assigns today's date plus one day to the variable tomorrow:
tomorrow = date()+1
It's better, though, to use special built-in date and time calculation functions provided in VBScript, which I'll discuss next.
Computing a Future Date with DateAdd
Using the DateAdd function, you can add a specified interval to a given date, time, or combined date/time. The syntax of the function is as follows:
DateAdd(interval, number, date)
You use the date argument to set the initial date. The interval argument is the interval type, such as month, day, or year, and the number argument is the number of intervals to add. Table 2.5 shows a list of interval types. They must be passed to the DateAdd function as a string in quotation marks.
Table 2.5. Interval Types for the DateAdd() Function
Interval |
Description |
YYYY |
Years |
Q |
Quarters |
M |
Months |
W |
Weeks |
D |
Days |
H |
Hours |
N |
Minutes |
S |
Seconds |
The following are some examples:
Expression |
Returns |
DateAdd("M", 2, Date()) |
Today's date plus two months |
DateAdd("H", -1, Time()) |
The current time minus one hour |
The DateDiff() Function
The DateDiff() function calculates the interval between two dates. The syntax is as follows:
DateDif(interval, date1, date2)
The interval argument describes the format of the result you want returned. Refer to Table 2.5 for these values.
For example, DateDiff("D", "9/9/1999", "1/2/2001") returns the number of days between September 9, 1999 and January 2, 2001.
This function is especially useful in scripts involving the age of files. For example, you might want to delete a given file if it's older than three hours. If variable timestamp holds the last-modified date and time of a file, the following test determines whether the file should be deleted:
if DateDiff("H", timestamp, time()) > 3 then
Other Date Functions
The following are a few more date and time functions you should be aware of:
Function |
Returns |
Day(date) |
The day of the month of the given date, from 1 to 31 |
Weekday(date) |
The day of the week of the given date as a number from 1 to 7, where 1 equals Sunday, 2 equals Monday, and so on |
Month(date) |
The month of the given date, where 1 equals January and so on |
WeekdayName(date) |
The day of the week of date as a string |
MonthName(date) |
The name of the month in which date falls |
Hour(time) |
The hour (0 to 23) of the given time |
Minute(time) |
The minute (0 to 59) of the given time |
Second(time) |
The second (0 to 59) of the given time |
VBScript has the predefined constants vbSunday, vbMonday, and so on that you can use to test the values returned by Weekday in If statements and others. vbMonday makes more sense than the number 2 to someone unfamiliar with this function.
The following are some examples of what VBScript returns when the expression is run at 3:10:37 P.M. on Tuesday, January 11, 2000:
Expression |
Returns |
Day(now()) |
11 |
Weekday(now()) |
3 (for Tuesday) |
Month(now()) |
1 (for January) |
WeekdayName(Weekday(now())) |
"Tuesday" |
MonthName(Month(now())) |
"January" |
Hour(now()) |
15 |
Minute(now()) |
10 |
Second(now()) |
37 |