This is Chapter 8 from my book, Learn to Program with VB.Net. If you would like to buy the book, or find out more information on it, just follow this link
http://www.johnsmiley.com/mybooks/0072131772.htm
Learn to Program with VB.Net
Chapter 8
Selection Structures
In programming, one of the most important capabilities your program must have is the ability to adapt to conditions that are encountered during run-time. In this chapter, we’ll continue to follow my Visual Basic class as we examine Selection Structures, specifically, the If statement and the Select...Case statement.
I arrived in the classroom a little later than usual, and found a little bit of a commotion.
"What's wrong?" I asked, noting that there was a group of people surrounding Rose and Jack.
"As you know," Jack said, "Rose and I are both engineers by trade and we work for the same company. Our company's biggest account is overseeing the construction of a new cruise ship in the United Kingdom. Anyway, it seems that construction is way ahead of schedule, and yesterday our supervisor told us that we're being called away to participate in the sea trials. So you see, this will probably be our last class!"
"I'm disappointed," Rose said, "because I had hoped to finish the coding for the China Shop Project before we left, but there's no way we'll be near to that point today."
I explained to both Rose and Jack that we would all be sorry not to have them present al the way through the project, but we hoped they would be able to return in time to see the final version of the China Shop Project implemented in Joe Bullina's store.
"As far as the China Shop Project," I said. "I have a surprise for you. By the end of today's class, we'll have coded a complete working prototype of the China Shop Project."
As the obvious shock of my last statement subsided, I began our eighth class.
"In the absence of other instructions," I said, "Visual Basic begins execution of the code in an event procedure from the first line of code and executes each line through to the End Sub statement without interruption."
I explained that although this behavior is fine in most circumstances, in some cases it isn't.
"There may be cases," I said, "where you need to perform a calculation, but the calculation varies depending on conditions that the program encounters at run-time. A program that is as inflexible as a rock dropped from your hand cannot possess this intelligent capability."
"In the China Shop project, for example, we'll be calculating a total price for the customer's selection, but that price will vary based on the quantity selected by the user. Fortunately, Visual Basic gives us the ability to vary the way our program behaves based on conditions that if finds at run-time, such as which one of the RadioButtons the user has selected to indicate his or her desired quantity of china. I know that we've already done some experimentation with this falling rock behavior, but I want to give you all a chance to work with a series of exercises which will give you the chance to observe this behavior a little more closely."
I then distributed this exercise to the class.
In this exercise, we’ll place a TextBox and a Button Control on a form. We'll then place code in the Click event procedure of the Button Control to display the contents of the Text property of the Textbox in the Output Window. We'll see that whatever value we enter into the TextBox will be displayed in the Output Window.
1. Start a new Windows Application.
2. Place a TextBox and a Button Control on the form. Accept the default names that Visual Basic assigns.
3. Select the Text property of the TextBox in the Properties window and clear it by pressing the Backspace key.
4. Double-click on the Button Control and place the following code into its Click event procedure:
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
Console.WriteLine (TextBox1.Text)
TextBox1.Text = ""
TextBox1.Focus()
End Sub
5. Save the project, as we'll be modifying it in Exercise 8-2.
6. Now run the program.
7. Enter some text into the TextBox and then click on the Button Control. Whatever value you enter into the TextBox will be displayed in Visual Basic's Output Window. The TextBox will then be cleared, ready for your next entry. Type some more text into the TextBox and click on the Button Control. The new text entered in the TextBox will be displayed in the Output window as well:
|
Illustration 1
I asked if there were any questions. "There are a couple of things I don't understand," Ward said. "What's the purpose behind assigning two quotation marks to the Text property of the TextBox, and what is going on with that Focus statement?"
"Let's take this from the top," I said "The following line of code displays the contents of the TextBox in the Output window by printing the Text property of the TextBox control."
Console.WriteLine TextBox1.Text
"We've seen the WriteLine method of the Console object before, and I think everyone's OK with that. Now, Ward, here's the line of code you had a question about:"
TextBox1.Text = ""
"What we're doing here," I said, "is clearing the contents of the TextBox control by setting its Text property equal to an empty string "". This is similar to what we did ourselves in the Properties window before we ran the program, except that this time we're doing it in program code."
"Does that mean that all of the properties we can change in the Properties window at design-time can also be changed at run-time with code?" Steve asked.
"In general that's true," I said, "but there are some exceptions."
"What about that next line of code?" Rhonda asked. "I don't understand what's going on there--what's Focus?."
I displayed the line of code on the classroom projector:
TextBox1.Focus()
"Did you notice," I said, "that after you typed something into the Textbox and clicked on the button control, that your cursor was automatically placed in the Textbox? That's what this line of code does. Without it, after we enter something into the TextBox and click on the Button Control, focus would remain on the Button Control. Since it's reasonable to believe that the user might want to enter more text into the TextBox, as a courtesy, we should execute the Focus method of the TextBox to set the focus back to the TextBox. Now the user can just start typing into the Textbox without first having to tab to it or click it with their mouse."
"If we want to ensure that the user enters something into the textbox," I said, after waiting to see if anyone had any questions, "then this code has quite a few deficiencies. For instance, suppose the user fails to enter anything at all into the TextBox and just clicks on the Button Control? The code will just blindly execute the WriteLine method of the Console object…"
To show what I meant, I ran the program again and several times clicked on the button control without entering anything into the Textbox. The empty strings in the Output window were obvious to everyone…
Illustration 2
"Do we really want to display 'nothing' in the Output window?" I asked. "Probably not."
"How can we prevent it?" Peter asked.
"There are a couple of things we can do," I said. "We can disable the Button Control until the user has made a valid entry in the TextBox, or we can place code in the Click event procedure of the Button Control to check if the TextBox is 'empty' prior to executing the code to write to the Output window. If the textbox is empty, we can display a message to the user informing them that they need to enter something into the TextBox."
"Which of those two alternatives is the best?" Jack asked.
"Both will achieve the purpose," I said, "but I think that the second alternative is probably the easier of the two, since all we need to do is code an If statement."
"You make that sound so simple!" Ward exclaimed, and he was right, so I apologized. Nothing is simple when you're a beginner, at least not until you've done it once or twice.
"I know that we examined the If…Then statement very briefly a few weeks ago," I said, "let's look at it in a little more detail now."
"Programmers," I continued, "use the If…Then statement to build some intelligence into their programs. The If…Then statement will conditionally execute one or more statements. Conditionally means that lines of code may or may not be executed, depending upon conditions found by your program at run-time."
"One thing that makes the If…Then statement a bit confusing to beginners is the fact that there are two ways to code it. The first method is the single-line style," I said, as I displayed the single-line style syntax on the classroom projector:
If some condition is true Then execute a statement
"The second method is known as the block form style." I said, as I displayed its syntax on the classroom projector:
If some condition is true Then
execute a
statement or statements
End If
"Regardless of the style," I said, "some condition is always evaluated. If it is true, then a statement or statements following the word 'Then' are executed--these are sometimes called imperative statements. The difference between the single line style and the block form style is the number of statements that can be executed if the condition is True. With the single line style, only one line of code can be executed. With the block form style, one or more statements can be executed if the statement is True."
I waited to see if I was losing anyone before continuing.
"Notice that with the block form style, you must code an End If statement," I said. "Also, all imperative statements must appear after the word Then on a line or lines of their own. With the block form style, nothing can follow the word 'Then'. With the single-line style, only one imperative statement can be specified, and it must appear on the same line as the word 'Then'."
"So if you need to execute more than one imperative statement," Dave said, "you must use the block form method."
"Exactly Dave," I said.
"This syntax is picky!" Rhonda said.
"At first it is Rhonda," I said, "but after a while, you'll get pretty comfortable with it. In fact, what I tell many of my beginner students is rather than worrying whether to code the single line style or the block form style, just code everything using the block form style--- even where there is just a single imperative statement that you wish to execute if the condition is True."
"Can you do that?" Mary asked.
"Sure you can," I said, "I know many Visual Basic programmers who never code a single line If statement---they use the block form all the time. In fact, many programmers think the block form is easier to read."
I gave them a moment to take that in.
"I notice that neither of these styles use Else," Steve commented.
"Actually," I said, "Else is a variation of the basic If…Then statement and we'll be looking at it shortly."
"In the syntax you just showed," Rhonda said, "what's a condition?"
"A condition is any Visual Basic expression that evaluates to a True or False value," I replied.
"I see," she said nodding affirmatively, "the same types of expressions we looked at last week with the Comparison and Logical operations."
"So you're saying that if a condition evaluates to True," Valerie said, "then all of the statements following the word Then are executed."
"That's right," I said. "but don't forget, there can be any number of statements executed if the condition is true. Typically, these statements appear as separate lines of code following the word Then."
"What if the condition evaluates to False?" Ward asked. "does that mean that all of the statements following the word Then are bypassed?"
"Excellent Ward," I said. "The only time the statements following the word Then are executed is if the condition evaluates to True--if the condition evaluates to False, they're all bypassed."
"I think this discussion would make more sense to me if you could give us an example," Rhonda said.
A good idea--I then created a new project with a single Button Control and placed the following code into its Click event procedure:
Protected Sub Button1_Click(ByVal sender as Object, ByVal
e as System.EventArgs)
Dim intValue As
Integer = 22
If intValue = 22
Then MsgBox ("The value of intValue is 22")
End Sub
"This is an example of the single-line syntax," I said. "Notice that with the single-line syntax, there is just a single imperative statement following the word Then. This imperative statement appears on the same line following the word 'Then'. Also, notice there is no End If statement required when using the single-line syntax."
I then ran the program, clicked on the Button Control and predictably, the message box appeared, displaying its message.
"You mentioned that some programmers use the block form style, even though it's not required for a single imperative statement," Dave said. "Could you show us that here?"
"And could you explain why we would want to do that again?" Ward asked.
"Sure Ward," I said. "Some programmers believe that using the block form style even though it's not required to execute a single imperative statement enhances the readability of their code."
I changed the code, converting the single-line If statement to a block-form If statement, and displayed it on the classroom projector.
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
Dim intValue As
Integer = 22
If intValue = 22
Then
MsgBox
("The value of intValue is 22")
End If
End Sub
I ran the program, clicked on the Button Control and received the same result.
"I understand much better now," Linda said, "and I think you're right. Using the block form style does seem to make the If statement stand out more. Is that also why you indented the code?"
"Yes," I replied. "Programmers routinely indent their code to make it more readable, particularly when they use If…Then statements. Of course, indenting has no effect on the execution of your code, although…"
"Although what?" Steve asked.
"Hiring managers look for good coding habits such as these when deciding among potential job candidates," I said.
"Are you saying that failing to indent your code can affect whether you are hired for a programming position?" Steve repeated.
"It could have a negative impact," I said, "in the same way that failing to properly comment your code can have an impact."
"Getting back to that code," I said, "Suppose we were to change the assignment statement so that the value of intValue is 23, what will happen then?"
"Nothing," Peter answered. "We only have code in place to execute if the condition intValue = 22 is true."
"Strictly speaking," I said, "nothing appears to happen, but in fact, the condition is evaluated as False, and so the program skips to the line following the words End If, which in this case is the End Sub."
I continued by saying that if you need to execute more than one statement when the condition evaluates to true, you must use the block form syntax. To demonstrate the execution of more than one imperative statement with the block-form, I quickly added a TextBox control to the project and modified the code in the Button Control's Click event procedure to execute a second statement if the condition evaluates to True:
If intValue = 22 Then
MsgBox
("The value of intValue is 22")
TextBox1.Focus()
End If
I ran the program---the message box was displayed and focus was set to the Textbox. No one had any questions about the If statement, and so I suggested that we should turn our attention to using an If statement to handle the problem from exercise 8-1 where the user enters 'nothing' into the Textbox and then clicks on the Button Control.
In this exercise, we’ll modify the code from Exercise 8-1, so that if the user makes no entry in the TextBox, a message box will be displayed instructing them that this is not permitted.
1. Continue working with the project from Exercise 8-1.
2. Modify the Click event procedure of the Button Control so that it looks like this:
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
If TextBox1.Text
= "" Then
MsgBox
("You must make an entry in the Textbox")
TextBox1.Focus()
Exit Sub
End If
Console.WriteLine TextBox1.Text
TextBox1.Text =
""
TextBox1.Focus()
End Sub
3. Save the project as we'll be modifying it in Exercise 8-3.
4. Now run the program.
5. Enter some text into the TextBox and then click on the Button Control. As in the previous exercise, whatever text you enter into the TextBox will be displayed in the Output window.
6. Now, with the TextBox empty, click on the Button Control. A message box will be displayed warning you that an empty entry is not allowed:
|
"I think I understand what's going on here," Ward said, "but what is the purpose of the Exit Sub statement?"
"That's a good question," I said. "Let me answer your question by asking you one. If the user makes no entry in the TextBox, clicks on the button control and we then display an error message, what should happen next?"
There was silence.
"Well," I said, "we've displayed the error message, and then set the focus back to the TextBox. Because of the 'falling rock' behavior of code execution, if we don't do something, the code following the words 'End If' will be executed--and we don't want that."
"So Exit Sub," Kathy said, "is a way to bypass the rest of the code in the event procedure?"
"Exactly Kathy," I said. "Exit Sub tells Visual Basic that we don't wish to execute any of the remaining code in the Event Procedure."
Exit Sub
"This line of code ensures that the rest of the code in the event procedure is not executed. It ends the execution of the code in the event procedure right there and then."
"Do you mean that nothing after the words Exit Sub are executed?" Barbara asked.
"That's right," I said. "Nothing. As soon as Visual Basic sees the Exit Sub statement, the event procedure is terminated. Do you see that without the Exit Sub statement we would execute the statements to display the contents of the TextBox in the Output window."
"I see that," Rhonda said, "but couldn't we have placed the If statement after the code to display the Textbox contents in the Output window."
"What's that expression about closing the barn door after the horse has gone?" I said. "If we placed the If statement after the WriteLine statement, we would display the contents of the empty TextBox in the Output window and then we would perform the If test to see if it was empty!"
After a moment or two, Rhonda readily agreed that this wouldn't make any sense at all. The If…Then statement was exactly where it belonged, at the beginning of the event procedure.
"You're right," I said, "the use of Exit statements are sometimes frowned upon, but remember, the syntax is available in the language, so it's perfectly valid to use it. But you are right---there is a more eloquent way of writing this code, and it does eliminate the need to code an Exit Sub statement in the event procedure."
I continued by explaining that with the If…Then statement, we tell Visual Basic to execute one or more imperative statements if the condition evaluates to True, but we never specify what to do if the condition evaluates tot False. "The If…Then…Else statement," I said, "allows us to specify one or more imperative statements to execute if the condition evaluates to False."
I displayed the syntax for the If…Then…Else statement:
If some condition is true Then
execute a statement or statements
ElseIf some other condition is true Then
execute a statement or statements
Else
execute a statement or statements
End If
"I've read about the Else statement," Dave said, "but I'm not familiar with the ElseIf statement."
"ElseIf is an optional statement;" I said. "In reality, it's just like another If statement that is coded before the End If statement. You can have as many ElseIf statements as you need to test the condition or conditions you wish to evaluate---or you can have none at all."
"This looks like it can get pretty complicated," Ward said. "It's looks like we really have three variations on the If statement, don't we? How do you decide which one of the three to use?"
"You're right Ward," I said. "There really are three 'flavors' of the If statement and the differences between can be very subtle:"
· The first flavor, the simple If…Then statement (whether single line or block-form), specifies code to execute for a True condition, but no code for the False condition.
· The second flavor, the If…Then…Else statement, specifies code for both the True and False conditions.
· The third flavor, the ElseIf statement allows you to specify multiple True and False conditions.
I suggested that we take the code from Exercise 8-2, and modify it to include statements to execute if the condition is False.
In this exercise, we’ll modify the code from Exercise 8-2, using an Else statement to eliminate the need to code an Exit Sub statement.
1. Continue working with the project from Exercise 8-2..
2. Modify the Click event procedure of the Button Control so that it looks like this:
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
If
TextBox1.Text = "" Then
MsgBox ("You must make an entry in the textbox")
Else
Console.WriteLine TextBox1.Text
TextBox1.Text = ""
End
If
TextBox1.Focus()
End Sub
3. Save the project if you wish--we won't be modifying it any further.
4. Now run the program.
5. Notice how the behavior of the program hasn't changed--although the code has changed.
Discussion
"So the behavior of the program hasn't changed a bit here," Ward said, "although we did change the code."
"That's right," I said, "I would say the code is a bit more eloquent."
"How so?" Steve asked.
I asked everyone to compare the code from Exercise 8-2 with the code in this exercise. "We have one less line," Steve said, "is that what makes it more eloquent?"
"That's part of it," I said. "but I think you would also have to agree that this code is much more readable now--it just flows better. Instead of having the somewhat cryptic Exit Sub statement, not only do we explicitly state what code will be executed if the condition is True but also the code that will be executed if the condition is False. Nothing is left to the imagination."
"I notice also," Dave said, "that in the previous version of the code we repeated the line TextBox1.Focus twice; now that line of code is outside of the If…Then…Else structure. I presume that's because we set Focus to the TextBox regardless of whether the condition evaluates to True or False?"
"An excellent observation, Dave" I said. "If we have code that is to be executed regardless of whether the condition is True or False, we just place it outside of the If…Then…Else structure."
Everyone seemed to understand what I was talking about .
"Can you give us an example of code with an ElseIf statement?" Joe asked.
After thinking for a few moments, I said, "To make this all a little more understandable, let me use pseudocode to illustrate an ElseIf statement."
I saw some puzzled looks.
"I mentioned pseudocode very early on in the course," I said. "Pseudocode is just a tool that programmers use to express a complex problem, but instead of coding it up in a particular language, pseudocode let's us express the problem in English. Then, when we have it worked out to our satisfaction, we can translate the pseudocode into whatever language we happen to be working work. Remember, what you see here isn't Visual Basic code--so don't try to type it into a code window!"
I then displayed this pseudocode on the classroom projector:
Pseudocode is just a way of expressing a complex statement in English, prior to coding it in an actual programming language. This is not unlike the wording we used in our Requirements Statement.
There is an employee working for a company.
According to the rules of company…
If the employee’s age is 62 or greater Then
he must be retired
ElseIf the employee’s age is 61 Then
he has 1 year until retirement
ElseIf the employee’s age is 60 Then
he has 2 years until retirement
ElseIf the employee's age is 59 Then
he has 3 years until retirement
Else
he has a really long time to go
End If
I suggested that we try coding this pseudocode ourselves using Visual Basic, but I warned everyone that this code would be a bit unwieldy. "Using a series of ElseIf statements can be cumbersome," I said. "After we code up this pseudocode in this exercise, in Exercise 8-5 we'll see how we can streamline this code using another Selection Structure called the Select…Case Statement."
Exercise
8-4
The If...Then...ElseIf Statement
In this exercise, we’ll explore the
If..Then..ElseIf statement.
1.
Start a new Windows Application.
2. Place a TextBox and a Button Control on the form. Accept the default names that Visual Basic assigns.
3. Select the Text property of the TextBox in the Properties window and clear it by pressing the Backspace key.
4. Double-click on the Button Control and place the following code into its Click Event Procedure.
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
If
TextBox1.Text = "" Then
MsgBox ("You must make an entry in the textbox")
ElseIf Val(TextBox1.Text) > 61 Then
Console.WriteLine TextBox1.Text & " - You must be retired"
ElseIf Val(TextBox1.Text) = 61 Then
Console.WriteLine TextBox1.Text & " - You have 1 year until
retirement"
ElseIf Val(TextBox1.Text) = 60 Then
Console.WriteLine TextBox1.Text & " - You have 2 years until
Retirement"
ElseIf Val(TextBox1.Text) = 59 Then
Console.WriteLine TextBox1.Text & " - You have 3 years until
retirement"
Else
Console.WriteLine TextBox1.Text & " - You have a long time
until retirement"
End
If
TextBox1.Text = ""
TextBox1.Focus()
End Sub
5. Save the project---we'll be modifying it in exercise 8-5.
6. Now run the program.
7. Type 62, 61, 60 , 59 and 40 into the TextBox and click on the Button Control after each entry. All of the various messages should be displayed in the Visual Basic Output window. If you try clicking the Button Control without making an entry in the TextBox, you will receive an error message. Your output window should look like this…
|
Illustration 4
There was probably more code in this exercise than in any of the others we had done so far, and several of my students became confused and lost their places. Fifteen minutes later, though, I was happy to see that everyone in the class had successfully completed it.
"I don't think we've ever written that much code," Rhonda said.
"I think you're right, Rhonda" I replied. "As you probably noticed, when you write code that tests for a variety of different conditions, your code can really 'balloon'---but sometimes, it's something that just can't be helped. The code you've written for this exercise, though lengthy, is still pretty manageable. But suppose we had a requirement to print a different message for every age between 1 and 100?"
"That would really balloon the code," Mary said. "Is there an alternative to the ElseIf statement?"
"Yes there is," I said, "and we'll get to that in a minute. But before we go there, I'd like to explain this code in just a bit more detail."
I displayed the first two lines of code from the exercise on the classroom projector:
If TextBox1.Text = "" Then
MsgBox ("You must make an entry in the textbox")
"What we're doing here," I said, "is checking to ensure that the user has made an entry in the TextBox, which of course, is exactly what we did in the previous exercise. Now the next line of code may look familiar to you …"
ElseIf Val(TextBox1.Text) > 61 Then
"I see that we're using the Val function here," Linda said, "I seem to recall having discussed that before."
"That's right Linda," I answered. "The Val function converts the String data type of the Text property of the Textbox into a Numeric data type. We're using it here to convert the user's entry in the TextBox to a number."
"I'm sure we've covered this before," Steve said, "but why is the Val function necessary?"
I reminded the class that each property has a data type of its own and the Text property is a string data type.
"It's not possible to perform numeric comparison on a string," Ward said. "Isn't that right? Is that why we had to use the Val function prior to comparing the Text property of the Textbox to the number 61?"
"Exactly right, Ward" I replied. "In order to perform any arithmetic or numeric comparisons on a String data type, we must first convert the string to a numeric data type, and that's what the Val function did here."
"What is that funny character on the next line of code," Chuck asked.
I explaining that the next line of code uses the concatenation character, the Ampersand (&)
Console.WriteLine TextBox1.Text & " - You must be retired"
to join the string " - You must be retired" with the value of the Text property of the TextBox. Therefore, if the number 62 has been entered into the TextBox, the Output window then displays the following message: 62 - You must be retired
"That's clever," Steve said. "So we're using the value of a property in the message--not a numeric literal."
"That's right Steve," I said. "Using the value of the property, and then concatenating it to the message give us a much more flexible and descriptive message. No matter what age the user enters into the TextBox, that age is displayed in the Output window, concatenated to an appropriate descriptive message."
"What about the rest of the code?" Rhonda asked. "Can you explain the rest?"
"Sure," I said. "After we convert the entry in the TextBox to a numeric data type, we then compare it, using the greater than Comparison operator, to see if it is greater than 61. We learned last week that Comparison operations return a True or a False value. If the number entered into the Textbox is greater than 61, a True value is returned, and we then display the user's age, joined with the string '- You must be retired' in the Visual Basic Output window."
"What if the user's age is not greater than 61?" Kate asked. "This is where I became confused."
"If the user's age is not greater than 61," I said, "the Comparison operation returns False, and our code jumps right to the line beginning with ElseIf and executes it. Of course, the ElseIf line turns out to be another If statement when is then evaluated…
ElseIf Val(TextBox1.Text) = 61 Then
Console.WriteLine TextBox1.Text & " - You have 1 year until
retirement"
"This code also converts the value in the Text property to a numeric date type," I said, "and then determines if that value is equal to 61. If it is, then we execute the imperative statement following the word Then, displaying an appropriate message in the Visual Basic Output window. If the entry in the TextBox is not equal to 61, we jump right to the next ElseIf statement to determine if the user's age is 60:"
ElseIf Val(TextBox1.Text) = 60 Then
Console.WriteLine TextBox1.Text & " - You have 2 years until
retirement"
"I'm OK with this," Linda said. "This is basically the same code we used to determine if the user's age is 61. If it is, we display a slightly different message in the Output window."
"That's right," I agreed, "and we can say the same thing about this section of code, which checks to see if the user's age is 59:"
ElseIf Val(TextBox1.Text) = 59 Then
Console.WriteLine TextBox1.Text & " - You have 3 years until
retirement"
"Now can you imagine," I said, "if we had to write individual lines of code for every age from 59 on down to 1. Fortunately, we can take care of all of those possibilities with the simple Else statement:"
Else
Console.WriteLine
TextBox1.Text & " - You have a long time until retirement"
End If
"By using the Else statement here," I said, "we tell Visual Basic that all of the remaining ages fit into one big category and to display, in the Output window, a generic message about having a long time until retirement."
I asked if there were any questions. "We didn't discuss the two lines of code outside of the If…Then…Else structure," Rhonda said.
"Good point," I replied. "These two lines of code are executed regardless of the age that the user enters into the TextBox. They clear the contents of the Textbox, and set focus to it."
TextBox1.Text = ""
TextBox1.Focus()
"I just wanted to mention," Linda said, "that I ran this code in Step Mode and it really made things very clear for me."
"That's a great point Linda," I said. "Beginners should probably run every piece of code they write in Step Mode to see what's going on behind the scenes of their program."
"Suppose we were asked to modify our program to do something like this?" I asked.
I then displayed this modified pseudocode on the classroom projector:
There is an employee working for a company.
According to the rules of company…
If the employee’s age is 62 or greater Then
he must be retired
ElseIf the employee’s age is 61 Then
he has 1 year until retirement
ElseIf the employee’s age is 60 Then
he has 2 years until retirement
ElseIf the employee’s age is 59 Then
he has 3 years until retirement
ElseIf the employee’s age is between 50 and
59 Then
he has a short time to go
ElseIf the employee’s age is between 40 and
49 Then
he has some time to go
ElseIf the employee’s age is between 25 and
39 Then
he
has a pretty long time to go
ElseIf the employee’s age is between 18 and 24 Then
he
has a really long time to go
Else he should be in school
End If
"That will complicate our program quite a bit," I said. "Are we up to an If…Then…Else statement with eight alternatives?"
"That's a lot of ElseIf statements," Ward said.
"The more alternatives we have in an If…Then…Else statement," I said, "the harder the program is to write, read and modify, and the more likely it is that we’ll make a mistake when we code it. Fortunately, there is an alternative to the If…Then…Else statement called the Select…Case statement which can be a godsend when your program must evaluate many alternatives like this one."
I then displayed the syntax for the Select…Case statement on the classroom projector:
Select Case testexpression
[Case expressionlist1
[statementblock-1]]
[Case
expressionlist2
[statementblock-2]]
.
.
[Case
Else
[statementblock-n]]
End Select
"Rather than trying to dryly explain this syntax," I said, "let me display an example of the Select…Case statement on the classroom projector. This is the first statement in a Select…Case structure:"
Select Case intValue
"The Select…Case statement begins with the words Select Case followed by what is called a test expression. You should be familiar with expressions by now. An expression is evaluated, and a result is returned. With the Select…Case statement, there is just a single test expression coded at the 'top' of the Select Case statement, and according to the rules for the Select…Case statement, the test expression must return either a number or a string. In this example, our test expression is actually a variable called intValue. Following that first line of code containing the test expression comes a series of Case statements. Here's the first one in our demo…"
Case 1
MsgBox ("intValue is equal to 1")
"This code tells Visual Basic to display a message if the value of the variable intValue is equal to 1. What makes the Select…Case structure so powerful is the ability to easily specify multiple conditions such as this one…"
Case 2,3
MsgBox ("intValue is either 2 or 3")
"The comma in the Case statement," I said, "is read like an Or operator. And look how easily a range of values can be specified:"
Case 4 to 8
MsgBox ("intValue is in the range 4 through 8")
"Or this way:"
Case Is > 45
MsgBox ("intValue is greater than 45")
"Why is the word 'Is' in that code?" Linda asked.
"I originally wrote that as Case > 45," I said, "but Visual Basic inserted the word 'Is' for me. According to the rules of the Select Case Statement you are not permitted to repeat the name of the test expression in a Case expression. In other words, you can't repeat the word intValue anywhere in your Case expressions. I suspect Visual Basic uses the word 'Is' as a replacement for intValue. You can read the statement as Case intValue > 45, but you mustn't enter the code that way."
I paused before continuing.
"Finally, how about this code?" I continued:
Case 1 To 3,5,9 To 13, Is > 100
MsgBox ("Wow!")
MsgBox ("This is great!")
"Trying to do this type of multiple condition testing is very tedious with an If…Then…Else statement," I said, "but virtually a snap with the Select…Case statement."
"It looks to me," Rhonda said, "like the Select…Case statement is just perfect. Why bother using the If…Then…Else statement at all?"
"The Select…Case statement does have its limitations," I said, "Remember, with the Select…Case statement you are limited to a single test expression, which means you have to formulate your case expressions around that limitation."
"In the syntax you displayed on the projector," Dave said, "there was a Case Else statement. What does that do?"
"The Case Else statement is an optional catchall statement," I said. "just like an ElseIf. Basically, you use the Case Else statement to handle a case you can't anticipate. If the test expression doesn't fall into one of the preceding Case statements, the code in the Case Else statement is executed."
Case Else
MsgBox ("Nothing was True")
"Suppose you have several Case expressions that evaluate to true?" Barbara asked. "Are all the tests done or does Visual Basic stop after the first true one, like the If statement? For example, in the code you just showed us, there were two Case statements that would evaluate to True for a value of intValue equal to 1."
"That's a excellent question," I said. "In Visual Basic, if a Case expression evaluates to true, all of the remaining Case expressions are bypassed. Therefore, if you have more than one Case expression which can evaluate to true, the first one in the list is the one that will have its code executed. In the example I showed you, if intValue was equal to 1, only the first Case statement would be executed."
We had been working for a long time without a break. I suggested that we complete one more exercise before taking a break.
In this exercise, we’ll explore the If..Then..ElseIf
statement.
1. Continue working with the project from Exercise 8-4.
2. Modify the Click event procedure of the Button Control so that it looks like this:
Protected Sub Button1_Click(ByVal sender as Object, ByVal e as System.EventArgs)
If
TextBox1.Text = "" Then
MsgBox "You must make an entry in the textbox"
TextBox1.Focus()
Exit Sub
End
If
Select Case Val(TextBox1.Text)
Case Is > 61
Console.WriteLine TextBox1.Text & " - You must be retired"
Case 61
Console.WriteLine TextBox1.Text & "
- You have 1 year until retirement"
Case 60
Console.WriteLine TextBox1.Text & " - You have 2 years until
retirement"
Case 59
Console.WriteLine TextBox1.Text & " - You have 3 years until
retirement"
Case 50 To 58
Console.WriteLine TextBox1.Text & " - You have a short time to
go"
Case 40 To 49
Console.WriteLine TextBox1.Text & " - You have some time to
go"
Case 25 To 39
Console.WriteLine TextBox1.Text & " - You have a pretty long
time to go"
Case 18 To 24
Console.WriteLine TextBox1.Text & " - You have a long time to
go
Case Else
Console.WriteLine TextBox1.Text & " - You should be in
school"
End
Select
TextBox1.Text = ""
TextBox1.Focus()
End Sub
3. Save the project if you wish--we won't be modifying it.
4. Now run the project..
5. As was the case with exercise 8-4, enter a number of different retirement ages into the TextBox and watch as various retirement messages are displayed in the Visual Basic Output window.
"Most programmers find the Select…Case statement to be pretty straightforward," I said.
"I noticed that we included the test for an empty TextBox outside the Select…Case statement," Bob said. "Couldn't we have included that test within the Select…Case Statement."
"Unfortunately not," I said, as I displayed the code on the classroom projector:
If TextBox1.Text = "" Then
MsgBox "You must make an entry in the textbox"
Exit
Sub
End If
"Do you remember that I said that we could specify only a single test expression in the Select Case statement? That means that we can't specify a test expression for both an empty TextBox and a specific value in the TextBox. Since we coded the test expression like this:"
Select Case Val(TextBox1.Text)
"we needed a separate If…Then test for an empty TextBox. Notice also, that, as we did before, we converted the string data type of the Text property of the TextBox to a numeric value using the Val function. This first Case statement is pretty straightforward…
Case Is > 61
"we're just checking to see if the entry in the Textbox is greater than 61. This line of code…"
Case 61
"… checks whether the value entered into the TextBox is 61. The next few lines of code perform the same check for the ages 60 and 59. This line of code…"
Case 50 To 58
"illustrates how easy it is to check for a range of values entered into the TextBox using the Select…Case structure. This next series of Case statements operates in the same manner, the only thing that changes is the message displayed. Finally," I said, "here's the catchall Else case:"
Case Else
Console.WriteLine TextBox1.Text & " - You should be in
school"
"If none of the other Case expressions evaluates to True," I said, " - You should be in school is displayed in the Output window."
"So the presumption here," Linda said, "is that if we get this far in the code, the user's age is less than 18?"
"That's right." I said. "Now before you say it, Linda, I know we could have coded a Case expression to handle this, like this for example:"
Case Is < 18
"but I wanted to give everyone a chance to work with the Case Else statement. Finally, beginners frequently forget this all-important line--the End Select statement!"
End Select
"We can't forget the End Select statement," I said, "since it marks the end of the Select Case Structure. When a Case expression evaluates to True and its statement or statements are executed, code execution resumes with the line of code following the End Select statement."
I concluded by asking everyone to look at the two lines of code after the End Select statement. Since it's outside of the Select…Case Structure, this code is executed regardless of the evaluation of the individual Case expressions:
TextBox1.Text = ""
TextBox1.Focus()
I asked if there were any questions. There were none, and so I told everyone to take a well-earned break.
"When we return from break," I said, "we'll begin coding the China Shop Project."
"We now know enough about Visual Basic," I said, "to put some basic code structures into our project. With the skills we have amassed we can now begin to code the project. It won't have all the bells and whistles that our Requirements Statement is asking for, but it should at least produce a usable quote."
"Let's take a moment to review where we are with the project," I said, "since it's been a couple of weeks since we last worked with it. Our user interface is basically in place now. The menu must be added of course, but that we'll come towards the end of this course. When we start the program, the ListBox is loaded with the three brands of china that the China Shop sells. Clicking on the RadioButtons and CheckBoxes triggers the default behavior of these controls, but at this point, nothing more. Clicking on the Calculate and Reset buttons also has no effect on the program."
"How far do you think we get with the program today?" Rhonda asked.
"I think we'll have time to write code for the Click event procedures of both the Calculate and Reset Button Controls," I said.
"You mean we'll actually be to the point of calculating a price today?" Ward asked.
"I think so," I replied. "First, though, we need to place some code in the Click event procedures of our RadioButton controls."
I reminded everyone that to calculate a sales quotation for the China Shop application, our program needs three pieces of information: a brand of china, the user's selection of a quantity and his or her selection of one or more china items.
"I think it will make our job of calculating a price a little easier," I said, "if we store the customer's quantity selection in a form-level variable, and then use that value later on in our computations. To do that, we'll place code in the Click event procedures of the 4 RadioButton controls."
In this exercise,
you'll code the Click Event procedures of the four RadioButton controls.
1. Load up the China Shop Project.
2. Place the following code in the Declarations section of the form. Place it right above the Public Sub New procedure. This statement will declare a form-level variable called m_intQuantity:
Private m_intQuantity as Integer
3. Place the following code into the Click event procedure of the rad1 RadioButton.
Public Sub rad1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles rad1.Click
m_intQuantity = 1
End Sub
4. Place the following code into the Click event procedure of the rad2 RadioButton.
Public Sub rad2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles rad2.Click
m_intQuantity = 2
End Sub
5. Place the following code into the Click event procedure of the rad3 RadioButton.
Public Sub rad3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles rad3.Click
m_intQuantity = 4
End Sub
6. Place the following code into the Click event procedure of the rad4 RadioButton.
Public Sub rad4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles rad4.Click
m_intQuantity = 8
End Sub
7. Save the China Shop Project
8. The addition of this code will have no obvious impact on your program, but you should run the program anyway to ensure that it still runs without errors.
"I was able to complete this exercise," Rhonda said, "but I must confess I'm absolutely sure what's going on here."
"I suspect you're not the only who feels that way," I said. "What we've done is placed code into the Click event procedures of each one of the RadioButtons. Whenever they are clicked, the value of m_intQuantity is set equal to the quantity that they represent. For instance, when rad8 is clicked, that indicates that the user is selecting a quantity of 8 for their china purchase--so we set the value of m_intQuantity equal to 8."
"I'm OK with that," Steve said, "but why did we declare the variable in the Declarations Section of the form--why not within the Click event procedures of the RadioButtons?"
"A variable declared in the Click event procedure of the RadioButton would live only for as long as the click event procedure." I said. "As soon as the code in the Click event procedure finished executing, the variable would die, and along with it its value."
"And a form level variable stays around for as long as the form is loaded," Dave said. "plus since it's a form level variable, the value can be seen by all of the code on the form."
"That's right!" I said. "Once we have the customer's desired quantity stored in the variable m_intQuantity, that value can be seen by all of the event procedures on the form. Later on we'll see that fact becomes very important to the Click event procedure of the btnCalculate Button Control."
Kate's point was excellent. Although the code we had just added to the China Shop project had no obvious impact on the program, we could see its impact behind the scenes by running our program in Step Mode.
"That's a great point, Kate," I said "By running the program in Step Mode, we'll be able to see the assignment of values to m_intQuantity as they take place. You can also, if you wish, place breakpoints on the code in the RadioButton control's event procedures which will cause the program to enter break mode when those lines of code are encountered."
"I didn't realize how much," Barbara said, "step mode and break points could help me understand what is actually going on in the program, I think I'll use it all of the time now."
In this exercise,
you'll code the Click Event procedure of the chkCompletePlaceSetting CheckBox.
1. Continue working with the China Shop project (or load it up if you have closed it.)
2. Place the following code into the Cick event procedure of the chkCompletePlaceSetting check box:
Public Sub chkCompletePlaceSetting_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkCompletePlaceSetting.Click
If chkCompletePlaceSetting.Checked = True
Then
chkPlate.Checked = True
chkButterPlate.Checked
= True
chkSoupBowl.Checked
= True
chkCup.Checked
= True
chkSaucer.Checked
= True
Else
chkPlate.Checked
= False
chkButterPlate.Checked
= False
chkSoupBowl.Checked
= False
chkCup.Checked
= False
chkSaucer.Checked
= False
End If
End Sub
3. Save the China Shop Project.
4. Run the program and click on the Complete Place Setting check box. All of the china items (except for the Platter) will automatically be selected:
|
Illustration 5
5. Click on the Complete Pace Setting CheckBox again. This time all of the china items (except for the platter) will automatically be de-selected.
I scanned the room for obvious signs of difficulty but found none--most of my students seemed to be pretty proud of themselves, and I found more than one clicking on the Compete Place Setting CheckBox over and over again.
"I had no trouble doing the exercise," Linda said, "but I am a little confused as to when exactly the Click event procedure of the CheckBox takes place. Does it take place before or after the check mark appears or disappears in the check box?"
"That's a good question," I said. "The click event procedure of the CheckBox takes place after the check mark appears or disappears--that's why we're able to use the Checked property of the CheckBox to determine if we should check or uncheck the other CheckBoxes. Let's take a closer look at the code now…"
I continued by explaining that the first thing we do in this code is to determine what the current state of the Complete Place Setting's check box is--we used the Checked property to determine if there's a checkmark in the CheckBox…
If chkCompletePlaceSetting.Checked = True Then
"The Checked property is a Boolean property," I said, "and if its equal to True, that tells us that the customer has just placed a check mark in the Complete Place Setting Check box. that means we should now place check marks in the five check boxes representing the items that that comprise a Complete Place Setting (i.e., all of the items except for the Platter), by setting their Checked properties to True…:"
chkPlate.Checked =
True
chkButterPlate.Checked
= True
chkSoupBowl.Checked
= True
chkCup.Checked
= True
chkSaucer.Checked
= True
"At this point," I continued, "we could check to see if the Checked Property of the Complete Place Setting CheckBox is False with another If…Then statement, but since the Checked property of the CheckBox is a Boolean value, if it's not True it must be…"
"False," Ward said, taking the words right out of my mouth.
"That's right Ward," I agreed, "if the Checked property's value isn't True, it must be False, and so we can handle that eventuality with an Else statement, using it to set the checked properties of each of the five CheckBoxes comprising a Complete Place Setting to False…"
Else
chkPlate.Checked
= False
chkButterPlate.Checked
= False
chkSoupBowl.Checked
= False
chkCup.Checked
= False
chkSaucer.Checked
= False
I've got to tell you," Rhonda said, "I think this is really neat. If the rest of the programming of the China Shop program turns out to be this much fun, I think I'm hooked on programming."
Since there were no more questions about this event procedure, I told everyone that it was now time to move onto the 'bread and butter' of the program, the Click event procedure of the Calculate button control.
In this exercise,
you'll code the Click Event procedure of the btnCalculate Button Control.
1. Continue working with the China Shop project (or load it up if you have closed it.)
2. Place the following code into the Click event procedure of the btnCalculate Button Control:
Public Sub btnCalculate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
'Declare our variables
Dim sngTotalPrice As
Single
Dim
sngButterPlatePrice As Single
Dim sngCupPrice As
Single
Dim sngPlatePrice As
Single
Dim sngPlatterPrice
As Single
Dim sngSaucerPrice
As Single
Dim sngSoupBowlPrice
As Single
'Has the customer selected a brand of china?
If lstBrands.Text =
"" Then
MsgBox("You must select a China
brand")
Exit Sub
End If
'Has the customer selected one or more china items?
If chkPlate.Checked
= False And _
chkButterplate.Checked = False And _
chkSoupbowl.Checked = False And _
chkCup.Checked = False And _
chkSaucer.Checked = False And _
chkPlatter.Checked = False Then
MsgBox("You must select one or
more china items")
Exit Sub
End If
'Has the customer selected a quantity?
If rad8.Checked =
False And _
rad4.Checked = False And _
rad2.Checked = False And _
rad1.Checked = False Then
MsgBox("You must select a
quantity")
Exit Sub
End If
'If the customer has
selected a platter
'warn them that there
is only 1 permitted per sales
'quotation
If
chkPlatter.Checked = True And m_intQuantity > 1 Then
MsgBox("Customer is limited to 1
platter per " & _
"order." & chr(13) & _
"Adjusting price accordingly")
End If
'All the pieces are
here, let's calculate a price
'Assign prices to
each item
Select Case
lstBrands.Text
Case "Mikasa"
If chkPlate.Checked = True Then
sngPlatePrice = 25
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 10
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 10
If chkCup.Checked = True Then
sngCupPrice = 5
If chkSaucer.Checked = True Then
sngSaucerPrice = 5
If chkPlatter.Checked = True Then
sngPlatterPrice = 50
Case "Farberware"
If chkPlate.Checked = True Then
sngPlatePrice = 10
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 3
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 5
If chkCup.Checked = True Then
sngCupPrice = 3
If chkSaucer.Checked = True Then
sngSaucerPrice = 3
If chkPlatter.Checked = True Then
sngPlatterPrice = 13
Case "Corelle"
If chkPlate.Checked = True Then
sngPlatePrice = 4
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 1
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 2
If chkCup.Checked = True Then
sngCupPrice = 1
If chkSaucer.Checked = True Then
sngSaucerPrice = 1
If chkPlatter.Checked = True Then
sngPlatterPrice = 5
End Select
'Add the prices
together and multiply by the quantity to
'calculate a grand
total
sngTotalPrice =
(((sngPlatePrice + sngButterPlatePrice _
+ sngSoupBowlPrice +
sngCupPrice + sngSaucerPrice) _
* m_intQuantity) + sngPlatterPrice)
'If the price is
greater than 0, display the price and
'make the label
visible
If sngTotalPrice
> 0 Then
lblPrice.text = "The price of your
order is $" & _
sngTotalPrice
lblPrice.Visible = True
End If
End Sub
3. Save the China Shop Project.
4. Run the program. Select Mikasa as your choice of china brand, 2 for quantity and select Plate, Butter Plate and Soup Bowl as your china items. If you now click on the Calculate Button Control, a calculated price of 90 should be displayed:
|
Illustration 6
It took about 15 minutes for everyone to complete this exercise. As I had warned the class, there was a lot of typing to do, and more than one student made typos entering the code--but after they were all finished, I could sense the feeling of accomplishment they were feeling---in essence, their version of the China Shop program was complete---it was now calculating a price quotation for a mythical customer.
"Let's take a good look at this code now," I said, as I attempted to pry them away from their efforts running the program. "The first thing we did here was to declare local variables that we use in the price calculation. It's good programming practice to declare variables at the 'top' of an event procedure. Also, as a courtesy to other programmers who may read your code, it's a good idea to insert comments, like the ones we have used here, to indicate exactly what is going on in the program."
'Declare our variables
Dim sngTotalPrice As
Single
Dim
sngButterPlatePrice As Single
Dim sngCupPrice As
Single
Dim sngPlatePrice As
Single
Dim sngPlatterPrice
As Single
Dim sngSaucerPrice
As Single
Dim sngSoupBowlPrice
As Single
"What exactly are these variables used for?" Chuck asked.
"The methodology we'll use to calculate a total price," I said, "requires that we first calculate a subtotal price for each item of china that the customer desires. These variables represent the prices of each china item, and the variable sngTotalPrice is the variable that will store the grand total."
"That makes a lot of sense to me," Rhonda said. "What are those If…Then statements used for?"
"Before we can calculate a price," I said, "we need to ensure that the customer has provided us with the following three pieces of information:"
· A brand of china
· One or more china items
· A quantity
"We use three If…Then statements to ensure we have everything we need to calculate a sales quotation." I said. "This first section of code ensures that the customer has made a selection in the list box by checking the Text property of the list box. If the Text property is empty, we know that no brand has been selected, and we display a message to the user and then bypass the rest of the code by executing the Exit Sub statement…"
'Has the customer selected a brand of china?
If lstBrands.Text =
"" Then
MsgBox("You must select a China
brand")
Exit Sub
End If
"I'm still a little confused," Valerie said. "How does a value get stored in the Text property of the ListBox?"
"When the customer makes a selection of an item in the list box by clicking on it, the Text property of the list box is automatically set to the name of the item that the customer has selected."
"I see," Valerie said, "so if the customer selects Mikasa in the list box, the Text property of the list box is then assigned the value Mikasa?"
"I just saw that," Ward said excitedly. "when I ran the program in Step Mode and used the Immediate window to display the Text property of the list box."
"Great," I said, "now you're getting the idea."
"So if the customer has made no selection at all in the list box," Blain said, "the Text property of the ListBox will contain an empty string."
"Exactly," I answered. "Now let's examine the code to determine if the customer has made at least one selection of a china item."
'Has the customer selected one or more china items?
If chkPlate.Checked
= False And _
chkButterplate.Checked = False And _
chkSoupbowl.Checked = False And _
chkCup.Checked = False And _
chkSaucer.Checked = False And _
chkPlatter.Checked = False Then
MsgBox("You must select one or
more china items")
Exit Sub
End If
"This code," I said, "checks the Checked property of each one of our CheckBox controls to ensure that the customer has selected at least one item. Notice the use of the And operator here, and notice also how we used the line continuation character to make the code more readable---otherwise we would have had one gigantic line of code."
"The And operator," Barbara said, "requires that for the entire statement to be considered True, every expression must be True also?"
"That's right Barbara," I said, "that means that if the customer hasn't selected at least one item of china, the If…Then statement evaluates to True, and we then display a warning message to the customer and exit the Click event procedure using the Exit Sub statement."
I then displayed the code that ensures that the customer has selected a quantity:
'Has the customer selected a quantity?
If rad8.Checked =
False And _
rad4.Checked = False And _
rad2.Checked = False And _
rad1.Checked = False Then
MsgBox("You must select a
quantity")
Exit Sub
End If
"Again, we use the And operator here," I said. "If the Checked property of all four RadioButtons is False, we know that the customer has not made a quantity selection."
I waited to see if anyone was confused before continuing.
"At this point, provided the customer has made a selection of a china brand, one or more items, and a quantity, we now have all the ingredients we need to calculate a price---but there's one more section of code we need to execute before we get to the actual price calculation."
'If the customer has
selected a platter
'warn them that
there is only 1 permitted per sales
'quotation
If
chkPlatter.Checked = True And m_intQuantity > 1 Then
MsgBox("Customer is limited to 1
platter per " & _
"order." & chr(13) & _
"Adjusting price accordingly")
End If
"You may remember," I said, "that Joe Bullina has a policy of permitting the customer to purchase just one platter. As you'll see shortly, we can handle the special problem that restriction poses in our calculation pretty easily--- but we really should tell the customer about the limitation and that's what this code does. We check to see if the Platter CheckBox is checked, and also if the customer's selected quantity is greater than 1---if it is, we display a message to the user.""
"What's going on with chr(13) in the Message Box?' Barbara asked.
"If you want to display more than one line in a Message box," I said, "you need to concatenate the ASCII character for a Line Feed to the first line of your message---that's what we're doing here. As a result, the message looks a little more readable."
I quickly ran the program, selected Mikasa as my brand, the Platter as an item and a quantity of 4. I then clicked on the Calculate button and the following message box was displayed on the classroom projector…
|
Illustration 7
"How did you decide what to do in your code 0after this" Rhonda exclaimed. "This is the part of programming that really confuses me! How did you ever come up with that formula to calculate the price?"
"Let me first state that there are probably several ways to calculate the price," I said. "What I did was come up with my own algorithm to do it."
"What’s an algorithm?" Steve asked.
"An algorithm is just a step-by-step methodology to solve a problem," I said. "My children are learning algorithms in school now, but instead of calling them algorithms, they call them word problems. But regardless what you call them---an algorithm is just a way of coming up with a method or formula to solve a problem. And what I do is to develop the algorithm using paper and pencil first."
"Paper and pencil?" Steve asked, obvious surprised.
"That's right," I said. "Once your algorithm works on paper, then the hardest part is really out of the way and you can then translate the algorithm into Visual Basic code."
"You make it sound so easy," Ward said. "What's the algorithm at work here?"
"Let me take you through my original though process," I replied. "which began with a statement of the problem. What is it that we need to do?"
"Calculate a price," Ward answered.
"That's good Ward," I said, "now can you tell me how we calculate a price?"
"Once we know that the customer has selected a brand, one or more items, and a quantity, we determine the brand of china that the customer has selected, determine the quantity the customer has selected and then, for each item of china the customer has selected, multiply the unit price by the quantity," Ward replied after thinking for a moment.
"That sounds like a great algorithm to me!" I said. "I can tell you Ward that you're right on with this algorithm."
"It can't be that easy," Barbara said.
"All algorithms aren’t this easy," I said, "but as simple as this price calculation is, without coming up with an algorithm in a methodical way, it's very possible to mess it up. Ordinarily, what we would do now is sit down, once again with pencil and paper, and test the algorithm using some simulations--for instance, the customer selects the Mikasa brand, selects a Plate, Butter Plate, and Soup Bowl, and a quantity of 2---calculate the price. We would then ensure that the algorithm calculates the correct price--which in this case is $90."
"What do we do now?" Joe asked.
"We translate Ward's algorithm into Visual Basic terms now," I said. "First, how do we know what brand the customer has selected?"
"By examining the list box," Linda said.
"Good," I said, "but not just the ListBox--what property of the ListBox?"
"The Text property of the list box," Steve answered.
"Excellent," I said. "And how do we know what quantity the customer has selected?"
"By determining which of the four RadioButtons have been selected," Kathy said.
"Not quite Kathy," I said, "do you remember what we did earlier in the Click event procedures of each one of the RadioButtons?"
"That's right," Dave said, "we determine the customer's quantity by checking the value of the variable m_intQuantity, which is updated whenever one of the RadioButton controls is clicked."
"Great, Dave" I said. "Now what about the china items? How can we determine which items the customer has selected?"
"By examining the check box controls," Ward answered. "If the check box has a check mark in it, I mean if the Checked property is equal to True, that means that the customer wants that item to be included in their price quotation."
"Everything you've all said is excellent," I said. "I guess the most difficult part of this is how to determine the unit price for the individual items of china?"
While the class was pondering this, I displayed this code on the classroom projector:
'All the pieces are
here, let's calculate a price
'Assign prices to
each item
Select Case
lstBrands.Text
Case "Mikasa"
If chkPlate.Checked = True Then
sngPlatePrice = 25
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 10
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 10
If chkCup.Checked = True Then
sngCupPrice = 5
If chkSaucer.Checked = True Then
sngSaucerPrice = 5
If chkPlatter.Checked = True Then
sngPlatterPrice = 50
Case "Farberware"
If chkPlate.Checked = True Then
sngPlatePrice = 10
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 3
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 5
If chkCup.Checked = True Then
sngCupPrice = 3
If chkSaucer.Checked = True Then
sngSaucerPrice = 3
If chkPlatter.Checked = True Then
sngPlatterPrice = 13
Case "Corelle"
If chkPlate.Checked = True Then
sngPlatePrice = 4
If chkButterPlate.Checked = True Then
sngButterPlatePrice = 1
If chkSoupBowl.Checked = True Then
sngSoupBowlPrice = 2
If chkCup.Checked = True Then
sngCupPrice = 1
If chkSaucer.Checked = True Then
sngSaucerPrice = 1
If chkPlatter.Checked = True Then
sngPlatterPrice = 5
End Select
"Can anyone explain what's going on in this section of code?" I asked.
"It looks to me," Dave said, "that we are using a Select...Case statement to determine the brand of china that the customer selected. Within the Select...Case structure, we appear to be checking each check box Checked property to determine what items the customer has selected. If the customer has selected the item, we are then assigning a price, unique to that item and brand, to one of the variables we declared earlier."
"An excellent analysis, Dave" I said. "that's exactly what we are doing."
I continued by explaining that at the very top of the event procedure, we had declared six variables to store prices for each of the individual items of china.
"For instance," I said, "sngPlatePrice is the variable that we use to hold the price for a plate, sngSoupBowlPrice is the variable that we use to hold the price for a soup bowl, and so on."
"Didn't we promise Mr. Bullina that we would look up prices from a text file?" Linda asked.
"That's a good point," I replied, "and you're right. The way we've 'hard coded' these prices into our program is a bad idea in a commercial program, but as they say, you need to crawl before you can walk. For now, this will be fine--in the upcoming weeks, we'll make good on our promise by modifying our program to read unit prices from an external disk file." I waited a moment before continuing.
"Let's examine that hypothetical scenario we went through a moment ago," I said. "A customer selects Mikasa for the brand, a quantity of 2, and selects a plate, butter plate and soup bowl. What will be the values of the individual variables in this event procedure?"
"Let's see," Linda said without a moment of hesitation, "sngPlatePrice will be equal to 25, sngSoupBowlPrice will be equal to 10 and sngButterPlatePrice will equal 10, sngCupPrice will equal ..."
She hesitated.
"Excellent so far," I said. "But why the hesitation?"
"I'm not sure what the value of sngCupPrice will be, since our mythical customer hasn't selected it," she said.
"No need to worry," I assured here. "Since we declared sngCupPrice as a Single type variable, it was automatically initialized with a value of 0. Since our mythical customer hasn't selected a cup, a value is never assigned to sngCupPrice---it retains its initial value of 0."
"In that case," she continued, "sngCupPrice is 0, sngSaucerPrice is 0 and sngPlatterPrice is 0."
"At this point," I said. "we now have values for each of the six variables that will comprise the grand total, which brings us to this code.."
'Add the prices
together and multiply by the quantity to
'calculate a grand
total
sngTotalPrice =
(((sngPlatePrice + sngButterPlatePrice _
+ sngSoupBowlPrice + sngCupPrice +
sngSaucerPrice) _
* m_intQuantity) + sngPlatterPrice)
"Any idea what is happening here?" I asked.
"It looks like we're taking the value of all the variables, except for the variable representing the platter, and adding them together. Then we're multiplying that sum by the value of the variable m_intQuantity, which is the customer's selected quantity. Then we're adding the price of the platter variable to calculate the total price and assigning that value to the variable sngTotalPrice," Barbara said.
"A wonderful explanation Barbara!" I said. "I couldn't have said it any better myself."
"I don't understand why the price of the platter is not multiplied by m_intQuantity?" Rhonda asked.
"That's because of the limit of one platter per customer," I replied. "We never want to multiply the unit price of the platter by more than 1."
"That's right," Rhonda said. I waited a moment, but there were no more questions. Everyone seemed to understand the calculation of the sales quotation--not a simple undertaking---but we still had one more piece of code in the event procedure to discuss:
'If the price is
greater than 0, display the price and
'make the label
visible
If sngTotalPrice
> 0 Then
lblPrice.text = "The price of your
order is $" & _
sngTotalPrice
lblPrice.Visible = True
End If
"This is the code that displays the sales quotation," I said.
I reminded everyone that earlier in the course we had decided to make the label control invisible until it was time to display the price. "For that reason," I said, "we use an If...Then statement to determine if the value of the variable sngTotalPrice is greater than 0. If it is, we then assign the value of the variable sngTotalPrice to the Text property of the label control and then we make the label control visible. If the value of sngTotalPrice is 0, the label control remains invisible."
It was time to complete the final exercise of the day.
In this exercise,
you'll code the Click Event procedure of the btnReset Button Control.
1. Continue working with the China Shop project (or load it up if you have closed it.)
2. Place the following code into the Click event procedure of the btnReset Button Control:
Public Sub btnReset_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnReset.Click
lstBrands.SelectedIndex
= -1
chkPlate.Checked =
False
chkButterPlate.Checked
= False
chkSoupBowl.Checked
= False
chkCup.Checked =
False
chkSaucer.Checked =
False
chkPlatter.Checked =
False
rad8.Checked = False
rad4.Checked = False
rad2.Checked = False
rad1.Checked = False
chkCompletePlaceSetting.Checked
= False
lblPrice.Visible =
False
End Sub
3. Save the China Shop Project.
4. Run the program. Select a brand of china, a quantity, and some items. Press the Calculate Button Control to display a price. Now press the Reset Button Control, all the selections should be cleared.
"This is probably the only line of code that caused you some hesitation," I said. "This line of code deselects the selected brand in the list box by setting the SelectedIndex property of the list box to –1:"
lstBrands.SelectedIndex = -1
I explained that the SelectedIndex property of the list box contains the number of the item selected in the list box.
"The first item in the list is number 0," I said, "the second item is 1 and so on. Setting this property to -1 deselects every item in the list box. This next section of code deselects all of the china items by setting the Checked properties of each of their CheckBoxes to False…"
chkPlate.Checked =
False
chkButterPlate.Checked
= False
chkSoupBowl.Checked
= False
chkCup.Checked =
False
chkSaucer.Checked =
False
chkPlatter.Checked =
False
"And this code deselects each RadioButton," I said, "once again by setting their Checked properties to False.."
rad8.Checked = False
rad4.Checked = False
rad2.Checked = False
rad1.Checked = False
"Next we remove the check mark in the Complete Place Setting check box," I continued.
chkCompletePlaceSetting.Checked = False
"And finally, the lblPrice label is made invisible again:"
lblPrice.Visible = False
No one had any questions, and neither was there any more material to cover in today's class.
"Our prototype is essentially complete," I said, "Now comes the moment of truth when we have to unveil our work to the customer!"
"Just in time!" Joe Bullina exclaimed, as he walked into the classroom with a smile on his face. As I had known we would be finishing up coding the prototype today, I had arranged for Joe Bullina to pay us another surprise visit. All of my students seemed very excited about showing off their prototypes, so after exchanging 'hellos' with everyone, I sat Joe down in front of my computer and ran the application for him. Joe spent a few moments interacting with the interface, selecting various options and watching, sometimes in amazement, at the way the program calculated prices. Meanwhile, everyone in the class crowded behind him in dead silence.
"I'm simply overwhelmed," Joe finally said, "this program is fantastic!"
I felt as if everyone let out a big sigh of relief---there's always some anticipation when you show the user your prototype for the first time. Joe then spent about a half hour reviewing the prototypes of the students (at least those who weren't too shy to share them with him.)
"So when can I have this installed in the China Shop?" Joe asked.
"Not for a few weeks yet," I said, "you see, it's still not finished!"
"It looks great!" Joe exclaimed. "It seems to do everything I want. What else is left to do?"
"What you are looking at Joe," Linda said, "is just a prototype of the application. We have designed it just to show you how things will look in the final version--but there are still some enhancements that need to be made."
"What kind of enhancements?" Joe asked.
"Well, for one thing," Ward began, "with this version of the program, you can't change the prices of your china items."
"And we haven’t put a menu in place yet either" Barbara added.
"That's right," said Joe, "I remember those details from the Requirements Statement! Well, in that case, I'll leave you to get on with it! Let me know how things are going, won’t you John?"
I assured Joe that we would keep him up to date on the project and thanked him for coming in to see us.
"Well, there you have it!" I exclaimed, when I got back from showing Joe out of the classroom, "I think it's safe to say that Joe liked what we he saw, and that's he's given us the green light to continue!"
"Did you notice how excited he was when he saw the prototype?" Kate added.
"Yes," said Linda, "he really was excited. In fact, I thought he might have taken the program with him back to the China Shop today if we hadn't stopped him."
"You're probably right Linda," I said. "We're lucky we have a written Requirements Statement that stopped him from rushing ahead with a program that's only partially complete. The value of the Requirements Statement isn’t only to ensure that everyone agrees on what needs to appear in the program, but also to keep everyone on the right track as the project progresses!"
With that final statement, I dismissed class, telling them, on their way out, that next week we would begin the real job of turning our prototype into a production-ready application.
In this chapter, we examined Selection Structures and how they are used to vary the way a program behaves based on conditions found at run-time. We saw that there are several types of Selection Structures, the many varieties of the If…Then statement and the Select…Case structure.
Remember the falling rock? We've seen how we can use Selection structures to change this behavior, starting with the plain If…Then statement. If a condition evaluates to True, then the imperative statement or statements following the word 'Then' are executed. The If…Then statement can be expanded to include alternative instructions for a False condition as well, using the Else keyword, and even further with a set of ElseIf keywords.
After a number of ElseIf's, your code will begin to look cumbersome. At this point, it's more elegant to use the Select Case structure. Always remember to include the End Select (or, in the case of If…Then statements, the End If line); otherwise, Visual Basic will complain that it doesn't know where your statement ends. You'll get a compile error when you try to run the program.
We've also come to a significant point in our project – the working prototype. This is a very important stage in the development process, because all the key working parts of the program are now in place. From this point onwards, we'll be adding functionality and code to turn our prototype into a professional-level program. Let's just take a look at what this chapter taught us.