
C# ПІДРУЧНИКИ / c# / Hungry Minds - ASP.NET Bible VB.NET & C#
.pdf'statements
End While
Now look at a practical example of how this While...Wend programming structure can be used in the real world:
Dim lContinue as Boolean, intCounter as Integer
lContinue = TRUE
intCounter = 1
While lContinue = TRUE
MsgBox("Welcome to my .NET world !",
MsgBoxStyle.Exclamation, "Welcome Message" & str(intCounter))
if intCounter > 10 then
lContinue = FALSE
end if
intCounter = IntCounter + 1
End While
'Other code continues here...
This code tests for a few conditions. The first one is to run the While loop until the lContinue variable becomes something other than True. The code then sends out a message box to the screen, welcoming the user to the new world of .NET. Then, another control structure is used within the While loop; this is called program nesting.
Note |
You will find that many of these logical decision programming |
|
constructs will work in concert with each other to make an |
|
application flow smoothly. There are many combinations of |
|
"nesting" these commands within others. In the preceding code |
|
example, the While construct leverages on the answer of a |
|
nested If...Then...Else statement. Don't be surprised if you see |
|
nested Ifs and nested Whiles used repeatedly in programming |
|
code. |
The loop is being tested for how many times it has run by interrogating the value of intCounter. If it is found to be greater than 10, then the logical variable lContinue is set to a value of False. The code then continues to flow, adding 1 to the intCounter variable and then returning to the top of the loop, where the value of lContinue is tested one more time. This time it is tested as being False (not True), and the While loop is terminated with the programming code continuing to run at the next command that follows the End While command.
For Next Loops
Another logical construct that is available to the .NET developer is the controlled looping commands of the For...Next loop. This looping structure is very similar to that of the While loop, except that it is only concerned with a certain number of iterations and does not depend on the value of another variable. Although there are some variations on this construct, flexibility is built in, as shown later in this section. The complete syntax follows:
For counter = start To end [ Step step ]
' Statement block to be executed for each value of counter.
Next [ counter ]
Here is a practical example of a For...Next loop:
Dim intLoopCount
For intLoopCount = 1 to 25
'Debug.WriteLine exports the given values to the debug window...
Debug.WriteLine ("Current Value of intLoopCount:" & intLoopCount)
Next intLoopCount
'More code...
This example will repeat the code of displaying text in the debug window 25 times. When the loop is concluded, the program continues its operation on the next line of code following the Next command. The For...Next loop increases the value of intLoopCount automatically, so you don't need to increment it yourself. Another feature of the For...Next loop construct is that you can set the amount by which the loop counter is counted. This is accomplished with the Step addition. Consider the following example:
Dim intLoopCount
For intLoopCount = 1 to 25 Step 5
'Debug. WriteLine exports the given values to the debug window...
Debug. WriteLine("Current Value of intLoopCount:" & intLoopCount)
Next intLoopCount
'More code...
Again, this code repeats until the intLoopCount reaches the number 25; however, in this case, it will only loop a total of five times, because intLoopCount is being increased by 5 each iteration of the loop rather than the default of 1. Step can also be used to count backward. The following example of the For portion of the construct is also valid:
For intLoopCount = 500 to 25 Step -50
Select Case Construct
The last major decision construct is that of Select Case. This construct is used when more than two paths need to be considered. Its use replaces the need for multiple If...Then commands, and it is easier to code, understand, and follow logically. For example, if you were trying to determine in what category to place someone's information based on the number of toes they have on each foot (sorry, that's all I could think of), and you were trying to do that with one long If statement, you would have to write this code:
If intToes = 1 then
' some code...
elseif intToes = 2 then
'some more code elseif intToes = 3 then
'some more code elseif intToes = 4 then
'some more code elseif intToes = 5 then
'some more code elseif intToes = 6 then
'it is possible !
end if
As you can see, even from this lame example, it is programmatically difficult to catch all the possibilities with this kind of coding scheme. Also, consider what would have to be changed if you had to start counting toes on both feet and then fingers too! This is where the Select Case construct can help. The full syntax follows:
Select [ Case ] testexpression
[ Case expressionlist
[ statements ] ]
[ Case Else
[ elsestatements ] ]
End Select
Here is a practical example:
Select Case intToes
Case 1
' some code...
Case 2
' some more code
Case 3
'some more code Case 4
'some more code Case 5
'some more code Case 6
'it is possible !
End Select
This is close to the other example, except that it looks cleaner and is easier to read. This alone is worth using it if you have a lot of similar coding decisions to make. The Select Case construct also has a "catch all" at the end that is very beneficial, which is the Case Else portion. Consider the preceding example. If you have to code for all the previous conditions and then also consider the situation in which there may be more toes to count, you have the option of using Case Else. You could write the preceding example as follows:
Select Case intToes
Case 1
'some code...
Case 2
'some more code Case 3
'some more code Case 4
'some more code Case 5
'some more code Case 6
'it is possible ! Case Else
'more code to catch all the other possibilities.
End Select
As you can see, the Case Else portion of the command can be used to catch any other situations that are not specifically being trapped. Even if you think that all the situations
are covered in the detailed Case condition lines, it is always a good idea to use Case Else, in the event that you may have missed a possible situation in the application.
Summary
This has been a very cursory overview of the VB.NET development environment. You have been introduced to the IDE as well as some coding standards. You have seen some of the basic building blocks of the whole .NET environment, and if you followed the sample mailing list project, you should have an application up and running.
Appendix B: Visual Basic Functions and Features
Overview
In Appendix A, "Visual Basic Syntax," you developed a small application, or solution, in the .NET environment. You were introduced to some of the basic code structures and decision-making constructs. As well, you were introduced to some of the more common IDE tools. All in all, you were given the first part of the foundation of the .NET environment. In this appendix, you will look at the second portion of the foundation, that of functions and subroutines.
Functions and Subroutines
First you need some definitions to lay the groundwork and set the stage for what will be covered in this appendix. A function is almost the same as a subroutine, except that the function is programmed to return a value to the calling code. A subroutine is a smaller portion of programming code that is defined to perform a specific task. Upon completion, subroutines do not return a data value to the calling code. Functions and subroutines also share the following attributes:
§Usually small blocks or sections of programming code
§Code is generally reusable in many contexts (if written well)
§Entities can have different scopes of use depending on how they are defined
To illustrate the differences between these two types of coding entities, a messenger analogy will be employed. A function is like a real-life messenger whom you send to the store for groceries. You give the messenger some money and a list of items to purchase. The messenger performs the task and returns with the goods. A subroutine is another type of messenger, except that this type of messenger is sent to a bank with money to deposit. The cash is given to the messenger and off he goes to perform the task. Eventually, and hopefully, your messenger returns with the good news that all has been accomplished. In effect, he only returns with the news that the task is completed. In both situations, you, as the sender, have to wait for the messenger to return (because you are hungry and want to know your new bank balance).
Subroutines and functions act in a similar fashion. Your code makes reference to them by name, and then you have to wait for the process to finish before your calling code can continue.
Now that you have been introduced to the definitions, you are ready to look at the syntax, with some code examples thrown in. Here is the official syntax for defining a subroutine:
[ <attrlist> ] [{ Overloads | Overrides | Overridable |
NotOverridable | MustOverride | Shadows | Shared }]
[{ Public | Protected | Friend | Protected Friend | Private }]
Sub name [(arglist)]
[ statements ]
[ Exit Sub ]
@code: @code: @code:[@code: @code:s@code:t@code:a@code:t
@code:e@code:m@code:e@code:n@code:t@code:s@code: @code:]@code:
End Sub
The following is a more concrete example:
Private Sub MySubRoutine(OptionalVariable as DataType)
'Code here
'Code here
End Sub
Every subroutine uses the key word Sub to indicate to the compiler that it is a subroutine. Also, to denote the conclusion of the subroutine, the key words End Sub are required. Any programming code between these "book ends" is considered part of the subroutine. The parentheses after the subroutine's name are used optionally to send data into it for processing.
Note |
The key word Private is used to denote the program scope of |
|
the defined subroutine or function. The scope of the defined |
|
routine is also determined by where it is created — more on that |
|
later in the section titled "Defining functions and scope." |
Here is an example of a subroutine that receives data and uses that data within its contained code:
Private Sub MySubRoutine (strValue as String)
Dim strMessage as String
StrMessage = "This is the passed in value: " & strValue
Debug.WriteLine(strMessage)
End Sub
You can see the variable called strValue being given to the subroutine via the parentheses. Then, within the routine, the strValue variable is concatenated to the hard-coded string and sent as output to the debug window.
Now look at the programming animal called a function — again, you will be shown the syntax first, followed by some practical examples:
[ <attrlist> ] [{ Overloads | Overrides | Overridable |
NotOverridable | MustOverride | Shadows | Shared }]
[{ Public | Protected | Friend | Protected Friend | Private }]
Function name[(arglist)] [ As type ]
[ statements ]
[ Exit Function ]
[ statements ]
End Function
The following is a more reasonable example of the basic syntax:
Private Function MyNextFunc(strValue as String) as String
'code here
'code here
MyNextFunc = "Hello My Name is Dawn Etta Riley"
End Function
Notice the differences here in relation to a subroutine:
§The Function keyword is used instead of Sub
§After the parentheses, a data definition is used
§End Function is used instead of End Sub
§The returned value is the name of the function as it is assigned within the function itself
And now for your practical example of a working function:
Private Function MyValue (intGiven as Integer) as Integer
Dim intCounter as integer, I as integer
Dim intHolder as Integer
IntCounter = intGiven * 5
IntHolder = 0
For I = 1 to intCounter
IntHolder += I
Next I
MyValue = intHolder
End Function
In this example, the function is defined as an integer function, and it will accept into it a value of an Integer data type called intGiven. Some variables are defined for use inside the function, and the counter variable is multiplied by 5 (just because). Then, a For...Next loop is employed to run intCounter times and during that loop another command is increasing the intHolder variable by the value of the counter (I).
You may find it helpful to "walk through" this code with some actual values. Let's pretend that intGiven is equal to 2. IntCounter becomes equal to 10, so the loop will then run 10 times. The first time through, the loop intHolder equals 1, the next time through intHolder is 1 + 2 = 3, next time 3 + 3 = 6, then 6 + 4 = 10, and so on. At the end of this process, intHolder finally equals 55. MyValue is assigned intHolder's value and is returned to the line of code that originally called the function.
This brings up a few other issues that you may have been wondering about:
§How do you call or invoke a function in code?
§What holds the value of the function once it is returned to the invoking code?
To help you understand the answers to these questions, consider the following code:
Dim intReturnedValue as Integer
IntReturnedValue = MyValue(2)
Debug.Write( intReturnedValue )
The second line of code performs two steps in one line. On the right side of the equal sign, the function called MyValue is triggered or called, passing it the value of 2. When the function is completed (remember that it should return the value of 55 in this case), the answer is assigned to intReturnedValue.
Defining functions and scope
Now that you see how to call a function, the next step to putting this puzzle together is to see where the function is defined. So far, all you have been exposed to in .NET is programming code being associated with a form or a window. .NET has the ability, and the need, to define programming code independently of a window or form. This is done by creating a module in which to house your code. A module is a nonvisual component of .NET. In this section, you will be using the solution coded in Appendix A called

