Objectives of the Week


List and Combo Boxes

List Box and Combo Box controls are Visual Basic form of an array. Standalone BASIC supports array structures, but Visual Basic implements arrays using these controls.

Arrays are data structures used for holding a list of related information. Your program can maintain these lists by adding and removing the entries stored, but also use them to allow a restricted list of values from which to choose.

Select the List and Combo Boxes from the Toolbox and draw the controls on the form as you do with most all VB controls.

ToolBox
  • A ListBox is an Array if Text Items
  • A ComboBox is a Combination of a ListBox and a TextBox

These controls share many of the same events, methods, and properties. But there are some significant differences between how they each function, depending on the style of their implementation.

List Box

    When the Checked Property is selected, the List Box acts more like a set of Option Buttons
    as only one item can be selected at a time.

Combo Box

 

List and Combo Boxes

 

Remember that what you do with arrays or any temporary storage medium is to put data in, and then refer to the data stored in the structure. The List and Combo Boxes share many Methods and Properties that provide allow these functions.

AddItem   ctrl.AddItem [,Position] Add an Item  at the end of the list, or at the specified position.
RemoveItem   ctrl.RemoveItem Position Remove an Item from the specified position
Clear   ctrl.Clear Empty the List or Combo Box

Visual Basic Arrays are Zero Based Arrays. This means that they are indexed starting with zero. If there are 5 entries in the array, they are numbered 0, 1, 2, 3, and 4.

So if I code:    ListBox.AddItem "New Item", 3
"New Item" will be placed in Position 3 (0, 1, 2, 3), or what we might think of as the 4th entry

Coding:     ListBox.RemoveItem 1
will remove the item in Position 1 (0,1), or what we might think of as the 2nd entry.

Here are a few List and Combo Box properties:

ListCount Contains the actual number of entries in the control.
If ctrl.ListCount contains a 5, there are 5 entries indexed 0, 1, 2, 3, 4
ListIndex Contains the number of the currently selected entry
If what we think of as the 3rd item has been selected, ListIndex will contain a 2 (0, 1, 2)
This property contains -1 when nothing has been selected from the list.
Text Contains the content of the currently selected item
Sorted Boolean. Will maintain the list in Sorted Order when set to True
MultiSelect Allows the control to have more than one entry selected at a time. If this is the case, ListIndex contains the last entry selected, and Text contains the content of the last entry selected.

The MultiSelect property can have three values. None, Simple and Extended.

List Property allows initialization of array items at design time and access to individual entries at run time.

To populate a List or Combo Box at design time, open the List Property and begin entering the content for each array element. Use CTRL-Enter to move to the next line.

At run time, any reference to an entry in the array requires that you specify what entry you want. You must supply an entry number. This number is often refereed to as an index or a subscript.

Both the List and Selected properties require an index.

List strItem = ctrl.List(i) Reference to a specific entry in the array
Selected If ctrl.Selected(i) Then .... A Boolean value describing the selection state of a specific entry in the array

The variable "i" is an Integer that contains the entry number.

The property ctrl.ListIndex contains the entry of the currently selected item so

will operate on the currently selected item, unless there is no item selected (ListIndex will be -1), and in that case, these instructions will fail with a run-time error.

More on processing the array entries after reviewing the Loop Controls


Looping

In general, we have three type of looping constructs available to us. These are implemented in various languages using a wide range of syntax that do not necessarily lend themselves to describing the actual loop construct.

While Loop Test at the Top 0 - N times
Until Loop Test at the Bottom 1 - N times
For Loop        Like a While Loop Fixed Number of Times

 Here is how VB implements each type of loop:

While Loop (Test at the Top)

Do While condition
     '  Body of the Loop
Loop
Do Until condition
     ' Body of the Loop
Loop

Until Loop (Test at the Bottom)             

Do
      ' Body of the Loop
Loop While condition
Do
      ' Body of the Loop
Loop Until condition

For Loop   

For i = intStart to intLimit [Step intStep]

Next i

The integer variables i, j, and k are acceptable conventions for use with For Loops so when you declare them, you don't need to use the int prefix. These variables should always be local to the event handler or procedure.

For Loop


Using Loops to Process List and Combos

In most situations, a List or Combo Box can be processed using this type of Loop construct:

For i = 0 to ctrl.ListCount - 1

Remember that the List and Combo Boxes are zero based.
When the ListCount property is 5, the entries are reference with index values from 0 to 4.
Referencing entry 5 will cause a run time error as there is no entry 5.

