DAY 15

Extending Your Web Pages with Strings


CONTENTS


You've seen a lot of the capabilities of VBScript in the lessons you've covered so far. The VBScript syntax provides you with the elements needed to piece together programs. You can use it to put together program logic with variables, operators, control structures, and procedures. You can greatly extend the power of the language by incorporating components into your programs, but the language of VBScript itself is quite powerful. A lot of advanced functions are part of the VBScript language.

These functions are built into VBScript, just as keywords such as If-Then, Sub, MsgBox, and Dim are. You can't see the source code for these functions because they are an inherent part of VBScript. No special declarations are needed to make use of these. They stand ready to be used from anywhere within your script. This potpourri of functions includes date-handling procedures, string-handling procedures, mathematical procedures, and more. Today's lesson focuses on the string-handling functions. The date and math functions are addressed on Day 16, "Extending Your Web Pages with Dates and Advanced Math."

String functions, in particular, are likely to be frequently used in Web page programming. Any page that collects data from the user to send to a server can use these functions to validate dates and string formats before sending the information on. This allows you to provide quicker, more responsive user feedback and minimize network traffic. If the situation warrants, the string functions, which are the topic of today's lesson, are easy to apply.

Note
One sample Web page, containing a collection of scripts, demonstrates all the string functions in today's lesson. This page, String.htm, is available on the CD-ROM. The sample scripts referred to throughout this lesson can be found there.

Whenever you're preparing information for or receiving information from the user in your script, there is a good chance that you're dealing with a string of characters. VBScript provides many functions that make work easier. Knowing about these functions can save you a lot of time; not knowing about them can cost you a lot of time.

A vivid example of the value of knowing what the language provides in areas such as string handling occurred recently in a classroom situation. A student proudly called the teacher over and showed off a rather lengthy Visual Basic function he had written. The 30+ lines of code in his function, he explained, made use of ASCII character codes and the offsets between lowercase and uppercase letters. The end result was that the function could convert any lowercase string into the equivalent uppercase letter string. The student went on to hint that, if some extra credit could result, he might even be willing to share the algorithm with other students. As gently as possible, the instructor told the student that he had just invented a function that was already provided by Visual Basic! His several hours of work was wasted effort. All he had to do was use a standard part of the language to make use of the same uppercase conversion in his code.

Knowing the range of string functions' capabilities will save you from the same fate. Good data validation is central to Web pages of the future, and it depends on effectively evaluating strings. Therefore, strong string-handling skills are a must if you plan to be an effective VBScript developer. Fortunately, the string functions, like the date functions, are relatively easy to apply after you understand the capabilities they offer.

Asc and Chr

A string is made of a series of characters. Each individual character is represented internally in the computer by a unique numeric code called an ASCII code. A different ASCII code exists for every character in the alphabet, for uppercase and lowercase versions of the same letter, for every number, and for most of the symbols on your keyboard. Usually when you write programs, you aren't too concerned with these codes. There may be times, however, when you need to be. For example, maybe you have to provide a Web page that aids your users in typing ASCII codes into an electronic sign board. They need a way to take a character like A and get the equivalent numeric code, so they can type in that code. The Asc function provides this capability. Listing 15.1 shows code that uses the Asc function to display the ASCII code for A.


Listing 15.1. Asc and Chr functions.
<!-------- Asc and Chr ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="Asc/Chr"  NAME="cmdAsc">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdAsc" EVENT="onClick">
<!--
    msgbox "The character ""A"" ASCII code is " & Asc("A") & "." & chr(13) & _
         "The character for ASCII code 66 is " & chr(66) & ".",0,"Using Asc/Chr"
-->
</SCRIPT>

Situations also arise where the conversion must be done in the other direction. For example, perhaps you're inspecting the memory contents of a computer with some advanced debugging tool. In an area that you know is supposed to contain a string variable, you see that the first byte contains a 66. You need to know what character that represents so you can tell if the correct string is in memory. The Chr function can give you the answer. Chr takes the numeric value that you provide it and returns the corresponding character (refer to Listing 15.1). The ASCII code for the character A is displayed with the Asc function, and the character represented by the ASCII code 66 is displayed with the Chr function. The results are shown in Figure 15.1. The results show that the ASCII code for A is 65. Not surprisingly, then, the character represented by ASCII code 66 turns out to be a B.

Figure 15.1 : Using the Asc and Chr functions.

One of the more common uses of the Chr function is to generate special characters that are not available on the keyboard. The character represented by the ASCII code 13, for example, is not one you can see. This character is called the carriage-return character. You can use this character in many places to force a line separation (for example, in the MsgBox function). If you include the ASCII character code 13 in the MsgBox text, more than one line will be displayed. The only problem is, how do you enter this character on your statement when you type in your program?

