SlideShare a Scribd company logo
1 of 33
Download to read offline
Access Tutorial 15: Advanced Triggers
15.1 Introduction: Pulling it all                              How do I create an unbound combo box?
     together                                                  Can I implement the search capability using
In this tutorial, you will bring together several of the        Visual Basic?
skills you have learned in previous tutorials to imple-
ment some sophisticated triggers.                          15.3 Tutorial exercises

15.2 Learning objectives                                   15.3.1 Using a macro to run VBA code
                                                           There a some things that cannot be done using the
    How do I run VBA code using a macro?
                                                           Access macro language. If the feature you wish to
    How do I use the value in one field to                implement is critical to your application, then you
     automatically suggest a value for a different         must implement it using VBA. However, since it is
     field?                                                possible to call a VBA function from within a macro,
    How do I change the table or query a form is          you do not have to abandon the macro language
     bound to once the form is already created?            completely.
    What is the After Update event? How is it             In this section, you are going to execute the Param-
     used?                                                 eterTest subroutine you created in Section 12.3.6
                                                           from within a macro. Since the RunCode action of
    How do I provide a search capability for my
                                                           the Access macro language can only be used to exe-
     forms?

© Michael Brydon (brydon@unixg.ubc.ca)
Last update: 25-Aug-1997                                            Home     Previous     1 o f 33   Next
15. Advanced Triggers                                                                           Tutorial exercises

cute functions (not subroutines) you must do one of          'this function calls the
two things before you create the macro:                       ParameterTest subroutine
1. Convert ParameterTest to a function — you do              ParameterTest intStart, intStop
   this simply by changing the Sub at the start of the       ParameterTestWrapper = True
                                                              'return a value
   procedure to Function.
                                                             End Function
2. Create a new function that executes Parame-
                                                           • Call the function, as shown in Figure 15.1.
   terTest and call the function from the macro.
15.3.1.1 Creating a wrapper                                     Note that the return value of the function is
Since the second alternative is slightly more interest-         declared as an integer, but the actual assign-
ing, it is the one we will use.                                 ment statement is ParameterTestWrap-
  • Open your basTesting module from                            per = True. This is because in Access/
    Tutorial 12.                                                VBA, the constants True and False are
  • Create a new function called ParameterTest-                 defined as integers (-1 and 0 respectively).
    Wrapper defined as follows:                           15.3.1.2 Using the RunCode action
    Function                                               • Leave the module open (you may have to resize
      ParameterTestWrapper(intStart As                       and/or move the debug window) and create a
      Integer, intStop As Integer) As
                                                             new macro called mcrRunCodeTest.
      Integer



                                                                  Home      Previous     2 o f 33     Next
15. Advanced Triggers                                                                     Tutorial exercises


              FIGURE 15.1: Create a function that calls the ParameterTest subroutine.




   the ParameterTest
    Create a function to call

       subroutine.


       Since ParameterTest                                         invoke the function (do notto
                                                                    Use the Print statement
                                                                                                forget
       does not return a value, its                                    the parameters).
       arguments are not in
       brackets.
                                                                       The return value of
                                                                       ParameterTestWrapper()
                                                                       is True, so this is printed when
                                                                       the function ends.


                                                           Home       Previous     3 o f 33     Next
15. Advanced Triggers                                                                            Tutorial exercises

 • Add the RunCode action and use the expression         • Select Run  Start to execute the macro as
   builder to select the correct function to execute,      shown in Figure 15.3.
   as shown in Figure 15.2.
                                                        15.3.2 Using activity information to
      The expression builder includes two parame-              determine the number of credits
      ter place holders (intStart and
                                                        In this section, you will create triggers attached to the
      intStop) in the function name. These
                                                        After Update event of bound controls.
      are to remind you that you must pass two
      parameters to the ParameterTestWrap-              15.3.2.1 Scenario
      per() function. If you leave the place holders    Assume that each type of course activity is generally
      where they are, the macro will fail because       associated with a specific number of credits, as
      Access has not idea what intStart             shown below:
      and intStop refer to.
                                                                 Activity                       Credits
 • Replace the parameter place holders with two                   lecture                            3.0
   numeric parameters (e.g. 3 and 6). Note that in                  lab                              3.0
   general, the parameters could be field names or
                                                                  tutorial                           1.0
   any other references to Access objects contain-
                                                                 seminar                             6.0
   ing (in this case) integers.



                                                                  Home       Previous     4 o f 33         Next
15. Advanced Triggers                                                                    Tutorial exercises


              FIGURE 15.2: Use the expression builder to select the function to execute.


   action to the macro.
    Add a RunCode




                                                                       Note the intStart and
                                                                       intStop parameter place
                                                                       holders. These must be replaced
                                                                       with expressions that Access
                                                                       understands.


   downthe expression builder to drill in
    Use
          to the user-defined functions
       your database file.


                                                             Home    Previous     5 o f 33     Next
15. Advanced Triggers                                                                     Tutorial exercises

                                                   Assume as well that the number of credits for a par-
  FIGURE 15.3: Execute the RunCode macro.
                                                   ticular type of course is not cast in stone. As such,
                                                   the numbers given above are merely “default” val-
                                                   ues.
                                                   You want to use the default credit values when you
                                                   create a new course or modify an existing course.
                                                   However, the user may override this default if neces-
                                                   sary for a particular course. The basic requirement is
                                                   illustrated in Figure 15.4.
                                                   15.3.2.2 Designing the trigger
                                                   Based on the foregoing, the answer to the “what”

   parameter place
    Replace the                                    question is the following:
                                                   1. Look up the default number of credits associated
        holders.
                                                      with the course activity showing in the form’s
                                                      Activity field.
   the toolRun toStart (or press the ! icon in
    Select
             bar) execute the macro.
                                                   2. Copy this number into the Courses.Credits
                                                      field.




                                                            Home      Previous     6 o f 33     Next
15. Advanced Triggers                                                                         Tutorial exercises


                        FIGURE 15.4: Inserting a default value into a new record.



       Create a new record for a lecture-based             of creditsmacro to find the default number
                                                             Create a
                                                                       and copy the value it into the
        course: COMM 437: Database Technology                    Credits field.


                                                                Select “Lecture” from the list of list of
                                                                 course activities created in Tutorial 8.




        Since this is a new record, the default
        value of Credits (like any numeric
        field) is zero. You want to use the
        information you just specified in the               macrothe Activityvalue in the the
                                                             Once
                                                                   executes. The
                                                                                 field is updated,
        Activity field to automatically                          Credits field can be changed by the
        look up the correct default number of                    user.
        credits for a lecture course and insert
        it in the Credits field.


                                                              Home       Previous      7 o f 33     Next
15. Advanced Triggers                                                                        Tutorial exercises

There are several possible answers to the “when”        • Ensure that you have a courses form (e.g., frm-
question (although some are better than others). For      Courses) and that the form has a combo box for
example:                                                  the Activity field. You may wish to order the
1. When the user enters the Credits field (the On         fields such that Activity precedes Credits in
   Enter event for Credits) — The problem with            the tab order (as shown in Figure 15.4).
   this choice is that the user could modify the
                                                             If your move fields around, remember to
   course’s activity without moving the focus to the
                                                             adjust the tab order accordingly (recall
   Activity field. In such a case, the trigger would
                                                             Section 8.3.4).
   not execute.
2. When the user changes the Activity field (the       15.3.2.4 Looking up the default value
   After Update event for Activity) — This choice
                                                       As you discovered in Section 14.3.5, Access has a
   guarantees that whenever the value of Activ-
                                                       DLookUp() function that allows you to go to the
   ity is changed, the default value will be copied
                                                       Activities table and find the value of Credits
   into the Credits field. As such, it is a better
                                                       for a particular value of Activity. A different
   choice.
                                                       approach is to join the Activities table with the
15.3.2.3 Preliminary activities                        Courses table in a query so that the default value of
 • Modify the Activities table to include a single-    credits is always available in the form. This is the
   precision numeric field called Credits. Add the     approach we will use here.
   values shown in the table in Section 15.3.2.1.


                                                                Home      Previous    8 o f 33     Next
15. Advanced Triggers                                                                   Tutorial exercises

 • Ensure you have a relationship (in the main rela-
                                                       FIGURE 15.5: Use a join to make the default
   tionship window) between Courses.Activity
                                                                    value available.
   and Activities.Activity.
 • Create a new query called qryCoursesAnd-
   Credits based on the Courses and Activi-
   ties tables (see Figure 15.5).

      Notice that you have two credits fields:
      Courses.Credits (the actual number of
      credits for the course) and Activi-
      ties.Credits (the “default” or “suggested”
      number of credits based on the value of
      Activity). Access uses the table
      name.field name notation whenever a
      query contains more than one field with the
      same name.

Since you already have forms based on the
Courses table that expect a field called Credits
(rather than one called Courses.Credits), it is a


                                                            Home     Previous    9 o f 33     Next
15. Advanced Triggers                                                                        Tutorial exercises

good idea to rename the Activities.Credits
                                                           FIGURE 15.6: Rename one of the Credits fields.
field in the query. You do this by creating a calculated
field.
  • Rename Activities.Credits to Default-
    Credits as shown in Figure 15.6. Note that this
    eliminates the need for the table
    name.field name notation.
15.3.2.5 Changing the Record Source of the
         form