For i = 0 To List1.ListCount - 1
    If List1.Selected(i) = True Then
        Debug.Print "Item " & i & " is " & List1.List(i)
    End If
Next i

This example will display the contents and the index values for each selected item.

There are times when this method will not work. Specifically, when an item is removed from the list.
When an item is removed, it changes the value of ListCount.

For i = 0 To List1.ListCount - 1
    If List1.Selected(i) = True Then
        List1.RemoveItem(i)
    End If
Next i

This example will not function correctly when anything except the last item has been selected and removed.
This is a "bug" or a feature in how VB implements the For Loop.

In Visual Basic, the limit if the For Loop is established during the initialization step. So if the ListCount is 5, the loop will repeat 5 times. When an item is removed from the array, the value if ListCount (the upper bound of the array) is changed. perhaps to 4, and when the 5th pass through the array takes place, the reference is "out of bounds" and the result is a run time error.

Here is one way around this feature:

For i = List1.ListCount - 1 to 0 Step -1
    If List1.Selected(i) = True Then
        List1.RemoveItem(i)
    End If
Next i

Starting at the end and working back toward the top works around that problem.


Examples of List / Combo Box Operations


Message and Input Boxes

A Message Box is a fast and easy (and annoying) way to provide the user with immediate feedback from with your program. Often, this feedback is in response to data entry type errors. Up to this point, the response was to simply let them know there was a problem, and send them back to the program so they could correct the situation and retry. "OK" was the only practical response to these situations.

The MessageBox function allows you to examine the users response and take appropriate requested action.

intResponse = MsgBox("Message",Icon+Buttons,"Title")
If intResponse = vbCancel
    ' Take the appropriate action

The response codes are based on the button codes used in the MessageBox function.

Button Code:        vbAbortRetryIgnore
Response Codes:  vbAbort, vbRetry, vbIgnore

 

The InputBox functions much like the Message Box and is used to prompt the user for input

strItem = InputBox("Enter a new item", "New Item", strDefault)

InputBox

If the user clicks on cancel, the Null String is returned to the program,
otherwise, whatever is in the input area is assigned to strItem.

Important to take some care in verifying that what the user entered is correct.
Here is a very basic example checking for the Cancel button and determining if the default value was changed.

This also includes an example of checking the return value from the MsgBox function.

strItem = InputBox("Enter a new item", "New Item", strDefault)

If strItem = strDefault Then
    intResponse = MsgBox("Accept the default name?", _
                                    vbQuestion + vbYesNo, _
                                        "Just Double Checking")
    If intResponse = vbNo Then
        Exit Sub
    End If
End If

If strItem = "" Then        ' User clicked on Cancel
        Exit Sub
End If


String Manipulation Functions

Left   Left Substring strTemp =  Left(strSource,Number of Bytes)
Left("ABCDEF",3) returns "ABC"
Right   Right Substring strTemp = Right(StrSource,Number of Bytes)
Right("ABCDEF",4) returns "CDEF"
Mid   Middle Substring strTemp = Mid(StrSource,Begin Position, Number of Bytes)
Mid("ABCDEF",2,3) returns BCD
Mid("ABCDEF",2) returns BCDEF
Len   Length of String l = Len(String)
Len("ABCDEF") returns 6
InStr   Search a String p = InStr(Start Position (starts with 1), Search String, Target String (often a literal))
InStr(2,"ABCDEF","D") returns a 4

The string functions are necessary to pick apart the pieces of a larger string. You can use InStr to look for occurrences of spaces or commas or other control/format characters used as delimiters in the larger string.

Here is an example of some code that pulls out City, State and Zip from a string. The CSZ string must be in the format:
City - Comma - Space - State Abbreviation - Space - Zip Code.

It wouldn't take much to convert this code to use the comma between City and State as a delimiter. This would allow the full state name in the format and not just the abbreviation.

Private Sub cmdConvert_Click()
    Dim p As Integer
    Dim intSaveP As Integer

    Dim strTemp As String

    strTemp = txtCSZ.Text
    ' Look for the last space
    p = 1
    Do
        intSaveP = p
        p = InStr(p + 1, strTemp, " ")
    Loop Until p = 0

    lblZip.Caption = Mid(strTemp, intSaveP + 1)

    strTemp = Left(strTemp, intSaveP - 1)

    ' Look for the last space AGAIN
    p = 1
    Do
        intSaveP = p
        p = InStr(p + 1, strTemp, " ")
    Loop Until p = 0

    lblState.Caption = Mid(strTemp, intSaveP + 1)
    lblCity.Caption = Left(strTemp, intSaveP - 2)