If you've been looking carefully at the examples, you've seen the answer many times already. You just supply the character with Chr(13):

msgbox "This will be line1" & chr(13) & " and this will be line 2",0,"Title"

On Day 4, "Creating Variables in VBScript," you learned how you can declare a variable to serve the purpose of an intrinsic constant for commonly used values. The constant.txt file in the tools directory on the CD-ROM contains statements you can copy and paste to put these variables in your code. Then you'll have an easy-to-read variable to serve the same purpose because it is equated to Chr(13). That constant is vbCr and can be used as follows:

msgbox "This will be line1" & vbCr & " and this will be line 2",0,"Title"

You can also use the combined carriage-return and line-feed characters (Chr(13) & Chr(10)) to carry out line separations. The end result is the same. In either case, you are generating the special character from the ASCII code rather than from your keyboard. Asc and Chr give you the full flexibility to work at the ASCII code or character level, even if you can't see those characters.

Note
Functions similar to Asc and Chr work at the byte rather than the character level. AscB returns the first byte of a string. ChrB returns the byte that corresponds to an ASCII code rather than the character. For practical purposes, you are likely to work simply in characters. However, if you were making use of extended character sets, particularly foreign language string support where more than one byte might be used to represent a character, these functions may be necessary.

Miscellaneous Functions: Ucase, Lcase, LTrim, RTrim, Trim, Left, and Right

Note
You may have noticed that the functions used in the samples start with a capital followed by lowercase letters. This is a good naming convention. VBScript itself, however, does not care about case. You can supply functions and keywords in capitals or lowercase letters. But for your own sake, try to use a consistent approach!

Seven functions in one little section may seem overwhelming, but like most of the string functions, they are easy to understand and apply, and these functions are all somewhat related. They all return a modified string based on an original string, and they are all frequently used in Web page data validation to verify correctly entered data before data is submitted back to the server. The case functions modify the case to upper- or lowercase. The trim functions trim off extra spaces, and the Left or Right functions return just the left or right portions of the original string. The best way to tackle them is to consider them one at a time.

Ucase and Lcase are a good place to start. These functions are commonly used in validation. Suppose, for example, that you have a page that requires the user to supply his department name. If the user is from the Engineering Department, you want to display a special message during validation to let him know that he has additional paperwork to fill out. Then you could put a check like this in your code:

if txtDepartment.Value = "Engineering" then ' provide special message

This may work fine for Fred, Ned, Ted, Jed, Holly, and Molly. But then Ed may come along and enter engineering, and Dolly may enter ENGINEERING. You could put the burden on the user and have your program fail to recognize Ed and Dolly as valid engineering users. However, placing perfect data entry expectations on the user is generally regarded as poor programming style. It would be especially so if Ed or Dolly happened to be your boss, and the Web page didn't give them the expected feedback. Don't saddle your users with a less than optimal solution when a very simple way to fix this problem is available. Convert the string you're examining to all uppercase letters, and compare it to a string with all uppercase letters:

if Ucase(txtDepartment.Value) = "ENGINEERING" then ' provide special message

Now it doesn't matter how the user enters Engineering. Your program will work correctly no matter how Ned, Ed, or Dolly enters his or her department name.

Ucase takes whatever string it is supplied and returns all uppercase characters. Of course, uppercase only works for letters, so digits and symbols are unaffected when passed to this function. Lcase works exactly the same, except it converts everything passed to it to lowercase. For example, the statement

msgbox lcase("Timmy Kenny JJ")

would result in the display of the message timmy kenny jj.

Another problem could still creep into your department check, and you could thank nonconformist users once again. Suppose Dolly unwittingly entered Engineering with a trailing blank, and Ed in a wild-fingered frenzy entered Engineering with a leading blank. Would this input result in a True condition when the following statement is carried out?

if Ucase(txtDepartment.Value) = "ENGINEERING" then ' provide special message

Of course not! This conditional expression does an exact match on the word ENGINEERING, and the presence of the extra blanks causes the conditional to fail. Your bosses might not expect you to accept this input, but likely they'd be happy if you could. You can accept this input with virtually no added effort. The Trim function removes all extra blank spaces that precede or follow characters within the string. So this statement:

msgbox Trim(" Lisa Kayla Ryan ")

would display a message box that said Lisa Kayla Ryan with no blanks in front of or behind it.

Trim has two closely related cousins, LTrim and RTrim. Although Trim does the work of both cousins, LTrim simply removes blanks from the left of a string, and RTrim just removes blanks at the end or right of a string. The statement

msgbox LTrim("   Lisa Kayla Ryan  ")

would display a message box that said Lisa Kayla Ryan   . The statement