Rather than create a new form based on the qry-
CoursesAndCredits query, you can modify the
Record Source property of the existing frmCourses
form so it is bound to the query rather than the
Courses table.
  • Bring up the property sheet for the frmCourses
    form and change the Record Source property to
    qryCoursesAndCredits as shown in
    Figure 15.7.
                                                              table to DefaultCredits.Activities
                                                               Rename Credits form the



                                                                  Home     Previous   10 o f 33    Next
15. Advanced Triggers                                                                         Tutorial exercises

                                                        The advantage of using a join query in this manner is
   FIGURE 15.7: Change the Record Source
                                                        that DefaultCredits is now available for use
        property of an existing form.
                                                        within the form and within any macros or VBA mod-

    changeup the form’sSource property.
     Bring
            its Record
                         property list and              ules that run when the form is open.
                                                        15.3.2.6 Creating the SetValue macro
                                                        The SetValue macro you require here is extremely
                                                        simple once you have DefaultCredits available
                                                        within the scope of the form.
                                                          • Create the mcrCourses.SetCredits macro
                                                            as shown in Figure 15.8.
                                                        15.3.2.7 Attaching a procedure to the After
                                                                 Update event
                                                        The On Click event of a button is fairly simple to
                                                        understand: the event occurs when the button is
                                                        clicked. The events associated with non-button
                                                        objects operate in exactly the same way. For exam-
                                                        ple, the After Update event for controls (text box,
                      The field list now contains all
                      the fields in the new query.      combo box, check box, etc.) occurs when the value


                                                                 Home      Previous    11 o f 33    Next
15. Advanced Triggers                                                                             Tutorial exercises

                                                            • Attach the mcrCourses.SetCredits macro to
   FIGURE 15.8: Create the SetValue macro.
                                                              the After Update event of the Activity field.
                                                            • Verify that the trigger works properly.
   and a named macro called SetCredits.
    Create a macro group called mcrCourses
                                                           15.3.3 Use an unbound combo box to
                                                                  automate search
                                                           As mentioned in Tutorial 8, a combo box has no
                                                           intrinsic search capability. However, the idea of scan-
                                                           ning a short list of key values, selecting a value, and
                                                           having all the information associated with that record
                                                           pop on to the screen is so basic that in Access ver-
                                                           sion 7.0 and above, this capability is included in the
                                                           combo box wizard. In this tutorial, we will look at a
   or simplyuse the builder to set the arguments
    You can
              type in the names of the fields.
                                                           couple of different means of creating a combo boxes
                                                           for search from scratch.
of the control is changed by the user. As a result, the    15.3.3.1 Manual search in Access
After Update event is often used to trigger data verifi-   To see how Access searches for records, do the fol-
cation procedures and “auto-fill” procedures like the      lowing:
one you are creating here.                                   • Open your frmDepartments form.

                                                                    Home      Previous     12 o f 33    Next
15. Advanced Triggers                                                                         Tutorial exercises

 • Move to the field on which you want to search         • Set the Enabled property of DeptCode to No (the
   (e.g., DeptCode);                                       user should never be able to change the key val-
 • Select Edit  Find (or press Control-F);                ues of existing records).
 • Fill out the search dialog box as shown in           15.3.3.3 Creating the unbound combo box
   Figure 15.9.
                                                        The key thing to remember about the combo box
In the dialog box, you specify what to search for       used to specify the search criterion is that it has
(usually a key value) and specify how Access should     nothing to do with the other fields or the underlying
conduct its search. When you press Find First,          table. As such, it should be unbound.
Access finds the first record that matches your           • Create an unbound combo box in the form
search value and makes it the current record (note          header, as shown in Figure 15.10.
that if you are searching on a key field, the first       • Change the Name property of the combo box to
matching record is also the only matching record).          cboDeptCode.
15.3.3.2 Preliminaries                                    • The resulting combo box should resemble that
To make this more interesting, assume that the frm-         shown in Figure 15.11.
Departments form is for viewing editing existing
                                                               When you create an unbound combo box,
departmental information (rather than adding new
                                                               Access gives it a default name (e.g.,
departments). To enforce this limitation, do the fol-
                                                               Combo5). You should do is change this to
lowing:
                                                               something more descriptive (e.g., cboDept-
  • Set the form’s Allow Additions property to No.

                                                                 Home      Previous    13 o f 33    Next
15. Advanced Triggers                                                                    Tutorial exercises


                      FIGURE 15.9: Search for a record using the “find” dialog box.



   the field you wishtoto
    Move the cursor

        search and invoke
        the search box
        using Control-F.


   and setthe value you wish to find
    Enter
             the other search
        parameters as required.


       Limit the search to the current
        field (i.e., the field with the
        focus when the search box was
        opened).


   (or only) record thatmove to the first
    Press Find First to
                          matches the
        search condition.


                                                              Home     Previous   14 o f 33    Next
15. Advanced Triggers                                                                   Tutorial exercises


                                FIGURE 15.10: Create an unbound combo box.

   down themake roomfor the detail
    Drag
          to
             separator
                       in the form
        header


   selecting the combocombo boxand
    Create an unbound
                        box tool
                                 by

        clicking in the header area.


       Use the wizard in the usual way
        to get a list of valid DeptCode
        values and descriptions. The
        bound column for the combo box
        should be DeptCode.



   its value has to bebox is unbound,
    Since the combo
                        stored for later
        use rather than stored in a field.




                                                              Home    Previous   15 o f 33    Next
15. Advanced Triggers                                                                          Tutorial exercises

                                                         15.3.3.4 Automating the search procedure
    FIGURE 15.11: An unbound combo box.
                                                                  using a macro
                                                         When we implement search functionality with a
                                                         combo box, only two things are different from the
                                                         manual search in Figure 15.9:
                                                         1. the search dialog box does not show up, and
                                                         2. the user selects the search value from the combo
                                                            box rather than typing it in.
                                                         The basic sequence of actions, however, remains
        Although the DeptCode column has been            the same. As a result, the answer to the “what” ques-
        hidden, it is the “bound” column. As a result,
        the value of the combo box as it appears here    tion is the following:
        is “COMM”, not “Commerce and ...”                1. Move the cursor to the DeptCode field (this
                                                            allows the “Search Only Current Field” option to
     Code). The advantage of the prefix cbo is              be used, thereby drastically cutting the search
     that it allows you to differentiate between the        time).
     bound field DeptCode and the unbound                2. Invoke the search feature using the current value
     combo box.                                             of cboDeptCode as the search value.




                                                                  Home     Previous     16 o f 33    Next
15. Advanced Triggers                                                                     Tutorial exercises

3. Move the cursor back to cboDeptCode or some
                                                        FIGURE 15.13: Fill in the arguments for the
   other field.
                                                                  FindRecord action.
The only problem with this procedure is that the
DeptCode text box is disabled. As a result, you must
include an extra step at the beginning of the macro
                                                               mcrSearch.FindDepartment.
                                                                Create a named macro called

to set its Enabled property to Yes and another at the
end of the macro to return it to its original state.
  • Create a new macro called mcrSearch.Find-
    Department.
  • Use the SetValue action to set the Dept-
    Code.Enabled property to Yes. This can be
    done using the expression builder, as shown in
    Figure 15.12.
  • Use the GotoControl action to move the cursor                                       Since Value is
                                                                                        the default
    to the DeptCode text box. Note that this action                                     property, its use
    will fail if the destination control is disabled.                                   is optional.
  • Use the FindRecord action to implement the
    search as shown in Figure 15.13.
                                                         equalsthe action arguments. Dothe combo box.
                                                          Enter
                                                                 sign before the name of
                                                                                         not forget the



                                                              Home     Previous    17 o f 33    Next
15. Advanced Triggers                                                                  Tutorial exercises


              FIGURE 15.12: Use the builder to specify the name of the property to set.



   expressionItem argument, down
    To set the
               builder to drill
                                use the

       to the correct form.


       The middle pane shows all the
       objects on the form including
       labels and buttons (hence the
       need for a good naming
       convention).


   (cboDeptCode) from thebox
    Select the unbound combo
                             middle
       pane. A list of properties for the
       selected object is displayed in the
       pane on the right.




                                                            Home     Previous   18 o f 33    Next