End Sub
Parse

Printing

The Printer Object represents your workstation printer. In fact, you can set the Printer Object using the ShowPrinter Common Dialog method.  Using the Print method and a number of formatting instructions, you can construct nicely formatted print reports from your Visual Basic application.

The Print command is the instruction that will write the output to the printer device. This instruction has a number of format and control characters associated with it.

A Comma tells Print to jump to the next tab setting

A SemiColon tells Print not to append any control character

A Print statement with no punctuation tells Print to generate a CR/LF

Printer.Print "Name",
Printer.Print "Address"

will print Name,  followed by a Tab, followed by Address, followed by a CR/LF

Print "Name";"Address" will print NameAddress
where
Print "Name","Address" will print Name    Address

Tab(n)   Absolute Column Position  
Spc(n)   Absolute Number of Spaces
Printer.New Page Send a FormFeed and Begin a new Page
Printer.End Doc   Send a FormFeed. This will complete your print job

You can also change the Font and Color properties of the Printer to suit your particular formatting needs.


Printing to a Form

Rather than route every summary or print request to a print device, a formatted report can be built on the form in much the same way a printed report is constructed.The Form Object shares many of the print related methods that the Printer Object supports.

The main form contains a "Print" button that will send a generated report to the printer. In class, you can provide a form that will provide the same function and not waste paper and tie up the printer.

In FormActivate you can code the same instructions for the Form Object that you would with the Printer Object and send a formatted report to a second form in the project. The Form and Printer Objects are not 100% compatible, but this is often a good method to get a majority of the formatting complete without waiting on the printer.

Here is a snippit of code that can be used to write to the "Background" of a form. This report can refer to the same controls on the main form as when you generate the report on the printer. There is no Printer.CLS method, but there is a NewPage and EndDoc method that controls the paging on the printer.

The Print Method is not listed with the other Methods and Properties in the AutoList feature of VB. It is available though as the Print instruction defaults to the From Object.

Me.Cls
Me.Print

Me.Font.Name = "Courier New"
Me.Font.Size = 24

Me.ForeColor = vbBlue
Me.Print Tab(3); "Shipment Summary"
Me.ForeColor = lngDefaultColor

Me.Font.Size = 12
Me.Print
Me.Print Tab(5); "Item List"

For This Class
Whenever a program says write a report to the printer
make sure that you write it to a form instead.


Review an Example

Download Example and walkthru the code

This example makes use of Combo Boxes, Adding and Removing items from these controls, but also makes use of Multiple Forms and passing a ComboBox as a function argument.

Look at the Change event in frmAdd

If txtAdd = "" Then
    cmdAdd.Enabled = False
Else
    cmdAdd.Enabled = True
End If

This code prevents the user from putting bad data in the ComboBox because the Add Function is disabled when the TextBox is empty. This is a better technique that simple editing the input and responding with an error message.

This code adds an entry to a ComboBox Object that refers to the selected "Real" control from the Main Form. This type of coding reduces the duplicate code that might be necessary to support all three Combo Boxes

' A control as a variable
' Use the Set command to refer to the object
Dim cComboBox As ComboBox

If optDDC.Value = True Then
    Set cComboBox = frmMain.cboDropdown

ElseIf optSC.Value = True Then
    Set cComboBox = frmMain.cboSimple

ElseIf optDDL.Value = True Then
    Set cComboBox = frmMain.cboDropdownList

Else
    Exit Sub
End If

cComboBox.AddItem txtAdd
txtAdd = ""
txtAdd.SetFocus

The Main Form uses the same type of code to initialize the ComboBoxes when the application starts.


Build the Example

Step by Step through the Example                     

Make sure that you:


Lab 1 -From the Text - Page 284, VB Mail Order

Step by Step through the First Lab

Let me know when you are done and I will check you off as Complete

Lab 2  - From the Text - Page 285, VB Auto Center

You are on your own.


Assignment

Reading Assignment

Programming Assignment

As Always: The assignment is due before the start of class next week

Student Information Program

    Page 280, Problem 7.1

There is one change to this assignment. You must "print" the form information to a second form, nicely formatted. Do not route the output to the printer.

Here is a list of the Program Grading Criteria