Mailman. It is on the companion Web site for this book. To define an empty module, do the following:
1.Select the solution name in the Solution Explorer.
2.Right -click the solution name.
3.Select Add Item from the resulting pop-up menu.
4.Select Module and name it "GlobalCode.vb."
5.Click OK.
The module selection window looks like that shown in Figure B-1. The module has been named GlobalCode, but you can call it whatever you wish. The new module should appear in the Solution Explorer list.
Figure B-1: Module creation and naming window
This brings up the discussion of subroutine and function scope. Because this particular module is not part of any specific form or window, it can be referenced on a global or application-wide level. If a subroutine or function were to be created within this module, then any other entity within the application could use it by default. If, for example, a special date routine is defined in this module and it is needed throughout the entire solution, you could call it from any window or routine that needed it.
With the new module in the Solution Explorer in focus, double-click it to open the code editor for it. It may already be open in the design area for you, so simply click that area to give it focus. Define the following subroutine, which will be used to send information to the debug window whenever a menu item is clicked. This can be a helpful routine to use when tracing program action.
Sub MenuCheck(ByVal RoutineName As String)
Debug.Write("you are in the " & RoutineName & " menu code" )
End Sub
Now you need to tell the subroutine how to start. With the Mailman solution open, create another module using the same process as before; this time call the module MainMod.
Launching programs
VB.NET has a neat way to launch the programs that you create in it. If you create a MDI application, such as the Mailman program, then .NET knows to launch that window upon program execution simply because it is a MDI application. But what happens if you want
to do some processing before the main MDI form appears? What if you want to make a splash screen (welcome screen) or accept a user login request for system security needs? If either of the preceding is the case, then you have to do an additional two steps:
§Step 1: Create a special subroutine named Main().
§Step 2: Inform .NET that you now have a main module that you want to start the application with.
You can create a special subroutine named Main() in the new module you just defined called MainMod, or you can create it in another module of your choice.
Note You should not call any other subroutine in your application by the special moniker of Main. This is a "reserved" subroutine name used specifically for program launch issues. There are some ways around this, but it is highly recommended that you toe the Microsoft line on this one.
Consider the following Main() subroutine code and see if you can follow what is happening. After the code listing, it will be explained for you.
Sub Main()
Dim TimerEvent As New System.Threading.AutoResetEvent(False)
Dim Start, Finish
Dim frmMainForm As New frmMainWin()
'wait 6 seconds by calling dummyevent and giving the milliseconds. TimerEvent.WaitOne(6000, False)
'close the event handle
TimerEvent.Close()
frmMainForm.Show()
The splash screen code is not yet included in the preceding code because the frmSplash window itself has not yet been defined within the solution.
After defining some variables in memory with the DIM command, the Start variable is stored with the Timer object's current value. Adding five seconds to the value of the Timer object and storing the value in the variable called Finish is what happens next. Then, a simple "dummy" loop is run until the current value of the Timer object (which updates itself constantly with the value of the system clock) is less than the value stored in the Finish variable. This is done to keep the computer "busy" while the splash screen is showing and needed. After the loop has finished, the main MDI form is loaded and displayed. Then, control of the application is released to the new form because this subroutine is finished.
The second step that you are required to perform to have a Main() module in operation is to inform .NET that you now have a main module that you want to start the application with. You want this new module to take precedence during program launch. Under the Project Tools menu, after selecting the project name, you should see a menu item named Project Properties. Click this menu item to open the form shown in Figure B-2.