msgbox RTrim("   Lisa Kayla Ryan  )

would display a message box that said Lisa Kayla Ryan. To fix your Web page department validation to make it leading- and trailing-blank proof, you'd supply this statement:

if Trim(Ucase(txtDepartment.Value)) = "ENGINEERING" then ' provide special message

Now you have a check that can withstand an entry like EnGinEeRinG . However, never underestimate the ability of a Web page user to provide unexpected input. Dolly and Ed still provide one more twist. Suppose their organization refers to the Engineering Department on some documents as "Department of Engineering" and on other documents as "Engineering Dept." Most users simplify their department as "Engineering." But not Dolly and Ed. Dolly supplies Department of Engineering in the input area, and Ed enters Engineering Dept. Of course, users in the Engineering Department should know better. They are really trying to test your program, and you're ready for them. You simply apply two more functions in the VBScript bag of string tricks-Left and Right.

Left allows you to extract the leftmost characters from a string. You can extract as many as you specify. Right allows you to extract rightmost characters from a string, again as many as you specify. For example, this statement:

msgbox Left("Ginny Emma Ben",10)

would display a message box that said Ginny Emma. This statement:

msgbox Right("Ginny Emma Ben",8)

would display a message box that said Emma Ben.

Because you know that engineering has 11 letters in it, you can check both the first and the last 11 characters. If the first or last 11 characters contain "ENGINEERING," it can be considered a match. The check that accomplishes this is shown in Listing 15.2.


Listing 15.2. Full validation on a department check.
if (Left(Trim(Ucase(txtDepartment.Value)),11) = "ENGINEERING") or _
   (Right(Trim(Ucase(txtDepartment.Value)),11) = "ENGINEERING")  _
          then ' provide special message

A couple aspects of this check may make it even more robust than it first appears. If you ask Left or Right for more characters than are present in a string, the return value will simply be the number of characters that exist in the string. You're safe even if your user enters a string shorter than 11 characters. Your program will correctly detect that no match occurred, rather than blowing up with an error.

The order in which these functions are applied is also important. This statement:

msgbox Left(Trim("      Chester"),3)

displays the message Che, while this similar-looking statement:

msgbox Trim(Left("      Chester",3))

displays an empty string.

Expressions are evaluated from the inner parentheses to the outer. In the department validation, evaluation occurs in the correct order. First, the user's input value is converted to uppercase. Then extra blanks are trimmed. Only then are the left or right characters extracted. With this approach, the validation will accept just about anything Dolly and Ed might throw at you. This even includes EngINEEring dePT and Department of Cool EnginEERING .

You can see the flexibility of these string functions. Listing 15.3 shows some sample code that further demonstrates the use of each of these functions. Figure 15.2 shows the results from running this test.

Figure 15.2 : Using Lcase, Ucase, LTrim, RTrim, Trim, Left, and Right.


Listing 15.3. A demonstration of miscellaneous functions.
<!-------- Misc: Lcase, Ucase, LTrim, RTrim, Trim, Left, Right -------------->
<INPUT TYPE=BUTTON VALUE="Misc Str"  NAME="cmdCase">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdCase" EVENT="onClick">
<!--
    dim strFeedback
    dim CLUBNAME

    CLUBNAME = "Mutt"

    strFeedback = "Lcase/Ucase: " & CLUBNAME & " should appear as " & _
         lcase(CLUBNAME) & " when used to refer to a pooch, and as " & _
         ucase(CLUBNAME) & " when used as the acronym for the " & _
         "Michigan Ultra Trail Team." & vbCrLf & vbCrLf

    strFeedback = strFeedback & "LTrim applied to ""    mutt    "" is: ***" & _
         ltrim("    mutt    ") & "***" & vbCrLf
    strFeedback = strFeedback & "RTrim applied to ""    mutt    "" is: ***" & _
         rtrim("    mutt    ") & "***" & vbCrLf
    strFeedback = strFeedback & "Trim applied to ""    mutt    "" is: ***" & _
         trim("    mutt    ") & "***" & vbCrLf & vbCrLF

    strFeedback = strFeedback & "Left two characters of Mutt: " & _
         Left(CLUBNAME,2) & vbCrLf
    strFeedback = strFeedback & "Right two characters of Mutt: " & _
         Right(CLUBNAME,2) & vbCrLf
    msgbox strFeedback,0,"Using case, trim, left/right"
-->
</SCRIPT>.

The validation approaches offered by these string functions are powerful. They let your code stand up to some of Dolly and Ed's best stuff, but Dolly and Ed can still foil these checks. All it takes is an entry like Cool Engineering Department to cause the check to fail. Don't despair, though. There are some more string functions in the bag of tricks, and one in particular lets you address even this challenge.

InStr

The InStr function checks for the presence of one string within another. If the desired string is present in the search string, the InStr function returns the position of that string. If the string can't be found, a 0 will be returned. For example, this statement:

msgbox InStr("Brad Mike Karen John Claire", "Mike")

will display 6. This result indicates that the desired string of Mike was found at the sixth character of the search string in the first argument.

This function is the perfect one to apply to the Engineering Department check. Because the function searches for the desired string anywhere in the search string, there is no need to trim the user input or extract just the left or right side of the user input. The check with InStr is therefore even more straightforward than its predecessor:

if Instr(Ucase(txtDepartment.Value), "ENGINEERING") > 0 _
    then ' provide special message

This one check will now correctly detect if engineering is supplied in any part of the input string. It will match for my Engineering dept , EnGINEERING department, or any other similar variation. Now you see how you can use string functions to make your Web page scripts sturdy enough to validate the input of even the Dollys and Eds of the world.

A couple more aspects of InStr are important to note. InStr normally starts searching for the desired text at the start of the search string, but it doesn't have to. You can direct it to start the search at any character. To do this, provide the search start character as the first argument to the function. For example, assume you want to see if the word Task appears anywhere other than in the first five characters, so you indicate that the search should begin at the sixth character. Then this search:

msgbox InStr(6, Ucase("Task List: re-org meeting; year-end report task"),"TASK")

would display 44. Notice that the search string had to be converted to uppercase with the Ucase function. Otherwise, the desired string TASK would not have matched task at the 44th position because the search is case sensitive. A way to carry out a non-case-sensitive search is to simply supply an additional parameter as the fourth parameter to InStr. By default, when this parameter is not presented, it is treated as if it has a 0 value, which means case-sensitive or only exact matches occur. If you supply a 1 for this parameter, matches will not be case sensitive. In other words, tAsK would show up as a match against TAsk. Then the search for task can be rewritten as

msgbox InStr(6, Ucase("Task List: re-org meeting; year-end report_
task","TASK",1)

and it will still display the result 44.

Listing 15.4 shows another example of how case sensitivity can make a difference in a search. In the first conditional check, the word pear is not located in the string of food names. In the second conditional check, it is located. These results are shown in Figure 15.3. The only difference in the two checks is that the second check uses the option that's not case sensitive and the start character option. Whenever a value is supplied for the case option, the start character must be supplied as well.

Figure 15.3 : An InStr search with and without case sensitivity.


Listing 15.4. An InStr search with and without case sensitivity.
<!-------- InStr ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="InStr"  NAME="cmdInStr">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdInStr" EVENT="onClick">
<!--

   Dim strFoods, strFeedback

   strFoods = "banana orange apple pear"

   ' Check for exact case
   if InStr(strFoods,"PEAR") > 0 then
       strFeedback = "PEAR is in " & strFoods & vbCrLf
   else
       strFeedback = "PEAR is not in " & strFoods & vbCrLf
   end if

   ' Check regardless of case
   if InStr(1, strFoods,"PEAR", 1) > 0 then
       strFeedback = strFeedback & "PEAR is in " & _
       strFoods & " without case-sensitivity" & vbCrLf
   else
       strFeedback = strFeedback & "PEAR is not in " & _
       strFoods & " without case-sensitivity" & vbCrLf
   end if

   msgbox strFeedback,0, "Using Instr"

-->
</SCRIPT>

If you carry out much string processing in your scripts, InStr will likely become a cornerstone of your string-handling strategy. When InStr is coupled with the capabilities of Len and Mid, which will be addressed next, you can extract strings as well as just locate them.

Note
You saw earlier that Asc and Chr have corresponding byte-oriented versions, AscB and ChrB. The same is true with InStr. An InStrB version of this function matches bytes rather than characters. This is useful for matching extended character sets typical of some foreign languages.

Len and Mid

The Len and Mid functions are two of the more frequently used string-handling procedures. Len returns the length of a string. For example, the following would display 26:

msgbox Len("abcdefghijklmnopqrstuvwxyz")

Blanks are included in the count, so the following would display 28:

msgbox Len("I ran with determination up Blood Hill")

The Len function is especially handy for validating input when you require some minimum number of characters. Perhaps you have a Web page that prompts for a student identification, for example. Assume that a student ID must be at least nine characters long. You could perform a validation check, such as

if len(txtID.value) < 9 then ' corrective action or message

The Len function is also one way to see if a variable has been assigned. Consider the code in Listing 15.5.


Listing 15.5. Checking Len on an unassigned string.
sub TestIt
    dim VarAge
    msgbox len(VarAge)
end sub

This routine would result in a display of 0. Because the variable VarAge hasn't been assigned when the length is checked, it has no current length, and a length of 0 is returned.

Len is one function that is helpful in validation and is closely focused on the number of characters in a string. Mid, a similar function, allows you to retrieve a string or substring from another original string. The name Mid can be deceiving if you aren't used to BASIC. It sounds as if it implies that you can only take these substrings from the middle of the original string. However, you can take any portion of the original string, whether at the start, end, or anywhere in between.

The best way to appreciate Mid is to examine some examples. Consider the following:

msgbox Mid("Joe Jacko BigAl", 5, 5)

This statement will display Jacko in the message box. The first argument to this function is the source string that will be used to copy the substring from. The second argument is the character position where the substring copy is to start. The VBScript Mid function calls the first character in its sequence character 1. So it considers the first character of the string, J, to be at position 1, the second character o to be at position 2, the third character e to be at position 3, and so on. Therefore, position 5 indicates the fifth character over, which is J. Finally, the last argument specifies how many characters will be copied. In the preceding sample line, five characters are to be copied from the start of the substring. Five characters from and including the J at the fifth position encompass all of Jacko, so this is what shows up in the message box display.

Mid is often used in conjunction with InStr. InStr can locate where a key phrase or delimiter starts in a string, and then Mid can extract it. For example, if you had a field on your page that asked the user for a city and a state, the code in Listing 15.6 would parse out just the state value, assuming that the user entered a comma between the city and the state.


Listing 15.6. Using InStr and Mid together.
<!-------- Len/Mid  ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="Len/Mid"  NAME="cmdMid">
<INPUT NAME="txtLocation" VALUE="Sparta, MI" SIZE=12>
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdMid" EVENT="onClick">
<!--

    Dim intPosition, intSize, strState
    ' Find the comma
    intPosition = InStr(txtLocation.Value,",")
 
    ' The purpose of this code is to transfer the state portion of the
    '   user-supplied location to a variable for later use in the program.
    if intPosition = 0 then
        msgbox "The location is not in the expected city, state format."
    Else
       ' Determine how long the state portion is based on where the
       '    city/state comma is and the overall length of the string
        intSize = len(txtLocation.Value) - intPosition

       ' Assign the state string to the variable
        strState = mid(txtLocation.Value, intPosition+1, intSize)

       ' Remove any leading or trailing spaces
       strState = Trim(strState)


   end if

  
   MsgBox """" & strState & """ extracted after comma in position " &_
 intPosition & " from source string """ & txtLocation.Value & """", 0,_
"State Parsing Using InStr/Len/Mid"

-->
</SCRIPT>

The results from running this test are shown in Figure 15.4. When the user supplies a city and state, such as the default Sparta, Mi, the script will parse just the state portion and display it. This code is not likely to be the life of the party at your next computer science social. As far as algorithms go, it is quite straightforward, and that's exactly the beauty of it. You can easily implement sophisticated parsing and validation on any input on your Web pages. You don't have to build up your own library of procedures to support your string handling. They're already there, ready to use.

Figure 15.4 : The results of parsing the state from a user input field using InStr, Len, and Mid.

Mid and Len, coupled with InStr, let you get at any portion of a string. You can carry out sophisticated string extractions and parsing with these functions. There's no need to turn to another language on a Web page server to handle your advanced input parsing and validation. If you can picture what needs to be done with the string input on your pages, VBScript provides the function toolkit to accomplish it.

Note
The Len and Mid functions are also available as byte-oriented calls, when LenB and MidB are used.

Space and String

The Space and String functions are some of the simpler members of the string handling family, but they do come in handy on occasion. Suppose you are generating a message that you want to have preceded by 20 spaces. You could simply put them within double quotes:

msgbox "                    Visual Basic Rules!"

This is a bit cumbersome, however. An easier approach is to use the Space function to request a string consisting of the specified number of spaces:

msgbox Space(20) & "Visual Basic Rules!"

Space is somewhat like a specialized version of String. String also gives you repeated occurrences of a character, but you can request any character you want, whether it is a blank, an asterisk, or anything else. For example, the following displays a string with 20 leading blanks:

msgbox String(20, " ") & "Visual Basic Rules!"
but this:
msgbox String(20, "*")& "Visual Basic Rules!"
displays the string as
"********************Visual Basic Rules!"

Listing 15.7 shows sample code that generates two messages-one preceded by spaces and the other preceded by dashes. The spaces are generated with the Space function, and the dashes are generated by the String function. The results from this code can be seen in Figure 15.5. Note that although both lines are indented, they do not line up evenly since a non-proportional font was used. In other words, 20 spaces do not take up the same amount of screen space as 20 dashes.

Figure 15.5 : Messages based on the Space and String functions.


Listing 15.7. Using Space and String to indent messages.
<!-------- Space/String ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="String"  NAME="cmdString">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdString" EVENT="onClick">
<!--

   Dim strFeedback

   strFeedback = space(20) & "This line was indented with Space(20) " & vbCrLf
   strFeedback = strFeedback & string(20,"-") & _
       "This line was indented with String(20,""-"") " & vbCrLf

   msgbox strFeedback,0, "Using Space/String"

-->
</SCRIPT>

The Space and String functions are useful in many ways for string formatting. They let you easily generate strings that you want to display as part of your feedback, and they also let you easily carry out initializations. If you had a string that you needed to initially create to contain 1KB of 0 characters, for example, you could easily do it with a statement like this:

strVarA = String(1024,"0")

You can also supply an ASCII character code for the character that is to be assigned to the string. If you wanted to fill a string with carriage-return characters, you could use a statement like this:

strVarA = String(1024,13)

These functions are easy to apply. They can also be quite a convenience, considering that the alternative would be writing a code loop to carry out such an assignment.

Even More String Functions: IsEmpty, Cstr, Val, Hex, Oct, and StrComp

Many important string functions have been covered so far, but there are even more that you can put to work. These are summarized briefly here, either because they have already been introduced earlier in the text or because they are not likely to be used as frequently as some of the other string functions examined in today's lesson.

IsEmpty

You saw an earlier example of how you can check to see if data is in valid date format, with the IsDate function, before working with it. Likewise, you can use the IsEmpty function to determine whether a string is empty or uninitialized. As mentioned earlier, this gives you largely the same information as using the Len function to see if a string has a length of 0.

CStr

No separate IsString function exists, however. Why isn't there an IsString function? Everything can be converted to a string representation, regardless of its original data subtype. The function that converts values to strings is CStr, as discussed on Day 4. With CStr, you can take a number and assign the corresponding string to a variable with statements like this:

strVarA = CStr(3019.53)

This fills the variable strVarA with the string 3019.53. CStr automatically handles some advanced localization issues you could run into if you are marketing your software in other countries. Some countries separate decimal numbers with commas rather than the period used in the United States. CStr will automatically take this into account when producing a string for a number.

You now know how to convert a number to its string format. You may also have occasions when you need to go in the other direction-convert a string to its numeric data subtype representation. Several functions were covered on Day 4 that carry out these conversions. They include CDbl, Cint, CLng, and CSng. An example of a Cint assignment is

intVarA = Cint(strVarB)

Such statements take a valid string representation of a number, such as 155, and provide the corresponding numeric data representation.

Val

If a variant variable is used to store the result, it internally records the fact that its data is of a numeric subtype rather than a string subtype after such a conversion. As you saw earlier, this is important for certain types of calculations.

But these functions do not work as well when a number must be converted from a string that is not in perfect numeric format. Assume that the number that must be converted is stored as the string 155 pints. Cint and the other similar functions would not convert this successfully. The related function Val can come to your assistance here, but Val is not supported in the current beta version of VBScript! However, it is supported in Visual Basic, and some documentation seems to indicate that it might be a part of the final VBScript.

Val converts just the numeric portion of a string to its corresponding numeric representation. Val always returns a data subtype of a double number (a decimal point number that can contain very large or very small values). If you don't want the data in double format, you can easily convert it to the appropriate numeric type using the result of Val. Consider the following example. Assume that strVarB contains 155 pints of fine ale. You want to store this number of pints in an integer. An integer, of course, can't deal with additional verbiage such as "pints of fine ale." The Val function can filter these out for you. This statement would carry out your assignment:

intVarA = Cint(Val(strVarB))

Val can handle numbers in Hex and Octal format as well. Hex numbers start with a &H indicator, and octal numbers start with an &O indicator. Val only converts up to the first nonblank character it finds. Val will return a 0 if there are no numeric portions in the string that it can convert. Therefore, this statement:

msgbox Val("Pints - 155")

will display 0.

As you can see, Val can do a lot for you. It could also confuse you, or worse yet, allow confusion to creep into your programs, if you did not realize how its conversion rules work. But for certain situations, it can't be beat. When you know you will have string input that starts with numeric characters and is followed by non-numerics, Val provides a quick, easy-to-use conversion path to your code. As mentioned earlier, at the time of printing Val is not functional in VBScript. Check later versions or documentation for updates on future status.

Hex and Oct

Two other interesting string functions are Hex and Oct. They convert a decimal number to the string representation of its octal or hexadecimal number system equivalent. If you design calculators, these can come in handy; otherwise, you may not have frequent use for them. But every now and then computer problems require working at the hex or octal level for low-level debugging, and then these functions can be a tremendous aid.

Listing 15.8 shows additional examples of each of the functions just discussed, and Figure 15.6 shows the results of these tests. The best way to understand these functions is to study plenty of examples and experiment with them yourself. If you are familiar with these functions, you will find many situations where this knowledge saves you time in the future.

Figure 15.6 : The results of the IsEmpty, Cstr, Hex, and Oct tests.


Listing 15.8. The examples of IsEmpty, CStr, Hex, and Oct.
<!-------- IsEmpty, Str, Cstr, Val  ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="Str/Val"  NAME="cmdVal">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdVal" EVENT="onClick">
<!--

   Dim strFeedback, strValue, intValue
  
   ' Check to see the initial status of variable
   if IsEmpty(intValue) then
       strFeedback = "intValue has not been assigned yet." & vbCrLf
   else
       strFeedback = "intValue contains : " & intValue & vbCrLf
   end if   

   ' Assign a value to the variable
   intValue = 255

   ' Now check again to see the status of variable
   if IsEmpty(intValue) then
       strFeedback = strFeedback & "intValue still has not been " & _
       assigned yet."  & vbCrLf & vbCrLf
   else
       strFeedback = strFeedback & "intValue now contains : " &_
intValue & vbCrLf & vbCrLf
   end if   

   ' Show the value from intValue using string conversion functions
   strValue = Cstr(intValue)
   strFeedback = strFeedback & "CStr of intValue is:""" & strValue &_
       """ Size=" & len(strValue) & vbCrLf

   ' Show the value in hex and octal
   strValue = Hex(intValue)
   strFeedback = strFeedback & "Hex of intValue is """ & strValue & _
       """" & vbCrLf
   strValue = Oct(intValue)
   strFeedback = strFeedback & "Oct of intValue is """ & strValue & """"
  
   MsgBox strFeedback, 0, "Using IsEmpty, Cstr, Hex, Oct"
 


-->
</SCRIPT>

Keep in mind when considering the conversion functions like CStr that in many cases you don't have to explicitly convert your data. If you are supplying data to be printed out in a message box, for example, the appropriate string representation of a variable will be used automatically. However, when the time comes that you do care about explicitly converting the data subtype of a variant variable, as discussed on Day 4, conversion functions like CStr can be invaluable aids.

StrComp

The last string function to consider is StrComp. You have seen some examples in today's lesson of string comparisons. They have been carried out directly with the = comparison operator. For example, the following compares one string to another to see if they are exactly alike:

if txtDept = "Engineering" then

But what if you wanted to see which string came first in alphabetical order? A function called StrComp lets you easily accomplish this and more. If you provide two strings as arguments to StrComp, the function will provide back the values shown in Table 15.1.

Table 15.1. The StrComp return values.
ValueCondition Represented
-1 string1 < string2
0string1 = string2
1string1 > string2
Null string1 or string2 is Null

An example of StrComp in shown in Listing 15.9. The corresponding results are shown in Figure 15.7. This code carries out two simple comparisons. In the first comparison, the first string argument precedes the second in alphabetical order. As you can see by the results, StrComp returns the value -1 on the comparison. In the second comparison, the second string precedes the first alphabetically. In this case, as the results show, StrComp returns the value 1.

Figure 15.7 : The results from the StrComp example.


Listing 15.9. The StrComp example.
<!-------- StrComp  ---------------------------------------->
<INPUT TYPE=BUTTON VALUE="StrComp"  NAME="cmdStrComp">
<SCRIPT LANGUAGE="VBSCRIPT" FOR="cmdStrComp" EVENT="onClick">
<!--

   Dim strFeedback, intCompare, strValue1, strValue2

   ' Assign starting values
   strValue1 = "apple"
   strValue2 = "zebra"

   ' Compare the two strings
   intCompare = StrComp(strValue1, strValue2)

   ' Evaluate results of comparison
   if intCompare = -1 then
       strFeedback = "StrComp determined that " & strValue1 & " precedes " & _
           strValue2
   elseif intCompare = 0 then
       strFeedback = "StrComp determined that " & strValue1 & _
      " is the same as " & _
           strValue2
   elseif intCompare = 1 then
       strFeedback = "StrComp determined that " & strValue1 & " follows " & _
           strValue2
   elseif IsNull (intCompare) then
       strFeedback = "One of the arguments was null"
   end if

   strFeedback = strFeedback & vbCrLf


   ' Try another test
   strValue1 = "apple"
   strValue2 = "aardvark"

   ' Compare the two strings
   intCompare = StrComp(strValue1, strValue2)

   ' Evaluate results of comparison
   if intCompare = -1 then
       strFeedback = strFeedback & "StrComp determined that " & strValue1 & _
           " precedes " & strValue2
   elseif intCompare = 0 then
       strFeedback = strFeedback & "StrComp determined that " & strValue1 & _
           " is the same as " & strValue2
   elseif intCompare = 1 then
       strFeedback = strFeedback & "StrComp determined that " & strValue1 & _
           " follows " & strValue2
   elseif IsNull (intCompare) then
       strFeedback = strFeedback & "One of the arguments was null"
   end if

   MsgBox strFeedback, 0, "Using IsEmpty, Str, CStr, Val"

-->
</SCRIPT>

Through code such as this example, you can use StrComp to carry out detailed comparisons of ordering and equivalence. But StrComp provides still another helpful capability. Earlier in this lesson you used Ucase to make a string uppercase before comparing it to an uppercase match string with =. If StrComp is used for the comparison, you can simply provide a third parameter to it to tell it to do a comparison that is not case sensitive. If this third parameter is other than 0, a comparison that is not case sensitive is used. If the parameter is 0 or is not present at all, then a case-sensitive comparison takes place. For example,

if StrComp("test","TEST") = 0 then

would not evaluate to True because the case of the strings is different. However,

if StrComp("test","TEST",1) = 0 then

would evaluate to True because case is not considered in that comparison.

StrComp provides you with powerful string evaluation capability. If your string processing needs are simple, you will likely find that a simple = comparison between two strings can serve your purpose. However, if you are doing advanced comparisons, such as alphabetical comparisons or comparisons in which you don't care about case matching, StrComp can save you a lot of coding.

Summary

When you construct a Web page and use script capabilities to make it active, you almost always need to deal with strings in one way or another. If the user supplies input through a text control, you receive it as a string. If you need to provide feedback through a message or label, you supply back a string. One of the most powerful capabilities of Web page programming is the potential to validate user input and provide meaningful feedback through a script without sending data back to the server. This requires the parsing and validating of strings. Working with strings is central to working with VBScript in many cases.

Today's lesson shows you the functions that VBScript provides for dealing with strings. Asc and Chr are used to deal with a character's ASCII code representation. Ucase and Lcase convert strings to uppercase and lowercase, respectively. LTrim, RTrim, and Trim are functions that return a string with leftmost, rightmost, or left and right blanks removed. Left and Right return a string that represents the requested number of leftmost or rightmost characters of the original string. InStr searches for a substring within a string. Len returns the length of a string. Mid can be used to return a substring from the specified position of a string. Space returns a string consisting of the requested number of blank spaces. String returns a string consisting of the requested number of designated characters. IsEmpty can be used to determine whether a string has been assigned or is still in an empty uninitialized state. Cstr converts a number to a string and also makes use of localization settings to use the decimal indicator of the current country localization setting. StrComp carries out string comparisons, including alphanumeric comparisons that are not case sensitive. This function returns indicators of the comparison results, including the less than, equivalent, greater than, or null status of the compared strings.

As you can see, a wide variety of functions are available for string handling. It is important to be familiar with all of them. While you may not use them all frequently, you might run into a situation that one of the functions is perfectly suited to handle. If you know about it, you will have an easy solution at your disposal.

Q&A

QIf you wanted to write code to see how many characters a string contained, would you use Len or InStr?
ALen. This function will return the number of characters in a string. InStr, on the other hand, searches for the occurrence of a substring within a string.
QWhat string would be assigned to the VarA variable from this line of code:

VarA = Lcase(Ucase(Ucase("bean sprout")))

AVarA would contain the string bean sprout. Expressions are evaluated from inner to outer parentheses. Therefore, the last function applied to the string would be Lcase. This would convert the entire string to lowercase regardless of its current value.
QAssume that you know you have a string of the form Cost=XXX in a variable. You want to assign just the numeric cost factor, XXX, to another string. What function would you use to achieve this, InStr or Mid?
AYou would use Mid because it is the function you use to copy a substring from a given position in a string. InStr, on the other hand, locates a substring within a string and returns the character position. But in this problem, you already know the character position of the substring XXX and simply want to copy that substring to another variable.

Workshop

This lesson shows an example of parsing user input, or extracting pieces of information from larger strings that the user supplied. Think of examples in pages you work with where it might be helpful to parse user input to check its format. For example, consider whether you have any phone number fields on your Web pages. Think through and sketch out the algorithm that you would have to use to parse the area code of a phone number and to verify that it consists of three digits. You can assume that the area code is provided between parentheses, as in the format (555).

Quiz

Note
Refer to Appendix C, "Answers to Quiz Questions," for the answers to these questions.

  1. Show the If conditional expression you could use to validate that a user had entered Accounting for the txtDepartment input control, regardless of case. Use StrComp to carry out this check.
  2. Suppose you were working with a script for a library. A scriptwide variable string called s_strBorrower lists the last names of all the borrowers of a particular book. The s_strBorrower variable might look like Jones Smith Brophy Koets Kringle, for example. Assume that one person may have borrowed a book more than once. Write a code statement that will determine how many times Brown borrowed the book. Essentially, you have to determine how many times Brown is present in the string s_strBorrower.