Hands-On 11: Using Activex Objects
Total Page:16
File Type:pdf, Size:1020Kb
Database Design 3 Hands-on Excercises
Hands-on 7: Using the Calendar Control
Using the Calendar Control to select a date
In this exercise you will use the Calendar Control to set the start and end dates for an orders report. The dates selected will be displayed in unbound text boxes and used as the parameters for the report.
Step 1: Add the calendar control to the form
Create a blank form in design view. Insert the calendar control either by clicking the More Controls in the Toolbox and selecting Calendar Control 11.0 or click Insert > ActiveX Control and select the calendar control from the list.
Fig. 11.1: Selecting the Calendar Control using the Toolbox.
Fig. 11.2: Selecting the Calendar Control from the Insert Menu
Set the Name property of the control to calSelectDate. You will use this name to refer to the control in the VBA code you will write later.
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 1 of 9 Database Design 3 Hands-on Excercises
Fig. 11.3: Set Name Property for Calendar Control
Step 2: Add the date selection controls
This consists of two unbound text boxes – one to display the beginning date for the range of the report, the other the ending date – and a command button to allow the user to set each text box to the value selected on the calendar. Insert these controls on to your form. Set the Name property for each control so that you can refer to it in your code – e.g txtBeginDate, txtEndDate, cmdSetDate. Set the Caption property of the command button to “Set beginning date”. You will write code to set this caption in Step 3 below. Set the format property for the text boxes to Short Date. At this point your form should look like the screenshot below.
Fig. 11.4: Design view of form with date selection controls added
Step 3: Write the date selection code
You need to write two VBA procedures for this. The first is attached to the On Open Event Property of the form to set the button caption when the form opens. The second is attached to the On Click Event Property of the button and will set the text boxes to the value of the date selected on the calendar. The code you need to enter for each Event Property is given below: Private Sub Form_Open(Cancel As Integer) ' set button caption when form opens
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 2 of 9 Database Design 3 Hands-on Excercises
cmdSetDate.Caption = "Set beginning date" End Sub
Private Sub cmdSetDate_Click() If cmdSetDate.Caption = "Set beginning date" Then txtBeginDate = calSelectDate.Value cmdSetDate.Caption = "Set ending date" Else txtEndDate = calSelectDate.Value cmdSetDate.Caption = "Set beginning date" End If End Sub
How does the code work? When the form opens the Form_Open procedure sets the caption of the button to “Set beginning date”. The calendar control’s value property – calSelectDate.Value - is the date selected by the user on the calendar. The cmdSetDate_Click() procedure checks the button caption - cmdSetDate.Caption. If the caption is “Set beginning date” the procedure sets the text box for the beginning date to the date selected in the calendar and changes the button’s caption to “Set ending date”. If the button’s caption is “Set ending date”, the code sets the text box for the ending date to the date selected in the calendar and sets the button caption back to “Select beginning date”. To see the code in action, change to form view and try selecting a date in the calendar and setting the values in the text boxes.
Step 4: Create the orders report
Now that we are able to set the beginning and ending dates using the calendar we can use these dates to set the range for an orders report. The report will show details of all orders placed between the beginning and ending dates the user sets on the form. An example of the initial report you could create is shown below. Note: You need to use the order form to enter a few orders so that there is some data to display on the report.
Fig. 11.5: Initial order listing report (example).
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 3 of 9 Database Design 3 Hands-on Excercises
The report gets order data from the Orders table and the Company table. It will list orders between the two dates selected on the form. To achieve this we need to base it on a parameter query.
Between [Forms]![frmPrintOrders]! [txtBeginDate] And [Forms]! [frmPrintOrders]![txtEndDate]
Fig. 11.6 Parameter query to list orders between specified dates Create a parameter query as shown in Fig 11.6. Note that the parameter expression set for the Date field takes its values from the text boxes on the Print Orders form. Once you have created the query you can run it to test that it works as expected. You will need to have the form open and have selected suitable dates. What happens if you try to run the query when the form is not open? Once you are happy with the query, create a report based on it. (You can use the Wizard for this.) To display the beginning and ending dates in the header (see Fig. 11.5 above) you need to add text boxes set to the value of the text box on the form - e.g. =[Forms]![frmPrintOrders]! [txtBeginDate]. Test the report with the form open and suitable dates selected. (If the form is closed you will get the same problem as when you tried to run the query with the form closed.)
Step 5: Add buttons to run the report from the form
To complete the order listing process you need to add buttons to the form that will allow the user to Preview or Print the order listing report for the specified date range or to cancel the report and close the form. Add the Preview and Print command buttons and set their Name property – e.g. cmdPrev, cmdPrint. The code for the Preview button is shown below. Private Sub cmdPrev_Click() Dim strRptName As String strRptName = "rptOrders" DoCmd.OpenReport strRptName, acViewPreview End Sub
Make sure that you use the name you have given to the report you created in your database! The first argument to the DoCmd.OpenReport method is the report name and the second is the view in which we want to open the report. The code for the print button will be exactly the same except that the view will need to be set to acViewNormal. This is the default value for the View argument and prints the report directly. As it is the default, you can omit the argument and the report will still be printed. 0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 4 of 9 Database Design 3 Hands-on Excercises
The cancel button will simply close the form. The VBA command to do this is DoCmd.Close. You can either write your own procedure or use the Wizard for this. The advantage of using the Wizard is that it will automatically add error handling code for you. Test that the buttons work as you expect.
Step 6: Add error handling
The form should now work to preview or print the orders report but there are several things that could go wrong. . The user might click the print or preview button without selecting the dates or when only the start date has been selected. . The user might select an ending date that is earlier than the starting date. . There might be no orders to display in the range of dates selected. . Someone might attempt to open the report without using the form – e.g. directly from the database window (although we would normally expect this to be hidden from users) or by adding a button to a menu form. As designers we need to anticipate problems such as these (there might be others that you can think of) and build in code to handle them.
Checking for valid date entry The first two possibilities outlined above can be dealt with by adding code to the Preview/Print button event handlers. The code highlighted below shows the additional code that you need to add to the cmdPrev_Click Event procedure. The same code also needs to be added to the code for the print button. Private Sub cmdPrev_Click() ' check that end date is > begin date If txtEndDate < txtBeginDate Then MsgBox "The ending date must be later than the beginning date" cmdSetDate.Caption = "Set ending date" calSelectDate.SetFocus Exit Sub End If ' check that value entered for begin date If IsNull(txtBeginDate) Then MsgBox "You must enter a beginning date" cmdSetDate.Caption = "Set beginning date" calSelectDate.SetFocus Exit Sub End If ' check that value entered for end date If IsNull(txtEndDate) Then MsgBox "You must enter an ending date" cmdSetDate.Caption = "Set ending date" calSelectDate.SetFocus Exit Sub End If Dim strRptName As String strRptName = "rptOrders" DoCmd.OpenReport strRptName, acViewPreview End Sub
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 5 of 9 Database Design 3 Hands-on Excercises
How does this code work? The first If statement checks whether the ending date is earlier than the starting date. If it is the message box informs the user of the problem and the form is set for the selection of the ending date with the focus set to the calendar control ready for the user to make a selection. The next two if statements check whether there is a value in the date selection text boxes using IsNull which will be True if the text box is empty. Note that three separate if statements are used rather than If ... Else. This is because the procedure will end if any one of the statements is True and the following statements will therefore be ignored.
Checking that there is data to display in the report We can use the No Data event of the report to cancel the report in this case. This code is similar to the code you wrote in Hands-on 9. Private Sub Report_NoData(Cancel As Integer) Cancel = MsgBox("No orders to display in range specified. Cancelling report...", _ vbInformation, _ Me.Caption) End Sub
However, there’s a problem. When we try to preview the report the message pops up but the DoCmd statement in the cmdPrev_Click() code still attempts to run and generates an error. To ensure this doesn’t happen we need to add error handling code to cmdPrev_Click() as shown below. (The lines you need to add to the existing code are highlighted.
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 6 of 9 Database Design 3 Hands-on Excercises
Private Sub cmdPrev_Click() On Error GoTo Err_cmdPrev_Click ' check that end date is > begin date If txtEndDate < txtBeginDate Then MsgBox "The ending date must be later than the beginning date" cmdSetDate.Caption = "Set ending date" calSelectDate.SetFocus Exit Sub End If ' check that value entered for begin date If IsNull(txtBeginDate) Then MsgBox "You must enter a beginning date" cmdSetDate.Caption = "Set beginning date" calSelectDate.SetFocus Exit Sub End If ' check that value entered for end date If IsNull(txtEndDate) Then MsgBox "You must enter an ending date" cmdSetDate.Caption = "Set ending date" calSelectDate.SetFocus Exit Sub End If Dim strRptName As String strRptName = "rptOrders" DoCmd.OpenReport strRptName, acViewPreview Exit_cmdPrev_Click: Exit Sub
Err_cmdPrev_Click: Resume Exit_cmdPrev_Click End Sub
Note, the error handling in this code simply exits from the procedure. The message box generated by the report’s No Data event handler has already informed the user that the report is being cancelled. There is no need for an additional message in this code.
Prevent the report from being opened except via the form To prevent the report from being run from anywhere other than the List Orders form we will use the report’s On Open event to check whether the form is open. If it is not we will give the user the option to open the form or cancel the report. To check whether the form is open we will use a general purpose function FormIsLoaded. First add this function to the Utilities module. (If you have not yet created a Utilities module create a new standard module now and name it modUtilities.)
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 7 of 9 Database Design 3 Hands-on Excercises
Public Function FormIsloaded(strFrmName As String) As Boolean Const conFormDesign = 0 Dim intI As Integer FormIsloaded = False For intI = 0 To Forms.Count - 1 If Forms(intI).FormName = strFrmName Then If Forms(intI).CurrentView <> conFormDesign Then FormIsloaded = True Exit Function End If End If Next End Function
How does this code work? The function takes a form name as its argument and returns a value of true if the form is open and false if it is not. The constant conFormDesign is set to 0 which is the value for a form’s design view. The integer intI is a loop variable that we will use to loop through the forms in the database’s forms collection. The return value of the function is initially set to false. This value is reset to True inside the loop if the form is open. The loop iterates over the forms collection and compares each name with the names of the forms that are currently open. If it finds a match the function exits with the value True. We can now call this function from the On Open event handler for the report. Add the following code to the report’s class module. Private Sub Report_Open(Cancel As Integer)
If Not FormIsloaded("frmPrintOrders") Then
Cancel = MsgBox("To preview or print this report you need to select dates from the Print Orders form. Open form?", vbOKCancel, Me.Caption)
If Cancel = vbOK Then DoCmd.OpenForm "frmPrintOrders" End If End If End Sub
How does this code work? It calls the FormIsLoaded function and checks the return value. If this is False (the form is not currently open) the open event is cancelled. The message box has an OK and Cancel button. The procedure checks which button the user has clicked. If they have clicked OK it opens the form so that dates can be selected. If they have clicked cancel the report is simply cancelled. Once you have added all the error handling code to your form, test that everything works as it should.
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 8 of 9 Database Design 3 Hands-on Excercises
Use the calendar control to select dates to be stored in the database
In the form you created above you used unbound text boxes and the dates selected from the calendar were not stored in your database. You can also use the calendar control as a bound control to insert date values into an underlying database field. You can try this out using the employee form. Open the employee form in Design View and add a calendar control. Set the Control Source Property to the value of the employee start date field. The drop down list will list all the fields available in the form’s underlying data source. The control source must be one of these fields.
Fig. 11.7: Set Control Source property of Calendar control.
Once you have set the Control Source the calendar is bound to the underlying field. Change to form view to see this in action.
Fig. 11.8: Bound calendar control.
Notice that the date selected on the calendar is the same as the date displayed in the Start Date text box. If you type a different date in the text box, the calendar will select the matching date. If you select a different date in the calendar, the date in the text box will change to match. You could replace the text box with the calendar control on this form. On this particular form it is probably easier for the user to simply type a date than it is for them to select from the calendar. However, there may be some situations where data entry is more convenient using the calendar control.
0ff41a6380e2e1e3ad52b264cbfbaa8d.doc Page 9 of 9