15. Advanced Triggers                                                                       Tutorial exercises

      Access interprets any text in the Find What      15.3.4 Using Visual Basic code instead of
      argument as a literal string (i.e., quotation           a macro
      marks would not be required to find COMM). To    Instead of attaching a macro to the After Update
      use an expression (including the contents of a
                                                       event, you can attach a VBA procedure. The VBA
      control) in the Find What argument, you must
                                                       procedure is much shorter than its macro counter-
      precede it with an equals sign (e.g.,            part:
      =[cboDeptCode].
                                                       1. a copy (clone) of the recordset underlying the
 • You cannot disable a control if it has the focus.      form is created,
   Therefore, include another GotoControl action       2. the FindFirst method of this recordset is used
   to move the cursor to cboDeptCode before set-          to find the record of interest.
   ting DeptCode.Enabled = No.                         3. the “bookmark” property of the clone is used to
 • Attach the macro mcrSearch.FindDepart-                 move to the corresponding bookmark for the
   ment to the After Update event of the cboDept-         form.
   Code combo box.                                     To create a VBA search procedure, do the following:
 • Test the search feature.                             • Change the After Update event of cboDeptCode
                                                          to “Event Procedure”.
                                                        • Press the builder ( ) to create a VBA subrou-
                                                          tine.



                                                               Home      Previous    19 o f 33    Next
15. Advanced Triggers                                                              Application to the assignment

 • Enter the two lines of code below, as shown in          a non-human-readable data type and therefore is
   Figure 15.14.                                           not of much use unless it is used in the manner
   Me.RecordsetClone.FindFirst                             shown here. Setting the Bookmark property of a
      “DeptCode = ‘”  cboDeptCode  “'”                   record makes the record with that bookmark the
   Me.Bookmark =                                           current record. In the example above, the book-
      Me.RecordsetClone.Bookmark                           mark of the records underlying the form is set to
This program consists of a number of interesting ele-      equal the bookmark of the clone. Since the clone
ments:                                                     had its bookmark set by the search procedure,
 • The property Me refers to the current form. You         this is equivalent to searching the recordset
   can use the form's actual name, but Me is much          underlying the form.
   faster to type.
 • A form’s RecordsetClone property provides a           15.4 Application to the assignment
   means of referencing a copy of the form's under-
   lying recordset.                                      15.4.1 Triggers to help the user
 • The FindFirst method is straightforward. It            • Create a trigger on your order form that sets the
   acts, in this case, on the clone.                        actual selling price of a product to its default
 • Every recordset has a bookmark property that             price. This allows the user to accept the default
   uniquely identifies each record. A bookmark is           price or enter a new price for that particular trans-
   like a “record number”, except that it is stored as      action (e.g., the item could be damaged). You will


                                                                  Home      Previous     20 o f 33   Next
15. Advanced Triggers                                                      Application to the assignment


            FIGURE 15.14: Implement the search feature using a short VBA procedure.



                                                  referencethe After Update event to
                                                   Change
                                                              an event procedure.


                                                  editor.the builder button to invoke the VBA
                                                   Press



                                                     Access automatically names the
                                                      subroutine. Enter the two lines of code.




                                                         Home      Previous      21 o f 33       Next
15. Advanced Triggers                                                             Application to the assignment

   have to think carefully about which event to         Section 10.4). The problem is updating the Back-
   attach this macro to.                                Orders table itself because two different situations
 • Create a trigger on your order form that calcu-      have to be considered:
   lates a suggested quantity to ship and copies this   1. A record for the particular customer-product
   value into the quantity to ship field. The sug-         combination exists in the BackOrders table --
   gested value must take into account the amount          If a backorder record exists for a particular cus-
   ordered by the customer, any outstanding backo-         tomer and a particular product, the quantity field
   rders for that item by that customer, and the cur-      of the record can be added-to or subtracted-from
   rent quantity on hand (you cannot ship what you         as backorders are created and filled.
   do not have). The user should be able to override    2. A customer-product record does not exist in
   this suggested value. (Hint: use the MinValue()         the BackOrders table -- If the particular cus-
   function you created in Section 12.5.)                  tomer has never had a backorder for the product
 • Provide you customer and products forms with            in question, then there is no record in the Back-
   search capability.                                      Orders table to update. If you attempt to update
                                                           a nonexistent record, you will get an error.
15.4.2 Updating the BackOrders table
                                                        What is required, therefore, is a means of determin-
