REUSING FORMS TO PERFORM STANDARD TASKS WITH THE OPENARGS AND TAG PROPERTIES

When creating applications in a language that's pure code (such as C++), you want to design your code so that you can reuse it for a number of reasons, including the following:

  • The main code for the reusable routine must be written only once.

  • After the code is debugged, make sure only that the calling routine passes the correct parameters.

These two points are also true when you create reusable code in Access. In Access, you also can create reusable objects. The following example looks at a reusable form and VBA code. The form allows the user to search for customers or movie titles, depending on where the search form was called.

Note

The database for the rest of this chapter can be found on the accompanying CD-ROM in Chap09.mdb, located in the ExamplesChap09 folder.


Three forms—StandardSearch, CustomersSearchSubform, and MovieTitlesSearchSubform—make up the standard search form routines. The number of SearchSubform-named forms will grow as more areas need to have a search form used. In this case, let's stick with the two, Customers and Movie Titles. To see what you want to accomplish, look at Figure 9.7. You'll start off by working with the Customers form.

Figure 9.7. Look closely at these two search forms. Notice that the caption and the subform are the only things noticeably different.


By using the same form for different subjects, as in looking for customers or movie titles, you're also providing a consistent interface for your user. This is always desirable.

To look at the calling form side (the form that's initiating the opening of another form), look at two properties that Access provides for your purposes: OpenArgs and Tag.

The first property, OpenArgs, can't be accessed from Design mode. The OpenArgs property is set when a form is opened at runtime with the OpenForm method, off the DoCmd object.

Note

Before Access 95, DoCmd was a statement that you used for calling macro actions from Access Basic. As of Access 95, you can call the DoCmd object to perform the same actions as in prior versions. The DoCmd statement is changed to the DoCmd object when existing applications are converted to Access 97 and 2000.


The call to open the search form from the Customers form can be found in the event procedure attached to the OnClick event on the Search button. The routine in Listing 9.3 performs this call.

Listing 9.3. Chap09.mdb: Opening a Reusable Search Dialog
Private Sub Search_Click()
    On Error GoTo Error_Search_Click

    DoCmd.OpenForm "StandardSearch", acNormal, , , acNormal, _
                      acDialog, Me.Name

Exit_Search_Click:

    Exit Sub

Error_Search_Click:

    MsgBox Err.Description
    Resume Exit_Search_Click

End Sub

This routine will be the same whether it's called from the Customers or Movie Titles form. The portion of the code that makes it so versatile is the last parameter, Me.Name, found on the line containing DoCmd, where Name is the name property of the current form (Me). This parameter is the OpenArgs property and can be accessed from the form object that's being opened. Figure 9.8 shows the syntax for the OpenForm method off the DoCmd object, using the Object Browser.

Figure 9.8. The Object Browser is one of the best tools for examining the various objects, methods, and properties.


Follow these steps to view a complete list of methods of the DoCmd object in the Object Browser:

1.
While in any module in the VBE, press F2, click the Object Browser toolbar button, or open the View menu and choose Object Browser.

2.
Select Access from the Project/Libraries combo box.

3.
Select DoCmd from the objects in the Classes list.

You now see the complete list of methods for the DoCmd object in the Object Browser. (For complete information about the Object Browser, see Chapter 2, “Coding in Access 2000 with VBA.”)

By placing Me.Name in OpenArgs, you can copy and paste the Search control and its OnClick event procedure into other forms with no changes. The only other item you need to worry about setting up on the calling form side is the Tag property.

The Tag property is user-definable, which means that Access pays no attention to it whatsoever, and you get to use it however you want. What you'll use it for in this example is to keep track of the field on which you want the standard search routine to perform the lookup in the calling form's recordset. In the Customers form, the routine is called CustomerID. You can see how the Tag property is set in Figure 9.9.

Figure 9.9. You can use the Tag property to store any information you want.


You're now done setting up the calling form. Next, let's look at what makes up the standard search form, StandardSearch. In looking at the standard search form, you are brought back to the OpenArgs property, which the code in Listing 9.4 uses. In the OnLoad event of the StandardSearch form, set the Caption property to reflect the calling form, and set the SourceObject property for the subSearch subform control.

Listing 9.4. Chap09.mdb: Setting Form Properties at Runtime
Private Sub Form_Load()

    On Error GoTo Error_Form_Load

    Me.Caption = Forms(Me.OpenArgs).Caption & " " & Me.Caption

    Me!subSearch.SourceObject = Me.OpenArgs & "SearchSubform"

Exit_Form_Load:

    Exit Sub

Error_Form_Load:

    MsgBox Err.Description
    Resume Exit_Form_Load

End Sub

The Me.Caption line concatenates the caption of the calling form (Customers) with a space and the caption of the standard search form.

In the next line of code, the OpenArgs property of the calling form—in this case, Customers—is concatenated to the literal SearchSubform. This creates the complete name of the search subform, CustomersSearchSubform. It then assigns that to the SourceObject property of the SearchSubform subform control. You can see this subform control in Figure 9.10.

Figure 9.10. Initially, the SearchSubform subform control has no form assigned to its SourceObject property.


Note

The properties Link Child Fields and Link Master Fields aren't used. This means that you have a lot of power because the RecordSource property of the form is used as the subform—in this case, CustomerSearchSubform—linked to whatever control you want, if at all. This also allows you to be able to modify this link at any time during runtime. The Link Child Fields and Link Master Fields properties are two of the only ones that are limited to update only at the OnOpen event of a form.


This form has two other interesting procedures. The first one is attached to the OnClick event for each of the Letter command buttons and the AfterUpdate event of the SearchText text box. You can see the SearchText text box in Figure 9.10 (the Unbound control above the property sheet). The function attached to the OnClick event, ap_Requery_SearchSub(), is shown in Listing 9.5 and is in the StandardSearch form's code behind form.

Listing 9.5. Chap09.mdb: Requerying the StandardSearch Subform
Function ap_Requery_SearchSub()

    On Error GoTo Error_ap_Requery_SearchSub

    Select Case Screen.ActiveControl.Name
        Case "txtSearchText"
            Me.Tag = Me!txtSearchText
        Case "All"
            Me.Tag = ""
            Me!txtSearchText = ""
        Case Else
            Me.Tag = Screen.ActiveControl.Caption
            Me!txtSearchText = ""
    End Select
    Me!subSearch.Requery

Exit_ap_Requery_SearchSub:

    Exit Function

Error_ap_Requery_SearchSub:

    MsgBox Err.Description
    Resume Exit_ap_Requery_SearchSub

End Function

This routine assigns a value to the StandardSearch form's Tag property based on which control was used, in the following order:

  • The txtSearchText control

  • The All button

  • One of the Letter controls

The routine then requeries the subform control, subSearch. The value in the Tag property is used in the RecordSource property of the subform's SourceObject—in this case, CustomerSearchSubform.

The other routine mentioned is called from the subform as well. There are three main points of interest concerning the form used as the customer search subform. By using the CustomerSearchSubform form (see Figure 9.11), let's look at these points of interest in order:

  • The CustomerSearchSubform's RecordSource is set to the following SQL statement:

    Select CustomerID, FirstName, LastName from Customers where
    Customers.LastName like Forms!StandardSearch.Tag & "*"
    Order by LastName, FirstName;
    

    As you can see, this query refers to the Tag property on the StandardSearch main form. This statement will change to reflect the current subform recordset, but needs to compare the recordset's fields to the standard search form's Tag property. If used by the Movie Titles form, the statement looks like this:

    Select TitleNo, Title from MovieTitles where MovieTitles.Title
    like Forms!StandardSearch.Tag & "*" Order by Title;
    

    The key fields are included in the SQL statements, even though they aren't displayed.

  • The Control Source property of the ChoiceDisplay text box, also shown in Figure 9.11, is set to the expression

    ="  " & [LastName] & ",  " & [FirstName]
    
  • The OnDblClick event of the ChoiceDisplay text box and the OnClick event of the Choose command button both call the same subroutine from StandardSearch. Here's the event procedure for OnDblClick:

    Private Sub ChoiceDisplay_DblClick(Cancel As Integer)
    
        dummy = Me.Parent.ap_StandardSearchChoice()
    
    End Sub
    

Figure 9.11. CustomerSearchSubform displays the LastName and FirstName of customers for users to choose.


Note

You can now call subroutines located in one form from other forms. The preceding code calls the ap_StandardSearchChoice() function, which is located in the StandardSearch form's module. You can find this form on the CD-ROM in ExamplesChap09Chap09.mdb. For more information about calling routines in other forms, see Chapter 2.


Listing 9.6 shows the code for ap_StandardSearchChoice(). This routine clones the calling form's recordset, looks up the key value of the chosen value in the clone, and then sets the bookmark of the calling form to that record.

Listing 9.6. Chap09.mdb: Locating the Record for the Choice Made
Public Function ap_StandardSearchChoice()

      Dim frmCalling As Form        '-- Form that called Search Form
      Dim frmSearchSub As Form      '-- Search Form
      Dim dynCalling As Recordset   '-- Recordset Clone of Calling Form

      On Error GoTo Error_ap_StandardSearchChoice

      Set frmSearchSub = Forms!StandardSearch!subSearch.Form
      Set frmCalling = Forms(frmSearchSub.Parent.OpenArgs)
      Set dynCalling = frmCalling.RecordsetClone

      '-- Check to see if the search value is numeric or not.
      '-- Search in cloned recordset for chosen value.

      If VarType(dynCalling(frmCalling.Tag)) <> vbString Then
        dynCalling.FindFirst frmCalling.Tag & " = " & _
                                  frmSearchSub(frmCalling.Tag)
      Else
        dynCalling.FindFirst frmCalling.Tag & " = '" & _
                                  frmSearchSub(frmCalling.Tag) & "'"
      End If

      '-- If a record is found, set the bookmark of the calling form.

      If dynCalling.NoMatch Then
        MsgBox "An Error has occurred, No match record found!", 32, _
                  "Search Error!"
      Else
        frmCalling.Bookmark = dynCalling.Bookmark
      End If

      dynCalling.Close

      DoCmd.Close acForm, "StandardSearch"

Exit_ap_StandardSearchChoice:

    Exit Function

Error_ap_StandardSearchChoice:

    MsgBox Err.Description, vbCritical, "Search Error"
    Resume Exit_ap_StandardSearchChoice

End Function

Now that all the code has been created, if you want to have the search routine work for the Movie Titles form, you only have to do the following:

1.
Click the Forms tab in the database container.

2.
Select CustomersSearchSubform.

3.
Open the Edit menu and choose Copy.

4.
Open the Edit menu and choose Paste.

5.
Type MovieTitlesSearchSubform for the new form name.

6.
Open the new form (MovieTitlesSearchSubform) in Design mode by highlighting it and clicking the Design button.

7.
Change the RecordSource property of MovieTitlesSearchSubform to reflect the desired data:

Select TitleNo, Title from MovieTitles where MovieTitles.Title
like Forms!StandardSearch.Tag & "*" Order by Title;

8.
Change the DisplayChoice control's Control Source property to reflect the new display:

="  " & [Title]

9.
Set the Tag property of the Movie Title form to TitleNo.

10.
Copy the Search command button and the code attached to the OnClick event procedure over to the Movie Title form.

Caution

Code isn't copied automatically when you only copy a control from one form to another. You must copy and paste the code in the modules themselves. This can also be a problem if you rename controls after you have event procedures attached to them. You can re-attach event procedures by finding the code and renaming the procedure to match the new name of the object.


One technique demonstrated in this section was swapping in a form name into the SourceObject property of a subform. In this case, it was used to substitute the version of the search subform that was necessary for the subject being sought—Customers or Movie Titles. This technique is also used for swapping in pages used with the Tab control. The following section further discusses this technique.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.205.214