CASE STUDY: Working with Two Instances of the Same Form This case study demonstrates a practical use of the capability to create multiple instances of forms, as well as runtime switching of record sources. In the TimeTrack application, the various forms are not well integrated. For example, if the user opens both the Clients and Projects forms, they each show all records in their respective tables. But suppose you want to see just the projects for the current client? You can handle that by basing the Projects form on a query that draws a parameter from the Clients form. As an added twist, though, the code in this case study enables you to open as many of these client-specific project forms as you like. For starters, here's a query to grab the projects for the current client. To build this object, you can open a new query in Design view, switch to SQL view, and just type in the SQL: SELECT Projects.* FROM Projects WHERE (((Projects.ClientID)=[Forms]![Clients]![ClientID])) ORDER BY Projects.ProjectName; Save the query as qryprojectsForClient. The next step is to slightly modify the code behind the Projects form, by adding a new procedure: Public Sub LoadClient() ' Called by the client form to change ' the recordsource of this form Me.RecordSource = "qryProjectsForClient" Me.Refresh End Sub Remember, a public procedure of a class becomes a method of the class or in this case, of the form that's based on the class. This means that you can call the procedure from the Clients form, as you see in a moment. The Refresh method of a form tells it to refresh its records from the database. This is useful any time you change the form's RecordSource property and want to show the new data. With the changes to the Projects form saved, you can modify the Clients form. Add a new command button named cmdProject. Here's the code for this button: Dim arrProjectForms() As Form_Projects Dim intProjectFormsCount As Integer Private Sub cmdProject_Click() ' Open the project form, showing ' projects for the current client ' Add a new form variable to the array intProjectFormsCount = intProjectFormsCount + 1 ReDim Preserve arrProjectForms( _ 1 To intProjectFormsCount) ' Create the new form Set arrProjectForms(intProjectFormsCount) = _ New Form_Projects ' Tell it we're opening from here arrProjectForms(intProjectFormsCount).LoadClient ' And display the new instance arrProjectForms(intProjectFormsCount).Visible = _ True End Sub The first two declaration statements go in the module's Declarations section. This code shows how you can keep track of an arbitrary number of form variables: just put them in an array. Each time the user clicks the button, the code creates a new instance of the form and puts it in the array for safekeeping. It then calls the LoadClient method of the new form to set its RecordSource, and makes it visible. VBA array functions are covered in Chapter 7, "Working with Arrays," p. 105. Thus, you can show one client on the Clients form and use cmdProjects to open a form showing the projects for just that client. Then, without closing the first projects form, you can move to a different client and repeat the procedure to see the projects for the new client. Figure 10.8 shows the result, with two different client-specific project forms already open. Figure 10.8. Using multiple instances for child forms.
When you close the Clients form, the array goes out of scope. As a result, all the child Projects forms close too. |