Now that we have gained knowledge about using arrays, we will create a program a little more advanced. We are going to create an application for a fictitious music store. The program will store the instruments and prices for the instruments in an array.
Open a new project.
Name the project MusicStore.
Name the form frmStore.
Set the form's Width property of the form to 10155 and the Height property to 6390.
Set the form's BorderStyle property to 1-Fixed Single and its MinButton property to True.
Set the form's StartUpPosition property to 2-Center Screen.
Set the form's caption as seen below.
Set up the interface below (place the objects first without the large frame):
Name the top label lblTitle.
Set its font size to 14 and select bold font style.
Set the AutoSize property of all the labels to True --> eight labels; Two displaying the word Quantity, two displaying the word Price, the top label, the labels in the lower right not set to a Fixed Single BorderStyle --> the labels to the left of those!
Name the label on the left displaying Quantity as lblQuantity.
Set the label's Index property to 0.
Name the other label displaying Quantity as lblQuantity.
Do the same thing for the label displaying the word Price, but name it lblPrice with appropriate indexes.
Name the first text box (the top leftmost one) txtQuantity.
Set the Index property of that text box to 0.
Set the Enabled property to False.
Copy the name from the properties list by pressing Ctrl then C.
Paste that name into the Name property for the other text boxes under the quantity labels by pressing Ctrl then V.
Name the first check box (the top leftmost one) chkItem.
Set the Index property of that check box to 0.
Copy the name from the properties list as you did earlier with txtQuantity now with the check box.
Paste that name into the Name property for the other check boxes as you did earlier.
Place a frame on the form.
Set the frame's Height property to 1575 and the frame's Width property to 3135.
Set the caption of the frame to the caption appearing on that object in the image above (the frame in the lower left of the form).
Place three option buttons on the form.
Size them down vertically by the objects handles an much as they go.
Set the captions of the option buttons as seen in the image above. Do not yet place them where you see them.
Name the option buttons as follows from top to bottom as you see them above:
optPriority
optGround
optAir
Select all the option buttons and press Ctrl X to cut the option buttons from the form.
Select the frame, then press Ctrl V to paste the option buttons into the frame.
Organize the option buttons as best you can if necessary.
Place three labels on the form, then select them all.
Change the BorderStyle property in the properties window to 1-Fixed Single.
Size those labels to match the labels in the lower right of the form in the image above.
Name those labels as follows from top to bottom:
lblProductTotal
lblShipping
lblOrderTotal
Set the Index property of each of those labels to 1.
Set the Alignment property of each of those labels to 1 - Right Justify.
Place three more labels on the form. They are the last labels --> the ones to the left of the labels you just placed in the image above.
Set their AutoSize property to True.
Set their captions as seen above.
Name those labels as follows from top to bottom:
lblProductTotal
lblShipping
lblOrderTotal
Select all the objects on the form, then press Ctrl X.
Place a frame object onto the form.
Set the frame's Width property to 9735 and its Height property to 5415.
With the frame selected, press Ctrl then V to paste all the objects into the frame.
Select the Format menu, then choose Lock Controls.
With the form still selected, click the Menu Editor icon on the standard toolbar.
In the caption text box, type &Store.
In the name text box, type mnuStore.
Press Next, then the right arrow.
In the caption text box, type &Fill In.
In the name text box, type mnuStoreFill.
Press Next.
In the caption text box, type C&lear Fields.
In the name text box, type mnuStoreClear.
Press Next.
In the caption text box, type &Display Order.
In the name text box, type mnuStoreDisplay.
Press Next.
In the caption text box, type &Calculate Order.
In the name text box, type mnuStoreCalculate.
Press Next.
In the caption text box, type a hyphen (-). Name it Separator.
Press Next.
In the caption text box, type Cl&ose.
In the name text box, type mnuStoreClose.
Now that we have set up this form, we can set up the order display form.
Add a new form to the project.
Set the form's Height property to and the form's Width property to
Set the form's BorderStyle property to 1-Fixed Single.
Set the form's StartUpPosition property to 2-Center Screen.
Name the form frmSummary.
Set up the form below:
Name the top label lblSummary.
Name the list box (the largest square) lstOrder.
Name the label displaying "Order Total:" lblTotal.
Set that label's Index property to 1.
Name the label next to it lblTotal.
Name the command button cmdDone.
Lock the controls on the form.
Go back to the form we set up earlier.
Well done setting up those forms. Now we can finally begin coding!
Add a code module to the project
Review: Project > Add Module
Name the module Order.
Type Public sngTotal as Single in the code module
Open the code window for the form frmStore.
In the General Declarations section of that code window, type the following lines:
Option Explicit
Dim bytField As Byte
Dim intQuantity As Integer
Dim strCatalog(9, 3) As String
Dim sngSubtotal As Single, sngShipping As Single
Line 1: Tell Visual Basic to create an error when the
code uses an undeclared variable.
Line 2: Declare variable bytField as the Byte data-type to
store the values of the indexes of the objects.
Line 3: Declare variable intQuantity as the Integer
data-type to store the amount of items the user wants when they want the same
amount of items for the entire order (this makes our life easier to select all
the items as well).
Line 4: Declare variable strCatalog as a String array, with
the dimensions 10 by 4 (includes 0).
Line 5: Declare variable sngSubtotal as a Single to store
the total amount of the order before the shipping price. Declare variable sngShipping
as a Single to store the cost of the shipping for the order.
Select the optPriority object in the object box of the code window.
Press tab, then type sngShipping = 39.95.
This line sets the shipping cost (sngShipping) to 39.95 when the option button optPriority is selected. This is just a little joke on the government because they lie about their shipping costs. Anyway...
Select the optGround option button in the object box of the code window.
Press tab, then type sngShipping = 5.95.
Select the optAir option button in the object box of the code window.
Press tab, then type sngShipping = 14.95.
Select the mnuStoreClose object in the object box of the code window.
Press tab, then type Unload frmStore.
Select the mnuStoreFill menu item in the object box of the code window.
Press tab, then type the following lines:
Dim bytField As Byte
intQuantity = InputBox("Enter quantity:", "Fill All Fields")
For bytField = 0 To 9
txtQuantity(bytField).Text = intQuantity
chkItem(bytField).Value = Checked
Next bytField
Line 1: Declare variable bytField to store the
index of the objects.
Line 2: Display an input box asking the user for the quantity of all the
items, then store that value in the variable intQuantity.
Line 3: Begin For Next loop. Take bytField and look at
values 0 through 9.
Line 4: Set the text of the text box with the current index value of bytField
to the value of intQuantity, retrieved from the user in line 2. It goes
through all of the text boxes because they are indexed 0 through 9,
the same range of the loop values.
Line 5: Check all the check boxes.
Line 6: Go to the next value of bytField in order to look at all
the objects (0 through 9).
Select the form object in the object box of the code window.
Press tab, then type the following lines:
strCatalog(0, 0) = "Ludwig 5-Piece Beginners' Drum Set"
strCatalog(0, 1) = "299.95"
strCatalog(1, 0) = "6-Piece Remo Masteredge Drumset"
strCatalog(1, 1) = "2199.95"
strCatalog(2, 0) = "6-Piece DW Drumset"
strCatalog(2, 1) = "2899.95"
strCatalog(3, 0) = "14-inch New Beat Zildjian Hi-Hat"
strCatalog(3, 1) = "179.95"
strCatalog(4, 0) = "6-inch Zildjian Splash"
strCatalog(4, 1) = "49.95"
strCatalog(5, 0) = "16-inch Zildjian Medium Crash"
strCatalog(5, 1) = "189.95"
strCatalog(6, 0) = "18-inch Zildjian Medium Thin Crash"
strCatalog(6, 1) = "199.95"
strCatalog(7, 0) = "7.5-inch LP Cowbell Supreme"
strCatalog(7, 1) = "24.95"
strCatalog(8, 0) = "5B Woodtip Zildjian Drumsticks"
strCatalog(8, 1) = "9.95"
strCatalog(9, 0) = "Vic Firth 2B Plastic Tip Drum Sticks"
strCatalog(9, 1) = "11.95"
sngShipping = 39.95
strShipping = "Priority Mail"
Lines 1 through 20 store the name of each product and its price in the array we set up. They are set in their own elements. To picture this array, see below:
Name of object | Price of object |
Ludwig 5-Piece Beginners' Drum Set | 299.95 |
6-Piece Remo Masteredge Drumset | 2199.95 |
6-Piece DW Drumset | 2899.95 |
14-inch New Beat Zildjian Hi-Hat | 179.95 |
6-inch Zildjian Splash | 49.95 |
16-inch Zildjian Medium Crash | 189.95 |
18-inch Zildjian Medium Thin Crash | 199.95 |
7.5-inch LP Cowbell Supreme | 24.95 |
5B Woodtip Zildjian Drumsticks | 9.95 |
Vic Firth 2B Plastic Tip Drum Sticks | 11.95 |
Now that we have set up the array, we can start to use these objects.
For bytField = 0 To 9
If chkItem(bytField).Value = Checked Then
txtQuantity(bytField).Enabled = True
Else
txtQuantity(bytField).Enabled = False
txtQuantity(bytField).Text = ""
strCatalog(bytField, 2) = ""
strCatalog(bytField, 3) = ""
End If
Next bytField
Line 1: Begin For Next loop, looking at values 0 to 9
for the variable bytField.
Line 2: Test to see which checkbox is checked. Looks at all of them
because it searches indexes 0 through 9 as specified in line 1.
Line 3: When the loop finds a checkbox that is checked, enable the txtQuantity
text box with the same index value of the checkbox (index value of bytField).
Line 5: When the loop sees a checkbox that is not checked, disable the txtQuantity
text box with the same index value of the checkbox.
Line 6: Clear the text in the txtQuantity text box when the check
next to it is unchecked.
Lines 7 and 8 clear the array elements that were written to
(dimensions two and three).
Line 9 ends the If statement, and Line 10 increments the
loop to look at indexes up to nine.
Dim bytClear As Byte
For bytClear = 0 To 9
txtQuantity(bytClear).Text = ""
chkItem(bytClear).Value = Unchecked
strCatalog(bytClear, 2) = ""
strCatalog(bytClear, 3) = ""
Next bytClear
frmSummary.lblTotal(1).Caption = ""
lblProductTotal(1).Caption = ""
lblShipping(1).Caption = ""
lblOrderTotal(1).Caption = ""
sngTotal = 0
sngSubtotal = 0
mnuDisplay.Enabled = False
Line 1: Declare local variable bytClear as a Byte data-type
Line 2: Begin For Next loop, looking at values 0 through 9
for the variable bytClear.
Line 3: Clear the text box txtQuantity with index value of bytClear,
thus clearing all ten because the variable looks at values 0 through 9
as set in line 2.
Line 4: Uncheck the checkbox with an index value of bytClear,
which looks at 0 through 9, thus clearing all ten checkboxes
Line 5: Clear the text in dimension two of the array strCatalog.
Remember that the array is indexed 0 through 9. This element will
later store the quantity of the separate items.
Line 6: Clear the text in dimension three of the array strCatalog.
This element will later store the total cost of each separate item. Quantity of
the item times its unit cost.
Line 7: Increment the loop; go to the next value of the variable bytClear
up to 9.
Line 8: Clear the caption of the label lblTotal(1) on the form frmSummary.
Lines 9 through 11 clear the caption of the labels displaying the
totals on the current form (frmOrder).
Lines 12 and 13 reset the variable sngTotal, which is the
entire order total, and the variable sngSubtotal, which is the order
total before adding the shipping cost.
Line 14: Disable the menu item mnuDisplay to prevent the user from
viewing a blank order.
sngTotal = 0
sngSubtotal = 0
For bytField = 0 To 9
If chkItem(bytField).Value = Checked Then
strCatalog(bytField, 2) = txtQuantity(bytField).Text
strCatalog(bytField, 3) = Val(strCatalog(bytField, 1)) *
Val(txtQuantity(bytField).Text)
End If
sngSubtotal = sngSubtotal + Val(strCatalog(bytField, 3))
Next bytField
lblProductTotal(1).Caption = Format(sngSubtotal, "Currency")
lblShipping(1).Caption = Format(sngShipping, "Currency")
sngTotal = sngSubtotal + sngShipping
lblOrderTotal(1).Caption = Format(sngTotal, "Currency")
mnuDisplay.Enabled = True
Lines 1 and 2 reset the variables sngTotal and sngSubtotal
to 0 so that they are recalculated and not added to the previous value.
We should always do this just as good coding practice.
Line 3: Once again, look at bytField for values of 0 to 9.
Line 4: Check all the checkboxes (0 through 9) and test to see which ones
are checked.
Line 5: Store the text in txtQuantity (quantity of individual
items) in the array elements when the checkbox for that object is checked.
Line 6: Store the total price of each separate item (quantity of item
times its unit price) in the next (fourth --> number three) array element
with the same value of bytField.
Line 7: End the If statement.
Line 8: Set the variable sngSubtotal equal to itself plus the
value of all the data in the fourth element of the array (stores total price of
a separate product).
Line 9: Go to the next value of bytField in order to search all
checkboxes (indexed 0 through 9) and store them in the appropriate
cells of the array.
Line 10: Set the caption of the label lblProductTotal(1) to the
variable sngSubtotal, formatted as Currency (Dollars and cents).
Line 11: Set the caption of the label lblShipping(1) to the
variable sngShipping, formatted as Currency.
Line 12: Set the variable sngTotal equal to the value of sngSubtotal
(stores the total price of all the items together) plus the value of sngShipping.
Line 13: Set the caption of the label lblOrderTotal(1) to the
value of the variable sngTotal, formatted as Currency.
Line 14: Enable the menu item mnuStoreDisplay.
frmSummary.Show
For bytField = 0 To 9
If chkItem(bytField).Value = Checked Then
frmSummary.lstOrder.AddItem strCatalog(bytField, 0) + " " + "(" + strCatalog(bytField, 2) + ")" + " " + Format(strCatalog(bytField, 3),
"$0,0.00")
End If
Next bytField
Line 1: Display the form frmSummary.
Line 2: Look at values 0 through 9 for the variable bytField
(all the objects).
Line 3: Search for the checked checkboxes.
Line 4: When it finds a checked checkbox, add the item displayed in the
list box on the form frmSummary. It adds the data in array element strCatalog(bytField,
0), which stores the item name, then place a space, then a parenthesis,
then the data in the array element strCatalog(bytField, 2), which stores
the quantity of the corresponding item, then a parenthesis, then a space, then
the data in the array element strCatalog(bytField, 3), formatted as
currency ($0,0.00 is currency), which stores the total price of each
separate item in the array (quantity of item times its unit price).
Line 5: End the If statement.
Line 6: Increment the For Next loop.
This program should work nicely now. But what else could we do? As you know, when we take the value of a string that has a letter in it or not a number, we get zero. How about we do not allow the user to enter letters into the quantity text boxes?
Dim bytValidCharacters As Byte
bytValidCharacters = 1
If txtQuantity(Index).Text = "" Then Exit Sub
For bytField = 1 To Len(txtQuantity(Index).Text)
If InStr("1234567890", Mid(txtQuantity(Index).Text, bytField, 1)) Then bytValidCharacters = bytValidCharacters + 1
Next bytField
If bytValidCharacters <> bytField Then
MsgBox "Please enter numbers only", 16
txtQuantity(Index).SelStart = Len(txtQuantity(Index).Text) - 1
txtQuantity(Index).SelLength = 1
txtQuantity(Index).SelText = ""
End If
Line 1: Declare variable bytValidCharacters as a Byte.
We use this below just as a flag
Line 2: Set the variable bytValidCharacters to one.
Line 3: Exit the sub-procedure when the text in one of the text boxes is
empty. Because these text boxes are already indexed, we have a parameter
(argument) in the parenthesis that allows us to specify a specific value to (in
this case, one through nine). This line automatically looks at each text box and
tests the text in it. It will not execute any code when it sees that the text
box we are changing is empty. Remember that it looks at this value when we
change the text because we are using the Change event.
Line 4: Begin For Next loop, looking at bytField for values
of one to the length of the text in the txtQuantity text box being
changed (length returns a value, so the loop looks all the way to the end
character).
Line 5: Test the string txtQuantity(Index).Text for 1234567890,
or numbers, at however many places in according to the value of bytField
and look at one character. The variable bytField takes the place of the
character space, and this variable is incremented because it is the loops test
variable. As a result, this loop continues to look at the next character in the
string (looks at character 1 then 2 then 3 and so forth to
the value of the string's length). When there are numbers in the string, add one
to the variable bytValidCharacters. This variable acts as a flag to tell
us that all the characters are numbers. It increments by one just like the
loop's test expression, bytField (without a Step statement, For
Next loops increment plus one more by default).
Line 7: When bytValidCharacters is not equal to bytField,
execute the lines below (lines 8 through 11). Remember that both variables
increment by one.
Line 8: Display a message box to the user.
Line 9: Set the selection start of the text box the user is changing to
the Length of the text in the text box txtQuantity minus one.
Remember that the Len function returns a value, so this line simply moves
the cursor back one character.
Line 10: Set the selection length of the text box txtQuantity to
one to select one character. This selects the invalid character because the
cursor move one behind that character.
Line 11: Clear the selected text in the txtQuantity text box, thus
clearing the invalid character.
I hope that code was not too difficult to understand. I tried to simplify it. Now to finally finish this program.
Go to the form frmSummary.
Open the code window for the form's Load procedure.
Press tab, then type lblTotal(1).Caption = Format(sngTotal, "Currency").
Recall that sngTotal is the final order total, so we want to display it as currency in the total order cost label (lblTotal(1)).
Select the cmdDone object in the code window's object box.
Press tab, then type the following lines:
lstOrder.Clear
Unload frmSummary
You know what this code does I am sure! The reason though that we need to clear the list box lstOrder is because the other form adds the items to it regardless, so it just keeps adding them to the list. Just like resetting a label before we display a value.
Test the application if you would like. I hope that you enjoyed this lesson about arrays. Now you can move on to Page 26.