You look tired. Why don't you take a five-minute break, and then we'll dive into the project code.
Welcome back! In this chapter, we'll use the data type and function features we read about to design some general support routines that will be used throughout the program. All of this code will appear in a Visual Basic module named General, all stored in a project file named General.vb.
Load the "Chapter 6 (Before) Code" project, either through the New Project templates, or by accessing the project directly from the installation directory. To see the code in its final form, load "Chapter 6 (After) Code" instead.
I've already added the General.vb file with its module starting and ending blocks.
Friend Module General End Module
All of the code we add in this chapter will appear between these two lines. Remember, modules are a lot like classes and structures, but you can't create instances of them; all of their members are shared with all parts of your source code. This allows them to be used anywhere in the application. We don't need to do anything special to make them available to the entire program, other than to set the access level of each member as needed.
First, we'll add some general constants used throughout the program. Back in Visual Basic 6.0, I would have called these "global constants." But now they are simply shared members of the General module. Add the following code just below the "Module General" statement.
Insert Chapter 6, Snippet Item 1.
' ----- Public constants. Public Const ProgramTitle As String = "The Library Project" Public Const NotAuthorizedMessage As String = _ "You are not authorized to perform this task." Public Const UseDBVersion As Integer = 1 ' ----- Constants for the MatchingImages image list. Public Const MatchPresent As Integer = 0 Public Const MatchNone As Integer = 1 Public Enum LookupMethods As Integer ByTitle = 1 ByAuthor = 2 ...remaining items excluded for brevity... End Enum Public Enum LibrarySecurity As Integer ManageAuthors = 1 ...remaining items excluded for brevity... ViewAdminPatronMessages = 23 End Enum Public Const MaxLibrarySecurity As LibrarySecurity = _ LibrarySecurity.ViewAdminPatronMessages
These constants and enumerations are pretty self-explanatory based on their Pascal-cased names. UseDBVersion will be used to ensure that the application matches the database being used when multiple versions of each are available. The MatchPresent and MatchNone constants will be used for library item lookups.
The two enumerations define codes that specify the type of library item lookup to perform (LookupMethods), and the security codes used to limit the features that a specific administrator will be able to perform in the application (LibrarySecurity).
It's time to add some methods. The first method, CenterText, centers a line of text within a specific width. For instance, if you had the string "Hello, World" (12 characters in length) and you wanted to center it on a line that could be up to 40 characters long, you would need to add 14 spaces to the start of the line (determined by subtracting 12 from 40, and then dividing the result by 2). The routine uses a couple of the string-specific Visual Basic functions (like Trim, Left, and Len) to manipulate and test the data, and the Integer Division "\" operator to help calculate the number of spaces to insert.
Insert Chapter 6, Snippet Item 2.
Public Function CenterText(ByVal origText As String, _ ByVal textWidth As Integer) As String ' ----- Center a piece of text in a field width. If the ' text is too wide, truncate it. Dim resultText As String resultText = Trim(origText) If (Len(resultText) >= textWidth) Then ' ----- Truncate as needed. Return Trim(Left(origText, textWidth)) Else ' ----- Start with extra spaces. Return Space((textWidth - Len(origText)) \ 2) & _ resultText End If End Function
The function starts by making a copy of the original string (origText), removing any extra spaces with the Trim function. It then tests that result to see if it will even fit on the line. If not, it chops off the trailing characters that won't fit, and returns that result. For strings that do fit on a line textWidth characters wide, the function adds the appropriate number of spaces to the start of the string, and returns the result.
Code snippet #2 also added a function named LeftAndRightText. It works just like CenterText, but it puts two distinct text strings at the extreme left and right ends of a text line. Any questions? Great. Let's move on.
Code snippet #3 adds a routine named DigitsOnly. It builds a new string made of just the digits found in a source string, origText. It does this by calling the IsNumeric function for each character in origText, one at a time. Each found digit is then concatenated to the end of destText.
Insert Chapter 6, Snippet Item 3.
Public Function DigitsOnly(ByVal origText As String) As String ' ----- Return only the digits found in a string. Dim destText As String Dim counter As Integer ' ----- Examine each character. destText = "" For counter = 1 To Len(origText) If (IsNumeric(Mid(origText, counter, 1))) Then _ destText &= Mid(origText, counter, 1) Next counter Return destText End Function
The last two functions, CountSubStr and GetSubStr, count and extract substrings from larger strings, based on a delimiter. Visual Basic includes two functions, Mid and GetChar, that also extract substrings from larger strings, but these are based on the position of the substring. The CountSubStr and GetSubStr examine substrings by first using a delimiter to break the larger string into pieces.
Insert Chapter 6, Snippet Item 4.
The CountSubStr function counts how many times a given substring appears in a larger string. It uses Visual Basic's InStr function to find the location of a substring (subText) in a larger string (mainText). It keeps doing this until it reaches the end of mainText, maintaining a running count (totalTimes) of the number of matches.
Public Function CountSubStr(ByVal mainText As String, _ ByVal subText As String) As Integer ' ----- Return a count of the number of times that ' a subText occurs in a string (mainText). Dim totalTimes As Integer Dim startPos As Integer Dim foundPos As Integer totalTimes = 0 startPos = 1 ' ----- Keep searching until we don't find it no more! Do ' ----- Search for the subText. foundPos = InStr(startPos, mainText, subText) If (foundPos = 0) Then Exit Do totalTimes = totalTimes + 1 ' ----- Move to just after the occurrence. startPos = foundPos + Len(subText) Loop ' ----- Return the count. Return totalTimes End Function
Just to be more interesting than I already am, I used a different approach to implement the GetSubStr function. This function returns a delimited section of a string. For instance, the following statement gets the third comma-delimited portion of bigString.
bigString = "abc,def,ghi,jkl,mno" MsgBox(GetSubStr(bigString, ",", 3)) ' Displays: ghi
I used Visual Basic's Split function to break the original string (origString) into an array of smaller strings (stringParts), using delim as the breaking point. Then I return element number whichField from the result. Because whichField starts with 1 and the array starts at 0, I must adjust the position to return the correct element.
Public Function GetSubStr(ByVal origString As String, _ ByVal delim As String, ByVal whichField As Integer) _ As String ' ----- Extracts a delimited string from another ' larger string. Dim stringParts() As String ' ----- Handle some errors. If (whichField < 0) Then Return "" If (Len(origString) < 1) Then Return "" If (Len(delim) = 0) Then Return "" ' ----- Break the string up into delimited parts. stringParts = Split(origString, delim) ' ----- See if the part we want exists and return it. If (whichField > UBound(stringParts) + 1) Then Return "" _ Else Return stringParts(whichField - 1) End Function
If these functions seem simple to you, then great! Most Visual Basic code is no more difficult than these examples. Sure, you might use some unfamiliar parts of the Framework Class Library, or interact with things more complicated than strings and numbers. But the overall structure will be similar. Most source code is made up of assignment statements, tests using the If statement, loops through data using a For...Next or similar statement, and function calls. And that's just what we did in these short methods.