Once a sales order is entered into the order form, it   ing whether a record already exists for a particular
is a simple matter to calculate the amount of each      customer-product combination. If a record does
product that should be backordered (you did this in     exist, then it has to be updated; if a record does not


                                                                 Home      Previous     22 o f 33   Next
15. Advanced Triggers                                                             Application to the assignment

exist, then one has to be created. This is simple             (see Section 15.3.2.4 to review renaming
enough to talk about, but more difficult to implement         fields in queries).
in VBA. As a result, you are being provided with a
shortcut function called UpdateBackOrders()             Note that if the backordered quantity is positive,
that implements this logic.                             items are backordered. If the backordered quantity is
                                                        negative, backorders are being filled. If the backor-
The requirements for using the UpdateBackO-
                                                        dered quantity is zero, no change is required and
rders() function are outlined in the following sec-
                                                        these records should no be included in the results of
tions:
                                                        the query.
15.4.2.1 Create the pqryItemsToBackOrder
                                                        15.4.2.2 Import the shortcut function
         query
                                                        Import the Visual Basic for Applications (VBA) mod-
If you have not already done so, create the pqry-
                                                        ule containing the code for the
ItemsToBackOrder query described in
                                                        UpdateBackOrders() function. This module is
Section 10.4. The UpdateBackOrders() proce-
                                                        contained in an Access database called
dure sets the parameter for the query and then cre-
                                                        BOSC_Vx.mdb that you can download from the
ates a recordset based on the results.
                                                        course home page.
      If you did not use the field names OrderID,         • BOSC_V2.mdb is for those running Access ver-
      and ProductID in your tables, you must use            sion 2.0. To import the module, select File 
      the calculated field syntax to rename them


                                                                 Home      Previous    23 o f 33   Next
15. Advanced Triggers                                                                  Application to the assignment

   Import, choose BOSC_V2.mdb, and select Mod-               ers, and Products. If any of your tables or fields
   ule as the object type to import.                         are named differently, an error occurs. To eliminate
 • BOSC_V7.mdb is for those running Access ver-              these errors, you can do one of two of things:
   sion 7.0 or higher. To import the module, select          1. Edit the VBA code. Use the search-and-replace
   File  Get External Data  Import, choose                    feature of the module editor to replace all
   BOSC_V7.mdb, and select Module as the object                 instances of field names in the supplied proce-
   type to import.                                              dures with your own field names. This is the rec-
15.4.2.3 Use the function in your application                   ommended approach, although you need an
                                                                adequate understanding of how the code works
The general syntax of the function call is:
                                                                in order to know which names to change.
UpdateBackOrders(OrderID, CustomerID).
                                                             2. Change the field names in your tables (and all
The OrderID and CustomerID are arguments and                    queries and forms that reference these field
they both must be of the type Long Integer. If this             names). This approach is not recommended.
function is called properly, it will update all the backo-
rdered items returned by the parameter query.                15.4.3 Understanding the
15.4.2.4 Modifying the UpdateBackOrders()                           UpdateBackOrders() function
         function                                            The flowchart for the UpdateBackOrders() func-
The UpdateBackOrders() function looks for spe-               tion is shown in Figure 15.15. This function repeat-
cific fields in three tables: BackOrders, Custom-            edly calls a subroutine, BackOrderItem, which


                                                                      Home      Previous    24 o f 33   Next
15. Advanced Triggers                                                         Application to the assignment

updates or adds the individual items to the BackO-        FIGURE 15.15: Flowchart for
rders table. The flowchart for the BackOrderItem            UpdateBackOrders().
subroutine is shown in Figure 15.16.
There are easier and more efficient ways of imple-                   start

menting routines to update the BackOrders table.
Although some amount of VBA code is virtually inev-    run pqryItemsToBackOrder
                                                        to get list of items to backorder
itable, a great deal of programming can be elimi-
nated by using parameter queries and action
queries. Since queries run faster than code in                       is     yes
Access, the more code you replace with queries, the                the list     error message       stop
                                                                   empty?
better.
                                                                         no
      To get full marks for the backorders aspect of
      the assignment, you have to create a more               do until end of list
      elegant alternative to the shortcut supplied
      here.                                               call BackOrderItems
                                                       (CustID,ProductID,Qty)


                                                                     stop



                                                        Home        Previous         25 o f 33   Next
15. Advanced Triggers                                                          Application to the assignment


                       FIGURE 15.16: Flowchart for the BackOrderItem subroutine.


              start


   search BackOrders table for
  matching CustID  ProductID
                                                                         yes

                      yes                                    check Products table to
                                                             ensure valid ProductID
             found?          update Qty     stop

                  no                                                          no
     check Customer table to                                         valid?        error message     stop
       ensure valid CustID
                                                                         yes

                       no                                      add new record with
                                                            CustID, ProductID  Qty
             valid?         error message   stop


                                                                      stop



                                                            Home      Previous       26 o f 33     Next
15. Advanced Triggers                                                           Application to the assignment

15.4.4 Annotated source code for the                   MsgBox “Back order cannot be processed:
       backorders shortcut module.                      order contains no items”
                                                       Exit Sub
In the following sections, the two procedures in the
                                                       End If
shortcut module are examined. In each case, the
                                                       Do Until rsBOItems.EOF
code for the procedure is presented followed by
                                                       Call BackOrderItem(lngCustID,
comments on specific lines of code.
                                                        rsBOItems!ProductID, rsBOItems!Qty)
15.4.4.1 The UpdateBackOrders() function               rsBOItems.MoveNext
Function UpdateBackOrders(ByVal                        Loop
 lngOrdID As Long, ByVal lngCustID As                  rsBOItems.Close
 Long)                                                 End Function
Set dbCurr = CurrentDb
                                                       15.4.4.2 Explanation of the
Dim rsBOItems As Recordset
                                                                UpdateBackOrders() function
dbCurr.QueryDefs!pqryItemsToBackOrder.
 Parameters!pOrderID = lngOrdID                        Function UpdateBackOrders(ByVal lngOr-
Set rsBOItems =                                        dID As Long, ByVal lngCustID As Long) —
 dbCurr.QueryDefs!pqryItemsToBackOrder                 This statement declares the function and its parame-
 .OpenRecordset()                                      ters. Each item in the parameter list contains three
If rsBOItems.RecordCount = 0 Then                      elements: ByVal or ByRef (optional), the variable's
                                                       name, and the variable's type (optional). The ByVal


                                                                Home     Previous    27 o f 33   Next
15. Advanced Triggers                                                              Application to the assignment

keyword simply means that a copy of the variables        Dim rsBOItems As Recordset — In this decla-
value is passed the subroutine, not the variable         ration statement, a pointer to a Recordset object is
itself. As a result, variables passed by value cannot    declared. This recordset contains a list of all the
be changed by the sub-procedure. In contrast, if a       items to add to the BackOrders table.
variable is passed by reference (the default), its       dbCurr.QueryDefs!pqryItemsToBackOrder
value can be changed by the sub-procedure.               .Parameters!pOrderID = lngOrdID — This
Set dbCurr = CurrentDb — Declaring a vari-               one is a bit tricky: the current database (dbCurr)
able and setting it to be equal to something are dis-    contains a collection of objects called QueryDefs
tinct activities. In this case, the variable dbCurr      (these are what you create when you use the QBE
(which is declared in the declarations section) is set   query designer). Within the collection of QueryDefs,
to point to a database object. Note that the database    there is one called pqryItemsToBackOrder
object is not created, it already exists.                (which you created in Section 15.4.2.1).
CurrentDb is a function supported in Access ver-         Within every QueryDef, there is a collection of zero
sion 7.0 and higher that returns a reference to the      or more Parameters. In this case, there is one called
current database. In Access version 2.0, this function   pOrderID and this sets the value of the parameter
does not exist and thus the current database must        to the value of the variable lngOrderID (which was
be found by starting at the top level object in the      passed to the function as a parameter).
Access DAO hierarchy, as discussed in                    Set rsBOItems = dbCurr.QueryDefs!pqry-
Section 14.3.1.                                          ItemsToBackOrder.OpenRecordset() — Here


                                                                  Home      Previous    28 o f 33   Next
15. Advanced Triggers                                                               Application to the assignment

is another set statement. In this one, the variable      MsgBox “Back order cannot be processed:
rsBOItems is set to point at a recordset object.         order contains no items” — The MsgBox
Unlike the current database object above, however,       statement pops up a standard message box with an
this recordset does not yet exist and must be created    Okay button in the middle.
by running the pqryItemsToBackOrder parame-              Exit Sub — If this line is reached, the list contains
ter query.                                               no items. As such, there is no need to go any further
OpenRecordset is a method that is defined for            in this subroutine.
objects of type TableDef or QueryDef that creates an     End If — The syntax for If… Then… Else… state-
image of the data in the table or query. Since the       ments requires an End If statement at the end of
query in question is a parameter query, and since the    the conditional code. That is, everything between the
parameter query is set in the previous statement, the    If and the End If executes if the condition is true;
resulting recordset consists of a list of backordered    otherwise, the whole block of code is ignored.
items with an order number equal to the value of
                                                         Do Until rsBOItems.EOF — The EOF property
pOrderID.
                                                         of a recordset is set to true when the “end of file” is
If rsBOItems.RecordCount = 0 Then — The                  encountered.
only thing you need to know at this point about the
                                                         Call BackOrderItem(lngCustID, rsBOI-
RecordCount property of a recordset is that it returns
                                                         tems!ProductID, rsBOItems!Qty) — A sub-
zero if the recordset is empty.
                                                         routine is used to increase the modularity and



                                                                  Home       Previous     29 o f 33   Next
15. Advanced Triggers                                                          Application to the assignment

readability of this function. Note the way in which the    15.4.4.3 The BackOrderItem() subroutine
current values of ProductID and Qty from the               Sub BackOrderItem(ByVal lngCustID As
rsBOItems Recordset are accessed.                           Long, ByVal strProdID As String, ByVal
                                                            intQty As Integer)
rsBOItems.MoveNext — MoveNext is a method
                                                           Set dbCurr = CurrentDb
defined for recordset objects. If this is forgotten, the
                                                           Dim strSearch As String
EOF condition will never be reached and an infinite
                                                           Dim rsBackOrders As Recordset
loop will be created. In VBA, the Escape key is usu-
                                                           Set rsBackOrders =
ally sufficient to stop an infinite loop.
                                                            dbCurr.OpenRecordset(“BackOrders”,
Loop — All Do While/Do Until loops must end                 dbOpenDynaset)
with the Loop statement.                                   strSearch = “CustID = “  lngCustID  “
rsBOItems.Close — When you create a new                     AND ProductID = '  strProdID  “'”
object (such as a Recordset using the Open-                rsBackOrders.FindFirst strSearch
Recordset method), you should close it before exit-        If rsBackOrders.NoMatch Then
ing the procedure. Note that you do not close              Dim rsCustomers As Recordset
dbCurr because you did not open it.                        Set rsCustomers =
                                                            dbCurr.OpenRecordset(“Customers”,
End Function — All functions/subroutines need               dbOpenDynaset)
an End Function/End Sub statement.                         strSearch = “CustID = “  lngCustID
                                                           rsCustomers.FindFirst strSearch


                                                                 Home    Previous   30 o f 33   Next
15. Advanced Triggers                                              Application to the assignment

If rsCustomers.NoMatch Then               rsBackOrders!Qty = intQty
MsgBox “An invalid Customer ID number     rsBackOrders.Update
 has been passed to BackOrderItem”        Else
Exit Sub                                  rsBackOrders.Edit
End If                                    rsBackOrders!Qty = rsBackOrders!Qty +
Dim rsProducts As Recordset                intQty
Set rsProducts =                          rsBackOrders.Update
 dbCurr.OpenRecordset(“Products”,         End If
 dbOpenDynaset)                           End Sub
strSearch = “ProductID = '  strProdID
                                          15.4.4.4 Explanation of the BackOrderItem()
  “'”
                                                   subroutine
rsProducts.FindFirst strSearch
If rsProducts.NoMatch Then                Since many aspects of the language are covered in
MsgBox “An invalid Product ID number      the previous subroutine, only those that are unique
 has been passed to BackOrderItem”        to this subroutine are explained.
Exit Sub                                  Set rsBackOrders = dbCurr.OpenRecord-
End If                                    set(“BackOrders”, dbOpenDynaset) — The
rsBackOrders.AddNew                       OpenRecordset method used here is the one
rsBackOrders!CustID = lngCustID           defined for a Database object. The most important
rsBackOrders!ProductID = strProdID        argument is the source of the records, which can be


                                                   Home     Previous    31 o f 33   Next
15. Advanced Triggers                                                              Application to the assignment

a table name, a query name, or an SQL statement.        do this, single quotes are used within the search
The dbOpenDynaset argument is a predefined con-         string.
stant that tells Access to open the recordset as a      rsBackOrders.FindFirst strSearch —
dynaset. You don't need to know much about this         FindFirst is a method defined for Recordset
except that the format of these predefined constants    objects that finds the first record that meets the crite-
is different between Access version 2.0 and version     ria specified in the method's argument. Its argument
7.0 and higher. In version 2.0, constants are of the    is the text string stored in strSearch.
form: DB_OPEN_DYNASET.
                                                        If rsBackOrders.NoMatch Then — The
strSearch = “CustID = ” lngCustID  “                  NoMatch property should always be checked after
AND ProductID = ’”  strProdID  “'” —                  searching a record set. Since it is a Boolean variable
A string variable has been used to break the search     (True / False) it can be used without an comparison
process into two steps. First, the search string is     operator.
constructed; then the string is used as the parameter
                                                        rsBackOrders.AddNew — Before information can
for the FindFirst method. The only tricky part here
                                                        be added to a table, a new blank record must be cre-
is that lngCustID is a long integer and strProdID
                                                        ated. The AddNew method creates a new empty
is a string. The difference is that the value of str-
                                                        record, makes it the active record, and enables it for
ProdID has to be enclosed in quotation marks when
                                                        editing.
the parameter is passed to the FindFirst method. To




                                                                 Home       Previous     32 o f 33   Next
15. Advanced Triggers                                                Application to the assignment

rsBackOrders!CustID = lngCustID — Note
the syntax for changing a variable’s value. In this
case, the null value of the new empty record is
replaced with the value of a variable passed to the
subroutine.
rsBackOrders.Update — After any changes are
made to a record, the Update method must be
invoked to “commit” the changes. The AddNew /
Edit and Update methods are like bookends
around changes made to records.
rsBackOrders.Edit — The Edit method allows
the values in a record to be changed. Note that these
changes are not saved to the underlying table until
the Update method is used.




                                                        Home   Previous   33 o f 33   Next

More Related Content

What's hot

What's hot (20)

Command Design Pattern
Command Design PatternCommand Design Pattern
Command Design Pattern
 
4759826-Java-Thread
4759826-Java-Thread4759826-Java-Thread
4759826-Java-Thread
 
Swing
SwingSwing
Swing
 
Applet in java new
Applet in java newApplet in java new
Applet in java new
 
Command pattern
Command patternCommand pattern
Command pattern
 
System software - macro expansion,nested macro calls
System software - macro expansion,nested macro callsSystem software - macro expansion,nested macro calls
System software - macro expansion,nested macro calls
 
6. Compile And Run
6. Compile And Run6. Compile And Run
6. Compile And Run
 
Unit 7 Java
Unit 7 JavaUnit 7 Java
Unit 7 Java
 
Parameter Estimation User Guide
Parameter Estimation User GuideParameter Estimation User Guide
Parameter Estimation User Guide
 
CS844 U1 Individual Project
CS844 U1 Individual ProjectCS844 U1 Individual Project
CS844 U1 Individual Project
 
Command Pattern
Command PatternCommand Pattern
Command Pattern
 
10 strategy pattern
10 strategy pattern10 strategy pattern
10 strategy pattern
 
Multithreading in java
Multithreading in javaMultithreading in java
Multithreading in java
 
Monte -- machine learning in Python
Monte -- machine learning in PythonMonte -- machine learning in Python
Monte -- machine learning in Python
 
Java: GUI
Java: GUIJava: GUI
Java: GUI
 
Advance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWTAdvance Java Programming (CM5I) 1.AWT
Advance Java Programming (CM5I) 1.AWT
 
GUI components in Java
GUI components in JavaGUI components in Java
GUI components in Java
 
Java swing
Java swingJava swing
Java swing
 
Gui
GuiGui
Gui
 
04b swing tutorial
04b swing tutorial04b swing tutorial
04b swing tutorial
 

Viewers also liked (18)

Valjak 2
Valjak 2Valjak 2
Valjak 2
 
Maquillaje
MaquillajeMaquillaje
Maquillaje
 
зависне величине
зависне величинезависне величине
зависне величине
 
Relevankah partai islam
Relevankah partai islamRelevankah partai islam
Relevankah partai islam
 
Valjak
ValjakValjak
Valjak
 
Mhs5
Mhs5Mhs5
Mhs5
 
Trapez 1
Trapez 1Trapez 1
Trapez 1
 
Mnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglovaMnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglova
 
Matematika 8. preze.marko
Matematika 8.   preze.markoMatematika 8.   preze.marko
Matematika 8. preze.marko
 
Grafik funkcija
Grafik funkcijaGrafik funkcija
Grafik funkcija
 
Statistika prim.popo v ić
Statistika prim.popo v ićStatistika prim.popo v ić
Statistika prim.popo v ić
 
Mnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglovaMnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglova
 
Kviz Mnogougao
Kviz MnogougaoKviz Mnogougao
Kviz Mnogougao
 
Mnogougao
MnogougaoMnogougao
Mnogougao
 
Mnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglovaMnogougao,zbir spo.i unutr.uglova
Mnogougao,zbir spo.i unutr.uglova
 
Pravilni mnogouglovi
Pravilni mnogougloviPravilni mnogouglovi
Pravilni mnogouglovi
 
Grafik funkcija
Grafik funkcijaGrafik funkcija
Grafik funkcija
 
Valjak i kupa
Valjak i kupaValjak i kupa
Valjak i kupa
 

Similar to Trigger

Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooksSamundra khatri
 
How to build a react native app with the help of react native hooks
How to build a react native app with the help of react native hooksHow to build a react native app with the help of react native hooks
How to build a react native app with the help of react native hooksKaty Slemon
 
IRJET- Implementation and Unittests of AWS, Google Storage (Cloud) and Am...
IRJET-  	  Implementation and Unittests of AWS, Google Storage (Cloud) and Am...IRJET-  	  Implementation and Unittests of AWS, Google Storage (Cloud) and Am...
IRJET- Implementation and Unittests of AWS, Google Storage (Cloud) and Am...IRJET Journal
 
An Introduction To Unit Testing and TDD
An Introduction To Unit Testing and TDDAn Introduction To Unit Testing and TDD
An Introduction To Unit Testing and TDDAhmed Ehab AbdulAziz
 
Dependency injection using dagger2
Dependency injection using dagger2Dependency injection using dagger2
Dependency injection using dagger2Javad Hashemi
 
Implementing the Adapter Design Pattern
Implementing the Adapter Design PatternImplementing the Adapter Design Pattern
Implementing the Adapter Design PatternProdigyView
 
Java Static Factory Methods
Java Static Factory MethodsJava Static Factory Methods
Java Static Factory MethodsYe Win
 
Android App Development - 07 Threading
Android App Development - 07 ThreadingAndroid App Development - 07 Threading
Android App Development - 07 ThreadingDiego Grancini
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlabTarun Gehlot
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And RefactoringNaresh Jain
 
Fundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfFundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfStephieJohn
 
Progamming Primer Polymorphism (Method Overloading) VB
Progamming Primer Polymorphism (Method Overloading) VBProgamming Primer Polymorphism (Method Overloading) VB
Progamming Primer Polymorphism (Method Overloading) VBsunmitraeducation
 
Unit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfUnit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfKaty Slemon
 
Fundamental concepts of react js
Fundamental concepts of react jsFundamental concepts of react js
Fundamental concepts of react jsStephieJohn
 
Handout2.pdf
Handout2.pdfHandout2.pdf
Handout2.pdfShoukat13
 

Similar to Trigger (20)

Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 
How to build a react native app with the help of react native hooks
How to build a react native app with the help of react native hooksHow to build a react native app with the help of react native hooks
How to build a react native app with the help of react native hooks
 
IRJET- Implementation and Unittests of AWS, Google Storage (Cloud) and Am...
IRJET-  	  Implementation and Unittests of AWS, Google Storage (Cloud) and Am...IRJET-  	  Implementation and Unittests of AWS, Google Storage (Cloud) and Am...
IRJET- Implementation and Unittests of AWS, Google Storage (Cloud) and Am...
 
An Introduction To Unit Testing and TDD
An Introduction To Unit Testing and TDDAn Introduction To Unit Testing and TDD
An Introduction To Unit Testing and TDD
 
Dependency injection using dagger2
Dependency injection using dagger2Dependency injection using dagger2
Dependency injection using dagger2
 
Implementing the Adapter Design Pattern
Implementing the Adapter Design PatternImplementing the Adapter Design Pattern
Implementing the Adapter Design Pattern
 
Java Static Factory Methods
Java Static Factory MethodsJava Static Factory Methods
Java Static Factory Methods
 
Android App Development - 07 Threading
Android App Development - 07 ThreadingAndroid App Development - 07 Threading
Android App Development - 07 Threading
 
Introduction to matlab
Introduction to matlabIntroduction to matlab
Introduction to matlab
 
ACM init()- Day 4
ACM init()- Day 4ACM init()- Day 4
ACM init()- Day 4
 
Jmh
JmhJmh
Jmh
 
TDD And Refactoring
TDD And RefactoringTDD And Refactoring
TDD And Refactoring
 
Fundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfFundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdf
 
Progamming Primer Polymorphism (Method Overloading) VB
Progamming Primer Polymorphism (Method Overloading) VBProgamming Primer Polymorphism (Method Overloading) VB
Progamming Primer Polymorphism (Method Overloading) VB
 
Design Patterns
Design PatternsDesign Patterns
Design Patterns
 
MA3696 Lecture 9
MA3696 Lecture 9MA3696 Lecture 9
MA3696 Lecture 9
 
Unit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfUnit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdf
 
Fundamental concepts of react js
Fundamental concepts of react jsFundamental concepts of react js
Fundamental concepts of react js
 
Handout2.pdf
Handout2.pdfHandout2.pdf
Handout2.pdf
 
Unit testing
Unit testingUnit testing
Unit testing
 

Trigger

  • 1. Access Tutorial 15: Advanced Triggers 15.1 Introduction: Pulling it all How do I create an unbound combo box? together Can I implement the search capability using In this tutorial, you will bring together several of the Visual Basic? skills you have learned in previous tutorials to imple- ment some sophisticated triggers. 15.3 Tutorial exercises 15.2 Learning objectives 15.3.1 Using a macro to run VBA code There a some things that cannot be done using the How do I run VBA code using a macro? Access macro language. If the feature you wish to How do I use the value in one field to implement is critical to your application, then you automatically suggest a value for a different must implement it using VBA. However, since it is field? possible to call a VBA function from within a macro, How do I change the table or query a form is you do not have to abandon the macro language bound to once the form is already created? completely. What is the After Update event? How is it In this section, you are going to execute the Param- used? eterTest subroutine you created in Section 12.3.6 from within a macro. Since the RunCode action of How do I provide a search capability for my the Access macro language can only be used to exe- forms? © Michael Brydon (brydon@unixg.ubc.ca) Last update: 25-Aug-1997 Home Previous 1 o f 33 Next
  • 2. 15. Advanced Triggers Tutorial exercises cute functions (not subroutines) you must do one of 'this function calls the two things before you create the macro: ParameterTest subroutine 1. Convert ParameterTest to a function — you do ParameterTest intStart, intStop this simply by changing the Sub at the start of the ParameterTestWrapper = True 'return a value procedure to Function. End Function 2. Create a new function that executes Parame- • Call the function, as shown in Figure 15.1. terTest and call the function from the macro. 15.3.1.1 Creating a wrapper Note that the return value of the function is Since the second alternative is slightly more interest- declared as an integer, but the actual assign- ing, it is the one we will use. ment statement is ParameterTestWrap- • Open your basTesting module from per = True. This is because in Access/ Tutorial 12. VBA, the constants True and False are • Create a new function called ParameterTest- defined as integers (-1 and 0 respectively). Wrapper defined as follows: 15.3.1.2 Using the RunCode action Function • Leave the module open (you may have to resize ParameterTestWrapper(intStart As and/or move the debug window) and create a Integer, intStop As Integer) As new macro called mcrRunCodeTest. Integer Home Previous 2 o f 33 Next
  • 3. 15. Advanced Triggers Tutorial exercises FIGURE 15.1: Create a function that calls the ParameterTest subroutine. the ParameterTest Create a function to call subroutine. Since ParameterTest invoke the function (do notto Use the Print statement forget does not return a value, its the parameters). arguments are not in brackets. The return value of ParameterTestWrapper() is True, so this is printed when the function ends. Home Previous 3 o f 33 Next
  • 4. 15. Advanced Triggers Tutorial exercises • Add the RunCode action and use the expression • Select Run Start to execute the macro as builder to select the correct function to execute, shown in Figure 15.3. as shown in Figure 15.2. 15.3.2 Using activity information to The expression builder includes two parame- determine the number of credits ter place holders (intStart and In this section, you will create triggers attached to the intStop) in the function name. These After Update event of bound controls. are to remind you that you must pass two parameters to the ParameterTestWrap- 15.3.2.1 Scenario per() function. If you leave the place holders Assume that each type of course activity is generally where they are, the macro will fail because associated with a specific number of credits, as Access has not idea what intStart shown below: and intStop refer to. Activity Credits • Replace the parameter place holders with two lecture 3.0 numeric parameters (e.g. 3 and 6). Note that in lab 3.0 general, the parameters could be field names or tutorial 1.0 any other references to Access objects contain- seminar 6.0 ing (in this case) integers. Home Previous 4 o f 33 Next
  • 5. 15. Advanced Triggers Tutorial exercises FIGURE 15.2: Use the expression builder to select the function to execute. action to the macro. Add a RunCode Note the intStart and intStop parameter place holders. These must be replaced with expressions that Access understands. downthe expression builder to drill in Use to the user-defined functions your database file. Home Previous 5 o f 33 Next
  • 6. 15. Advanced Triggers Tutorial exercises Assume as well that the number of credits for a par- FIGURE 15.3: Execute the RunCode macro. ticular type of course is not cast in stone. As such, the numbers given above are merely “default” val- ues. You want to use the default credit values when you create a new course or modify an existing course. However, the user may override this default if neces- sary for a particular course. The basic requirement is illustrated in Figure 15.4. 15.3.2.2 Designing the trigger Based on the foregoing, the answer to the “what” parameter place Replace the question is the following: 1. Look up the default number of credits associated holders. with the course activity showing in the form’s Activity field. the toolRun toStart (or press the ! icon in Select bar) execute the macro. 2. Copy this number into the Courses.Credits field. Home Previous 6 o f 33 Next
  • 7. 15. Advanced Triggers Tutorial exercises FIGURE 15.4: Inserting a default value into a new record. Create a new record for a lecture-based of creditsmacro to find the default number Create a and copy the value it into the course: COMM 437: Database Technology Credits field. Select “Lecture” from the list of list of course activities created in Tutorial 8. Since this is a new record, the default value of Credits (like any numeric field) is zero. You want to use the information you just specified in the macrothe Activityvalue in the the Once executes. The field is updated, Activity field to automatically Credits field can be changed by the look up the correct default number of user. credits for a lecture course and insert it in the Credits field. Home Previous 7 o f 33 Next
  • 8. 15. Advanced Triggers Tutorial exercises There are several possible answers to the “when” • Ensure that you have a courses form (e.g., frm- question (although some are better than others). For Courses) and that the form has a combo box for example: the Activity field. You may wish to order the 1. When the user enters the Credits field (the On fields such that Activity precedes Credits in Enter event for Credits) — The problem with the tab order (as shown in Figure 15.4). this choice is that the user could modify the If your move fields around, remember to course’s activity without moving the focus to the adjust the tab order accordingly (recall Activity field. In such a case, the trigger would Section 8.3.4). not execute. 2. When the user changes the Activity field (the 15.3.2.4 Looking up the default value After Update event for Activity) — This choice As you discovered in Section 14.3.5, Access has a guarantees that whenever the value of Activ- DLookUp() function that allows you to go to the ity is changed, the default value will be copied Activities table and find the value of Credits into the Credits field. As such, it is a better for a particular value of Activity. A different choice. approach is to join the Activities table with the 15.3.2.3 Preliminary activities Courses table in a query so that the default value of • Modify the Activities table to include a single- credits is always available in the form. This is the precision numeric field called Credits. Add the approach we will use here. values shown in the table in Section 15.3.2.1. Home Previous 8 o f 33 Next
  • 9. 15. Advanced Triggers Tutorial exercises • Ensure you have a relationship (in the main rela- FIGURE 15.5: Use a join to make the default tionship window) between Courses.Activity value available. and Activities.Activity. • Create a new query called qryCoursesAnd- Credits based on the Courses and Activi- ties tables (see Figure 15.5). Notice that you have two credits fields: Courses.Credits (the actual number of credits for the course) and Activi- ties.Credits (the “default” or “suggested” number of credits based on the value of Activity). Access uses the table name.field name notation whenever a query contains more than one field with the same name. Since you already have forms based on the Courses table that expect a field called Credits (rather than one called Courses.Credits), it is a Home Previous 9 o f 33 Next
  • 10. 15. Advanced Triggers Tutorial exercises good idea to rename the Activities.Credits FIGURE 15.6: Rename one of the Credits fields. field in the query. You do this by creating a calculated field. • Rename Activities.Credits to Default- Credits as shown in Figure 15.6. Note that this eliminates the need for the table name.field name notation. 15.3.2.5 Changing the Record Source of the form Rather than create a new form based on the qry- CoursesAndCredits query, you can modify the Record Source property of the existing frmCourses form so it is bound to the query rather than the Courses table. • Bring up the property sheet for the frmCourses form and change the Record Source property to qryCoursesAndCredits as shown in Figure 15.7. table to DefaultCredits.Activities Rename Credits form the Home Previous 10 o f 33 Next
  • 11. 15. Advanced Triggers Tutorial exercises The advantage of using a join query in this manner is FIGURE 15.7: Change the Record Source that DefaultCredits is now available for use property of an existing form. within the form and within any macros or VBA mod- changeup the form’sSource property. Bring its Record property list and ules that run when the form is open. 15.3.2.6 Creating the SetValue macro The SetValue macro you require here is extremely simple once you have DefaultCredits available within the scope of the form. • Create the mcrCourses.SetCredits macro as shown in Figure 15.8. 15.3.2.7 Attaching a procedure to the After Update event The On Click event of a button is fairly simple to understand: the event occurs when the button is clicked. The events associated with non-button objects operate in exactly the same way. For exam- ple, the After Update event for controls (text box, The field list now contains all the fields in the new query. combo box, check box, etc.) occurs when the value Home Previous 11 o f 33 Next
  • 12. 15. Advanced Triggers Tutorial exercises • Attach the mcrCourses.SetCredits macro to FIGURE 15.8: Create the SetValue macro. the After Update event of the Activity field. • Verify that the trigger works properly. and a named macro called SetCredits. Create a macro group called mcrCourses 15.3.3 Use an unbound combo box to automate search As mentioned in Tutorial 8, a combo box has no intrinsic search capability. However, the idea of scan- ning a short list of key values, selecting a value, and having all the information associated with that record pop on to the screen is so basic that in Access ver- sion 7.0 and above, this capability is included in the combo box wizard. In this tutorial, we will look at a or simplyuse the builder to set the arguments You can type in the names of the fields. couple of different means of creating a combo boxes for search from scratch. of the control is changed by the user. As a result, the 15.3.3.1 Manual search in Access After Update event is often used to trigger data verifi- To see how Access searches for records, do the fol- cation procedures and “auto-fill” procedures like the lowing: one you are creating here. • Open your frmDepartments form. Home Previous 12 o f 33 Next
  • 13. 15. Advanced Triggers Tutorial exercises • Move to the field on which you want to search • Set the Enabled property of DeptCode to No (the (e.g., DeptCode); user should never be able to change the key val- • Select Edit Find (or press Control-F); ues of existing records). • Fill out the search dialog box as shown in 15.3.3.3 Creating the unbound combo box Figure 15.9. The key thing to remember about the combo box In the dialog box, you specify what to search for used to specify the search criterion is that it has (usually a key value) and specify how Access should nothing to do with the other fields or the underlying conduct its search. When you press Find First, table. As such, it should be unbound. Access finds the first record that matches your • Create an unbound combo box in the form search value and makes it the current record (note header, as shown in Figure 15.10. that if you are searching on a key field, the first • Change the Name property of the combo box to matching record is also the only matching record). cboDeptCode. 15.3.3.2 Preliminaries • The resulting combo box should resemble that To make this more interesting, assume that the frm- shown in Figure 15.11. Departments form is for viewing editing existing When you create an unbound combo box, departmental information (rather than adding new Access gives it a default name (e.g., departments). To enforce this limitation, do the fol- Combo5). You should do is change this to lowing: something more descriptive (e.g., cboDept- • Set the form’s Allow Additions property to No. Home Previous 13 o f 33 Next
  • 14. 15. Advanced Triggers Tutorial exercises FIGURE 15.9: Search for a record using the “find” dialog box. the field you wishtoto Move the cursor search and invoke the search box using Control-F. and setthe value you wish to find Enter the other search parameters as required. Limit the search to the current field (i.e., the field with the focus when the search box was opened). (or only) record thatmove to the first Press Find First to matches the search condition. Home Previous 14 o f 33 Next
  • 15. 15. Advanced Triggers Tutorial exercises FIGURE 15.10: Create an unbound combo box. down themake roomfor the detail Drag to separator in the form header selecting the combocombo boxand Create an unbound box tool by clicking in the header area. Use the wizard in the usual way to get a list of valid DeptCode values and descriptions. The bound column for the combo box should be DeptCode. its value has to bebox is unbound, Since the combo stored for later use rather than stored in a field. Home Previous 15 o f 33 Next
  • 16. 15. Advanced Triggers Tutorial exercises 15.3.3.4 Automating the search procedure FIGURE 15.11: An unbound combo box. using a macro When we implement search functionality with a combo box, only two things are different from the manual search in Figure 15.9: 1. the search dialog box does not show up, and 2. the user selects the search value from the combo box rather than typing it in. The basic sequence of actions, however, remains Although the DeptCode column has been the same. As a result, the answer to the “what” ques- hidden, it is the “bound” column. As a result, the value of the combo box as it appears here tion is the following: is “COMM”, not “Commerce and ...” 1. Move the cursor to the DeptCode field (this allows the “Search Only Current Field” option to Code). The advantage of the prefix cbo is be used, thereby drastically cutting the search that it allows you to differentiate between the time). bound field DeptCode and the unbound 2. Invoke the search feature using the current value combo box. of cboDeptCode as the search value. Home Previous 16 o f 33 Next
  • 17. 15. Advanced Triggers Tutorial exercises 3. Move the cursor back to cboDeptCode or some FIGURE 15.13: Fill in the arguments for the other field. FindRecord action. The only problem with this procedure is that the DeptCode text box is disabled. As a result, you must include an extra step at the beginning of the macro mcrSearch.FindDepartment. Create a named macro called to set its Enabled property to Yes and another at the end of the macro to return it to its original state. • Create a new macro called mcrSearch.Find- Department. • Use the SetValue action to set the Dept- Code.Enabled property to Yes. This can be done using the expression builder, as shown in Figure 15.12. • Use the GotoControl action to move the cursor Since Value is the default to the DeptCode text box. Note that this action property, its use will fail if the destination control is disabled. is optional. • Use the FindRecord action to implement the search as shown in Figure 15.13. equalsthe action arguments. Dothe combo box. Enter sign before the name of not forget the Home Previous 17 o f 33 Next
  • 18. 15. Advanced Triggers Tutorial exercises FIGURE 15.12: Use the builder to specify the name of the property to set. expressionItem argument, down To set the builder to drill use the to the correct form. The middle pane shows all the objects on the form including labels and buttons (hence the need for a good naming convention). (cboDeptCode) from thebox Select the unbound combo middle pane. A list of properties for the selected object is displayed in the pane on the right. Home Previous 18 o f 33 Next
  • 19. 15. Advanced Triggers Tutorial exercises Access interprets any text in the Find What 15.3.4 Using Visual Basic code instead of argument as a literal string (i.e., quotation a macro marks would not be required to find COMM). To Instead of attaching a macro to the After Update use an expression (including the contents of a event, you can attach a VBA procedure. The VBA control) in the Find What argument, you must procedure is much shorter than its macro counter- precede it with an equals sign (e.g., part: =[cboDeptCode]. 1. a copy (clone) of the recordset underlying the • You cannot disable a control if it has the focus. form is created, Therefore, include another GotoControl action 2. the FindFirst method of this recordset is used to move the cursor to cboDeptCode before set- to find the record of interest. ting DeptCode.Enabled = No. 3. the “bookmark” property of the clone is used to • Attach the macro mcrSearch.FindDepart- move to the corresponding bookmark for the ment to the After Update event of the cboDept- form. Code combo box. To create a VBA search procedure, do the following: • Test the search feature. • Change the After Update event of cboDeptCode to “Event Procedure”. • Press the builder ( ) to create a VBA subrou- tine. Home Previous 19 o f 33 Next
  • 20. 15. Advanced Triggers Application to the assignment • Enter the two lines of code below, as shown in a non-human-readable data type and therefore is Figure 15.14. not of much use unless it is used in the manner Me.RecordsetClone.FindFirst shown here. Setting the Bookmark property of a “DeptCode = ‘” cboDeptCode “'” record makes the record with that bookmark the Me.Bookmark = current record. In the example above, the book- Me.RecordsetClone.Bookmark mark of the records underlying the form is set to This program consists of a number of interesting ele- equal the bookmark of the clone. Since the clone ments: had its bookmark set by the search procedure, • The property Me refers to the current form. You this is equivalent to searching the recordset can use the form's actual name, but Me is much underlying the form. faster to type. • A form’s RecordsetClone property provides a 15.4 Application to the assignment means of referencing a copy of the form's under- lying recordset. 15.4.1 Triggers to help the user • The FindFirst method is straightforward. It • Create a trigger on your order form that sets the acts, in this case, on the clone. actual selling price of a product to its default • Every recordset has a bookmark property that price. This allows the user to accept the default uniquely identifies each record. A bookmark is price or enter a new price for that particular trans- like a “record number”, except that it is stored as action (e.g., the item could be damaged). You will Home Previous 20 o f 33 Next
  • 21. 15. Advanced Triggers Application to the assignment FIGURE 15.14: Implement the search feature using a short VBA procedure. referencethe After Update event to Change an event procedure. editor.the builder button to invoke the VBA Press Access automatically names the subroutine. Enter the two lines of code. Home Previous 21 o f 33 Next
  • 22. 15. Advanced Triggers Application to the assignment have to think carefully about which event to Section 10.4). The problem is updating the Back- attach this macro to. Orders table itself because two different situations • Create a trigger on your order form that calcu- have to be considered: lates a suggested quantity to ship and copies this 1. A record for the particular customer-product value into the quantity to ship field. The sug- combination exists in the BackOrders table -- gested value must take into account the amount If a backorder record exists for a particular cus- ordered by the customer, any outstanding backo- tomer and a particular product, the quantity field rders for that item by that customer, and the cur- of the record can be added-to or subtracted-from rent quantity on hand (you cannot ship what you as backorders are created and filled. do not have). The user should be able to override 2. A customer-product record does not exist in this suggested value. (Hint: use the MinValue() the BackOrders table -- If the particular cus- function you created in Section 12.5.) tomer has never had a backorder for the product • Provide you customer and products forms with in question, then there is no record in the Back- search capability. Orders table to update. If you attempt to update a nonexistent record, you will get an error. 15.4.2 Updating the BackOrders table What is required, therefore, is a means of determin- Once a sales order is entered into the order form, it ing whether a record already exists for a particular is a simple matter to calculate the amount of each customer-product combination. If a record does product that should be backordered (you did this in exist, then it has to be updated; if a record does not Home Previous 22 o f 33 Next
  • 23. 15. Advanced Triggers Application to the assignment exist, then one has to be created. This is simple (see Section 15.3.2.4 to review renaming enough to talk about, but more difficult to implement fields in queries). in VBA. As a result, you are being provided with a shortcut function called UpdateBackOrders() Note that if the backordered quantity is positive, that implements this logic. items are backordered. If the backordered quantity is negative, backorders are being filled. If the backor- The requirements for using the UpdateBackO- dered quantity is zero, no change is required and rders() function are outlined in the following sec- these records should no be included in the results of tions: the query. 15.4.2.1 Create the pqryItemsToBackOrder 15.4.2.2 Import the shortcut function query Import the Visual Basic for Applications (VBA) mod- If you have not already done so, create the pqry- ule containing the code for the ItemsToBackOrder query described in UpdateBackOrders() function. This module is Section 10.4. The UpdateBackOrders() proce- contained in an Access database called dure sets the parameter for the query and then cre- BOSC_Vx.mdb that you can download from the ates a recordset based on the results. course home page. If you did not use the field names OrderID, • BOSC_V2.mdb is for those running Access ver- and ProductID in your tables, you must use sion 2.0. To import the module, select File the calculated field syntax to rename them Home Previous 23 o f 33 Next
  • 24. 15. Advanced Triggers Application to the assignment Import, choose BOSC_V2.mdb, and select Mod- ers, and Products. If any of your tables or fields ule as the object type to import. are named differently, an error occurs. To eliminate • BOSC_V7.mdb is for those running Access ver- these errors, you can do one of two of things: sion 7.0 or higher. To import the module, select 1. Edit the VBA code. Use the search-and-replace File Get External Data Import, choose feature of the module editor to replace all BOSC_V7.mdb, and select Module as the object instances of field names in the supplied proce- type to import. dures with your own field names. This is the rec- 15.4.2.3 Use the function in your application ommended approach, although you need an adequate understanding of how the code works The general syntax of the function call is: in order to know which names to change. UpdateBackOrders(OrderID, CustomerID). 2. Change the field names in your tables (and all The OrderID and CustomerID are arguments and queries and forms that reference these field they both must be of the type Long Integer. If this names). This approach is not recommended. function is called properly, it will update all the backo- rdered items returned by the parameter query. 15.4.3 Understanding the 15.4.2.4 Modifying the UpdateBackOrders() UpdateBackOrders() function function The flowchart for the UpdateBackOrders() func- The UpdateBackOrders() function looks for spe- tion is shown in Figure 15.15. This function repeat- cific fields in three tables: BackOrders, Custom- edly calls a subroutine, BackOrderItem, which Home Previous 24 o f 33 Next
  • 25. 15. Advanced Triggers Application to the assignment updates or adds the individual items to the BackO- FIGURE 15.15: Flowchart for rders table. The flowchart for the BackOrderItem UpdateBackOrders(). subroutine is shown in Figure 15.16. There are easier and more efficient ways of imple- start menting routines to update the BackOrders table. Although some amount of VBA code is virtually inev- run pqryItemsToBackOrder to get list of items to backorder itable, a great deal of programming can be elimi- nated by using parameter queries and action queries. Since queries run faster than code in is yes Access, the more code you replace with queries, the the list error message stop empty? better. no To get full marks for the backorders aspect of the assignment, you have to create a more do until end of list elegant alternative to the shortcut supplied here. call BackOrderItems (CustID,ProductID,Qty) stop Home Previous 25 o f 33 Next
  • 26. 15. Advanced Triggers Application to the assignment FIGURE 15.16: Flowchart for the BackOrderItem subroutine. start search BackOrders table for matching CustID ProductID yes yes check Products table to ensure valid ProductID found? update Qty stop no no check Customer table to valid? error message stop ensure valid CustID yes no add new record with CustID, ProductID Qty valid? error message stop stop Home Previous 26 o f 33 Next
  • 27. 15. Advanced Triggers Application to the assignment 15.4.4 Annotated source code for the MsgBox “Back order cannot be processed: backorders shortcut module. order contains no items” Exit Sub In the following sections, the two procedures in the End If shortcut module are examined. In each case, the Do Until rsBOItems.EOF code for the procedure is presented followed by Call BackOrderItem(lngCustID, comments on specific lines of code. rsBOItems!ProductID, rsBOItems!Qty) 15.4.4.1 The UpdateBackOrders() function rsBOItems.MoveNext Function UpdateBackOrders(ByVal Loop lngOrdID As Long, ByVal lngCustID As rsBOItems.Close Long) End Function Set dbCurr = CurrentDb 15.4.4.2 Explanation of the Dim rsBOItems As Recordset UpdateBackOrders() function dbCurr.QueryDefs!pqryItemsToBackOrder. Parameters!pOrderID = lngOrdID Function UpdateBackOrders(ByVal lngOr- Set rsBOItems = dID As Long, ByVal lngCustID As Long) — dbCurr.QueryDefs!pqryItemsToBackOrder This statement declares the function and its parame- .OpenRecordset() ters. Each item in the parameter list contains three If rsBOItems.RecordCount = 0 Then elements: ByVal or ByRef (optional), the variable's name, and the variable's type (optional). The ByVal Home Previous 27 o f 33 Next
  • 28. 15. Advanced Triggers Application to the assignment keyword simply means that a copy of the variables Dim rsBOItems As Recordset — In this decla- value is passed the subroutine, not the variable ration statement, a pointer to a Recordset object is itself. As a result, variables passed by value cannot declared. This recordset contains a list of all the be changed by the sub-procedure. In contrast, if a items to add to the BackOrders table. variable is passed by reference (the default), its dbCurr.QueryDefs!pqryItemsToBackOrder value can be changed by the sub-procedure. .Parameters!pOrderID = lngOrdID — This Set dbCurr = CurrentDb — Declaring a vari- one is a bit tricky: the current database (dbCurr) able and setting it to be equal to something are dis- contains a collection of objects called QueryDefs tinct activities. In this case, the variable dbCurr (these are what you create when you use the QBE (which is declared in the declarations section) is set query designer). Within the collection of QueryDefs, to point to a database object. Note that the database there is one called pqryItemsToBackOrder object is not created, it already exists. (which you created in Section 15.4.2.1). CurrentDb is a function supported in Access ver- Within every QueryDef, there is a collection of zero sion 7.0 and higher that returns a reference to the or more Parameters. In this case, there is one called current database. In Access version 2.0, this function pOrderID and this sets the value of the parameter does not exist and thus the current database must to the value of the variable lngOrderID (which was be found by starting at the top level object in the passed to the function as a parameter). Access DAO hierarchy, as discussed in Set rsBOItems = dbCurr.QueryDefs!pqry- Section 14.3.1. ItemsToBackOrder.OpenRecordset() — Here Home Previous 28 o f 33 Next
  • 29. 15. Advanced Triggers Application to the assignment is another set statement. In this one, the variable MsgBox “Back order cannot be processed: rsBOItems is set to point at a recordset object. order contains no items” — The MsgBox Unlike the current database object above, however, statement pops up a standard message box with an this recordset does not yet exist and must be created Okay button in the middle. by running the pqryItemsToBackOrder parame- Exit Sub — If this line is reached, the list contains ter query. no items. As such, there is no need to go any further OpenRecordset is a method that is defined for in this subroutine. objects of type TableDef or QueryDef that creates an End If — The syntax for If… Then… Else… state- image of the data in the table or query. Since the ments requires an End If statement at the end of query in question is a parameter query, and since the the conditional code. That is, everything between the parameter query is set in the previous statement, the If and the End If executes if the condition is true; resulting recordset consists of a list of backordered otherwise, the whole block of code is ignored. items with an order number equal to the value of Do Until rsBOItems.EOF — The EOF property pOrderID. of a recordset is set to true when the “end of file” is If rsBOItems.RecordCount = 0 Then — The encountered. only thing you need to know at this point about the Call BackOrderItem(lngCustID, rsBOI- RecordCount property of a recordset is that it returns tems!ProductID, rsBOItems!Qty) — A sub- zero if the recordset is empty. routine is used to increase the modularity and Home Previous 29 o f 33 Next
  • 30. 15. Advanced Triggers Application to the assignment readability of this function. Note the way in which the 15.4.4.3 The BackOrderItem() subroutine current values of ProductID and Qty from the Sub BackOrderItem(ByVal lngCustID As rsBOItems Recordset are accessed. Long, ByVal strProdID As String, ByVal intQty As Integer) rsBOItems.MoveNext — MoveNext is a method Set dbCurr = CurrentDb defined for recordset objects. If this is forgotten, the Dim strSearch As String EOF condition will never be reached and an infinite Dim rsBackOrders As Recordset loop will be created. In VBA, the Escape key is usu- Set rsBackOrders = ally sufficient to stop an infinite loop. dbCurr.OpenRecordset(“BackOrders”, Loop — All Do While/Do Until loops must end dbOpenDynaset) with the Loop statement. strSearch = “CustID = “ lngCustID “ rsBOItems.Close — When you create a new AND ProductID = ' strProdID “'” object (such as a Recordset using the Open- rsBackOrders.FindFirst strSearch Recordset method), you should close it before exit- If rsBackOrders.NoMatch Then ing the procedure. Note that you do not close Dim rsCustomers As Recordset dbCurr because you did not open it. Set rsCustomers = dbCurr.OpenRecordset(“Customers”, End Function — All functions/subroutines need dbOpenDynaset) an End Function/End Sub statement. strSearch = “CustID = “ lngCustID rsCustomers.FindFirst strSearch Home Previous 30 o f 33 Next
  • 31. 15. Advanced Triggers Application to the assignment If rsCustomers.NoMatch Then rsBackOrders!Qty = intQty MsgBox “An invalid Customer ID number rsBackOrders.Update has been passed to BackOrderItem” Else Exit Sub rsBackOrders.Edit End If rsBackOrders!Qty = rsBackOrders!Qty + Dim rsProducts As Recordset intQty Set rsProducts = rsBackOrders.Update dbCurr.OpenRecordset(“Products”, End If dbOpenDynaset) End Sub strSearch = “ProductID = ' strProdID 15.4.4.4 Explanation of the BackOrderItem() “'” subroutine rsProducts.FindFirst strSearch If rsProducts.NoMatch Then Since many aspects of the language are covered in MsgBox “An invalid Product ID number the previous subroutine, only those that are unique has been passed to BackOrderItem” to this subroutine are explained. Exit Sub Set rsBackOrders = dbCurr.OpenRecord- End If set(“BackOrders”, dbOpenDynaset) — The rsBackOrders.AddNew OpenRecordset method used here is the one rsBackOrders!CustID = lngCustID defined for a Database object. The most important rsBackOrders!ProductID = strProdID argument is the source of the records, which can be Home Previous 31 o f 33 Next
  • 32. 15. Advanced Triggers Application to the assignment a table name, a query name, or an SQL statement. do this, single quotes are used within the search The dbOpenDynaset argument is a predefined con- string. stant that tells Access to open the recordset as a rsBackOrders.FindFirst strSearch — dynaset. You don't need to know much about this FindFirst is a method defined for Recordset except that the format of these predefined constants objects that finds the first record that meets the crite- is different between Access version 2.0 and version ria specified in the method's argument. Its argument 7.0 and higher. In version 2.0, constants are of the is the text string stored in strSearch. form: DB_OPEN_DYNASET. If rsBackOrders.NoMatch Then — The strSearch = “CustID = ” lngCustID “ NoMatch property should always be checked after AND ProductID = ’” strProdID “'” — searching a record set. Since it is a Boolean variable A string variable has been used to break the search (True / False) it can be used without an comparison process into two steps. First, the search string is operator. constructed; then the string is used as the parameter rsBackOrders.AddNew — Before information can for the FindFirst method. The only tricky part here be added to a table, a new blank record must be cre- is that lngCustID is a long integer and strProdID ated. The AddNew method creates a new empty is a string. The difference is that the value of str- record, makes it the active record, and enables it for ProdID has to be enclosed in quotation marks when editing. the parameter is passed to the FindFirst method. To Home Previous 32 o f 33 Next
  • 33. 15. Advanced Triggers Application to the assignment rsBackOrders!CustID = lngCustID — Note the syntax for changing a variable’s value. In this case, the null value of the new empty record is replaced with the value of a variable passed to the subroutine. rsBackOrders.Update — After any changes are made to a record, the Update method must be invoked to “commit” the changes. The AddNew / Edit and Update methods are like bookends around changes made to records. rsBackOrders.Edit — The Edit method allows the values in a record to be changed. Note that these changes are not saved to the underlying table until the Update method is used. Home Previous 33 o f 33 Next