Lab for Week 10 - Step by Step

 

Very Busy (VB) Mail Order


Collections and Customer Information

This example will gather information from the user and store it in a Collection.

Lab Project Perhaps the most important feature of this lab is the heirarchy or relationship between the components.

frmMain ONLY talks to frmCustomer
frmCustomer ONLY has knowledge of cCustomers (the Collection)
cCustomers ONLY works with cCustomer (the Member Class)

It is true that frmCustomer needs SOME knowledge of what goes into the Collection, but there is no direct connection between the two components.

 

 

The interface looks like this:

Lab Main Lab Cust

 

Here is the working example

 

The Main Form uses the services of the Customer Form and maintains its own user interface. The coding in frmMain is almost trivial.

Private Sub cmdAdd_Click()
    With frmCustomer
        .Action = "A"
        .Show vbModal
    End With

    lstCustomer.ListIndex = -1

End Sub

Private Sub cmdCount_Click()
    MsgBox "There are " & _

      frmCustomer.CustCount & _
      " customers."

End Sub

 

Private Sub cmdDisplay_Click()
    If lstCustomer.ListIndex <> -1 Then
        With frmCustomer
            .cmdCancel.Visible = False
            .Key = lstCustomer.List(lstCustomer.ListIndex)
            .Action = "D"
            .Show vbModal
        End With
        lstCustomer.ListIndex = -1
        frmCustomer.cmdCancel.Visible = True

    Else
        MsgBox "Please Select a Customer from the List", _

                                vbOKOnly, "Input Requested"

    End If

End Sub

Private Sub cmdRemove_Click()
    If lstCustomer.ListIndex <> -1 Then
        With frmCustomer
            .Key = lstCustomer.List(lstCustomer.ListIndex)
            .Action = "R"
            .Show vbModal
        End With
        lstCustomer.ListIndex = -1
    Else
        MsgBox "Please Select a Customer from the List", _

                            vbOKOnly, "Input Requested"
    End If

End Sub



The Customer Form contains three Form Properties and calls on the Collection Class services to Add to the Collection, Remove from the Collection, and Display an entry in the Collection. One of the properties queries for the Collection Count.As was mentioned previously, the separation in the responsibilities of each of the components is important and should be re-emphasized.

Private Sub DisplayData()
    With m_Customers(m_strKey)
        txtID.Text = .CustomerID
        txtLastName.Text = .LastName
        txtFirstName.Text = .FirstName
        txtAddress.Text = .Address
        txtCity.Text = .City
        txtState.Text = .State
        txtZipCode.Text = .ZipCode
    End With

End Sub
This code appears to consist of simple assignment statements (and that's what it is supposed to look like). The reference to a particular element in the Collection returns a member object and the following assignments call the Member Class Property Get Procedures

This will look particularly confusing when running under the debugger. It is often asked why this is not coded directly into the Customer Form, and the response is always that the design must support the separation of the components.

It's a design specification

 


The Collection Class must support the Add and Remove Methods, and the Item and Count Properties.

The Add looks complex, but each assignment calls the Porperty Set Procedures for the Member Class. Each of these procedures do nothing more than use the services of the Collection object that is built into Visual Basic.

Public Sub Add(ByVal strCustomerId As String, _
                                ByVal strLastName As String, _
                                ByVal strFirstName As String, _
                                ByVal strAddress As String, _
                                ByVal strCity As String, _
                                ByVal strState As String, _
                                ByVal strZipCode As String)


    ' Create the Customer that will be
    ' Added to the Customers Collection
    Dim NewCustomer As New cCustomer

    ' Each assignment will call the
    ' Property Let procedure in cCustomer
    ' as a reference is being made to NewCustomer
    With NewCustomer
        .CustomerID = strCustomerId
        .LastName = strLastName
        .FirstName = strFirstName
        .Address = strAddress
        .City = strCity
        .State = strState
        .ZipCode = strZipCode

        ' Add it to the Collection
        ' Reference to .CustomerID is a call to
        ' the Property Get procedure
        m_Customers.Add NewCustomer, .CustomerID

    End With

End Sub

Public Sub Remove(ByVal strKey As String)
    m_Customers.Remove strKey

End Sub

Public Function Item(ByVal strKey As String) As cCustomer
    Set Item = m_Customers.Item(strKey)

End Function

Public Property Get Count() As Long
    Count = m_Customers.Count

End Property


And finally, the Member Class is required only to provide Property Let and Property Set Procedures for each of the properties that the class exposes.

Private m_strCustomerID As String
Private m_strLastName As String
Private m_strFirstName As String
Private m_strAddress As String
Private m_strCity As String
Private m_strState As String
Private m_strZipCode As String


Understanding the layers at work here is the most important part of this lab. The project appears to be complex on the surface, but like many problems, breaking it down into components will make the design, coding, and support much easier.

This completes the lab

Back to Week 10