Figure B-2: Compiler options window
Here you tell the compiler what object to use for application launching. You should see in the Startup Object drop-down list all system objects (forms and modules) that you have defined so far. Select Sub Main to tell the compiler to use this subroutine to begin the application.
Note Other options are available here that you can explore yourself. Different ways to make the compiler act are among some of the additional options. Take a few minutes to explore through these options.
Now that you have set up the start module and written the main subroutine, make a simple splash screen similar to that shown in Figure B-3 and name it frmSplash.
Figure B-3: Sample splash window
Now, go back to your main code module and add the line of code shown in bold in the following code. This was left out previously because the code would not have compiled if it made reference to an entity that did not exist.
Sub Main()
Dim TimerEvent As New System.Threading.AutoResetEvent(False)
Dim Start, Finish
Dim frmSplashNew As New frmSplash()
Dim frmMainForm As New frmMainWin()
frmSplashNew.Show()
'wait 6 seconds by calling dummyevent and giving the milliseconds. TimerEvent.WaitOne(6000, False)
'close the event handle
TimerEvent.Close()
frmSplashNew.Close()
frmMainForm.Show()
End Sub
End Sub
Let's get back to the point of this whole section, which is to call the subroutine that was created in the module called "GlobalCode." Open the main form named frmMainWin and access the menu code for the address form. It should look like the code in the following listing:
Dim frmAdd1 As New frmAddress()
' enable menu items now that a window will be opened...
mnuCopy.Enabled = True
mnuPaste.Enabled = True
mnuCut.Enabled = True
mnuTileHoriz.Enabled = True
mnuTileVert.Enabled = True
mnuCascade.Enabled = True
'Set the Parent Form of the Child window.
frmAdd1.MdiParent = Me
frmAdd1.Show()
Add the following code that is in bold text, which will call the MenuCheck subroutine defined earlier in this appendix .
Dim frmAdd1 As New frmAddress()
' enable menu items now that a window will be opened...
mnuCopy.Enabled = True
mnuPaste.Enabled = True
mnuCut.Enabled = True
mnuTileHoriz.Enabled = True
mnuTileVert.Enabled = True
mnuCascade.Enabled = True