Access Attendance table help; Need to update table daily w/o copying table twice

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • twinnyfo
    Recognized Expert Moderator Specialist
    • Nov 2011
    • 3653

    #31
    Perfect!!!!! No need to apologize. You have learned something today.

    Now, on to the next step!

    We need to create a subform to house the People. I will describe everything here, and you have to follow directions--but you have to TRUST me on this, because I will tell you to do some strange things that don't make sense.

    Create a new form called "fsubPeople ". Set its default view to "Continuous Forms". No navigation buttons, No Record Selectors, Vertical Only Scroll Bars, No Control Box, No Close Button, No Min Max Buttons, No Allow Additions.

    Set its Record Source as tblPerson. (I'll explain later).

    From the Form Design Tools, select Design, in the Tools Section, select Tools and click on Add Existing Fields. Drag and drop the F_Name and L_Name Fields over to the detail section of your form. Get these two text boxes nice and cozy all the way at the top of the detail section. You can delete the labels for these text boxes. Rename the text boxes to txtL_Name and txtF_Name.

    Now, listen carefully. I can't explain why this happens (at least it does to me), but we need a way for this sub form to identify the Person ID, but we don't want to display it. Drag the PersonID field onto your form.

    Then....

    Delete it.

    Add a Command button to the form and name it cmdAttend with caption "Attend". On Click event for that Command Button:
    Code:
    Option Compare Database
    Option Explicit
    
    Private Sub cmdAttend_Click()
        Dim strSQL  As String
        Dim db As DAO.Database
    
        strSQL = _
            "INSERT INTO tblAttendance " & _
            "( PersonID, AttendanceDate ) " & _
            "VALUES ( " & Me.PersonID & ", #" & _
                Me.Parent.Form.txtDate & "# );"
        Debug.Print strSQL
        Set db = CurrentDb()
        Call db.Execute(Query:=strSQL, _
                        Options:=dbFailOnError)
        Set db = Nothing
    
        Me.Requery
    
    End Sub
    In the end your tiny subform should look something like this:
    [imgnothumb]https://bytes.com/attachment.php? attachmentid=99 26&stc=1&d=1552 585184[/imgnothumb]

    Finally, go back to the record source for this form and delete the Record Source. The only reason we used the table as a record source was to establish certain field names and ensure we got everything correct (and it's just easier than designing unbound controls that have nothing to use as control sources).

    Save that form and close it.

    Open your Attendance form in design view, and drag the new subform onto your main form. Be sure to rename the sub form fsubPeople (if it didn't default to that name).

    But, now, we need a way to update the list of people on the sub form. Since we know that your SQL creates a useable list of people...... We need to set that string to the record source of the new subform you made. Your FindPeople() procedure should now look like this:
    Code:
    Private Sub FindPeople()
        Dim strSQL As String
    
        strSQL = _
            "SELECT tblPerson.PersonID, " & _
            "tblPerson.F_Name, " & _
            "tblPerson.L_Name " & _
            "FROM tblPerson " & _
            "LEFT JOIN tblAttendance " & _
            "ON tblPerson.PersonID = tblAttendance.PersonID " & _
            "WHERE (tblAttendance.PersonID Is Null " & _
            "AND tblAttendance.AttendanceDate=#" & Me.txtDate & "#) " & _
            "OR tblAttendance.PersonID Is Null " & _
            "ORDER BY tblPerson.L_Name, tblPerson.F_Name;"
    
        With Me.fsubPeople
            .Form.RecordSource = strSQL
            .Requery
        End With
    
    End Sub
    Notice that we also deleted the Debug.Print strSQL (because we know that it works!).

    Your main form should now look something similar to this:
    [imgnothumb]https://bytes.com/attachment.php? attachmentid=99 27&stc=1&d=1552 585775[/imgnothumb]

    But wait! There's one more thing we have to do. Whenever we change the value of your Date text box, we need to update everything, too. So, we add the following procedure in the text box's On Change Event:
    Code:
    Private Sub txtDate_Change()
    
        Me.Refresh
        Call FindPeople
    
    End Sub
    We're just refreshing the value of the text box to that its value can be used, and updating the people.

    Save your form and close it.

    Open your Form and see if there are any errors. At this point you should be able to select different dates, and if there is any attendance data already in tblAttendance, it should reflect in your list of names. If you click on "Attend" next to any name, that name "should" disappear from the list.

    Let me know how you get along with this.
    Attached Files

    Comment

    • twinnyfo
      Recognized Expert Moderator Specialist
      • Nov 2011
      • 3653

      #32
      Also, on your People sub-form, txtF_Name and txtL_Name should be Enabled=No and Locked=Yes.

      Comment

      • brikusi
        New Member
        • Mar 2019
        • 44

        #33
        I made all the changes, form is looking great. I did get an error however when I ran It. I think its looking for the PersonID to be there as you mentioned above.

        Can we add it there ant set its property to not visible? Just a thought if that is the cause of the error.
        [imgnothumb]https://bytes.com/attachments/attachment/9928d1552597784/formerror.jpg[/imgnothumb]
        Attached Files
        Last edited by twinnyfo; Mar 14 '19, 09:30 PM.

        Comment

        • twinnyfo
          Recognized Expert Moderator Specialist
          • Nov 2011
          • 3653

          #34
          Yep - that should work. I think I just try to trick Access when I do that. It makes me feel like I’ve got a leg up on the machine...... It should work fine after that.

          Comment

          • brikusi
            New Member
            • Mar 2019
            • 44

            #35
            That did it! Works as expected.

            Comment

            • twinnyfo
              Recognized Expert Moderator Specialist
              • Nov 2011
              • 3653

              #36
              Let me know how you get along with your other tasks and we will finish up.

              Comment

              • brikusi
                New Member
                • Mar 2019
                • 44

                #37
                I completed the new query and additional subform and added it to the master form. I noticed as I ran the form that as they are removed off 1 list they are added to another. This is pretty cool.

                Quick questions as I'm starting to see whats going on:

                1. Am i tracking only those who attended or absent in the 2nd form?
                - Do I only mark those who are not present then provide comments about them in the 2nd sub form?

                2. What if someone is marked by mistake? How would I bring them back to the 1st subform?

                Comment

                • twinnyfo
                  Recognized Expert Moderator Specialist
                  • Nov 2011
                  • 3653

                  #38
                  You are so close! I'll answer your questions, then finish up what you need to do.

                  1. Am i tracking only those who attended or absent in the 2nd form?
                  - Do I only mark those who are not present then provide comments about them in the 2nd sub form?
                  This is a list of those who have attended. Those on the first form are those who are absent.

                  2. What if someone is marked by mistake? How would I bring them back to the 1st subform?
                  This can easily be built into the 2nd subform. Just add a button to delete the current record and refresh everything.

                  So, final steps:

                  For those who are wondering, during PM, the following instructions were given last night:
                  twinnyfo:
                  The next step is even more super easier than anything else so far. Hopefully you can understand this via e-mail. Create a query. Add tblAttendance and tblPerson. Make sure that the two tables are joined on PersonID. Add the fields AttendDate, F_Name, L_Name and Comments to your query. Note that the Name fields come from tblPerson, but because the tables are joined on PersonID, these will match the people who have attended. Sort the query by L_Name and F_Name. Save the query as qryAttendance.

                  Create another sub-form, called fsubAttendance. Form view is Continuous. Record source is qryAttendance. Same settings on all the properties for the other sub form. Add text boxes (with appropriate renaming) for F_Name, L_Name and Comments. The Name fields should be Enabled=No, Locked=Yes. Comments is enabled and unlocked. Make the text boxes all nice and pretty. Save the form and put it on the main form, just like you did for the other sub form.
                  First, we need to make an update to Post #31, first block of code in order to update the 2nd sub-form. Your procedure should now look like this:
                  Code:
                  Private Sub cmdAttend_Click()
                      Dim strSQL  As String
                      Dim db As DAO.Database
                  
                      strSQL = _
                          "INSERT INTO tblAttendance " & _
                          "( PersonID, AttendanceDate ) " & _
                          "VALUES ( " & Me.PersonID & ", #" & _
                              Me.Parent.Form.txtDate & "# );"
                      Set db = CurrentDb()
                      Call db.Execute(Query:=strSQL, _
                                      Options:=dbFailOnError)
                      Set db = Nothing
                  
                      Me.Requery
                      [B][U]Me.Parent.Form.fsubAttendance.Form.Requery[/U][/B]
                  
                  End Sub
                  Now, we need to make sure that the Attendance list is properly filtered by date. Same post, 2nd block of code, we've added the filtration code at the end of your procedure:
                  Code:
                  Private Sub FindPeople()
                      Dim strSQL As String
                  
                      strSQL = _
                          "SELECT tblPerson.PersonID, " & _
                          "tblPerson.F_Name, " & _
                          "tblPerson.L_Name " & _
                          "FROM tblPerson " & _
                          "LEFT JOIN tblAttendance " & _
                          "ON tblPerson.PersonID = tblAttendance.PersonID " & _
                          "WHERE (tblAttendance.PersonID Is Null " & _
                          "AND tblAttendance.AttendanceDate=#" & Me.txtDate & "#) " & _
                          "OR tblAttendance.PersonID Is Null " & _
                          "ORDER BY tblPerson.L_Name, tblPerson.F_Name;"
                  
                      With Me.fsubPeople
                          .Form.RecordSource = strSQL
                          .Requery
                      End With
                  
                      [B][U]With Me.fsubAttendance.Form[/U][/B]
                          [B][U].Filter = "AttendanceDate = #" & Me.txtDate & "#"[/U][/B]
                          [B][U].FilterOn = True[/U][/B]
                      [B][U]End With[/U][/B]
                  
                  End Sub
                  Aside from adding a close button to your main form and making things more beautiful-looking (and possibly adding a delete button to the 2nd sub-form), unless I am gravely mistaken, you are done!

                  You can take that to church this Sunday!

                  Let me know if you need anything else.

                  Comment

                  • brikusi
                    New Member
                    • Mar 2019
                    • 44

                    #39
                    Awesome sauce! I am going to apply the following steps above but I think I may have something backwards.

                    The first form doesn't have comments. if this form is for those absent (fsubPeople) I will need comments added there, so I can note rather their absence is due to trip, sick, etc.

                    Also this is the information that I will need to be tracking in a report. but the 2nd sub form (fsubAtttendanc e) is whats recorded in tblAttendance.

                    Comment

                    • twinnyfo
                      Recognized Expert Moderator Specialist
                      • Nov 2011
                      • 3653

                      #40
                      OK - So your last point threw a gigantic wrench into things. However, It is not so much a wrench as a change in thought.

                      OK - if you need to track attendance for those who attend but keep notes on those who don't, then the first list now becomes your attendees and your second list becomes your absentees (which might make sense ultimately to change the name of the table to "tblAbsentees") .

                      Here is your challenge either way: If you are only tracking absentees, then you are really looking for those people who are not there? Have you ever tried looking for something that, literally, is not present? This makes it difficult to manage the list, but from a database design perspective, things are easy.

                      If you want to still keep attendance, but also track absentees with comments, there is na easy way to do it. Simply copy all the records for all the people over to your attandance table every time you take attendance and add a check box for attendance and then the comments field is available for those who are absent.

                      Either way is possible. This just depends on what types of numbers you are talking about. If you have small numbers, then keeping track of those who are absent is a bit easier. However, as numbers grow, the second option becomes more feasible as a user.

                      If you use the second option, though, you will need a way to track attendance and maintain history. So, as people come and go, you can't simply delete the person from tblPerson. First, tblAttendance won't allow you to delete them. Second, you will lose the history for that person's attendance. So, you will need an "Active" field in tblPerson (Yes/No field) that simply indicates whether the person is an active member of the church. Then, each time you take attendance, you run this SQL:
                      Code:
                      INSERT INTO tblAttendance ( PersonID, AttendanceDate )
                      SELECT tblPerson.PersonID, Date() 
                      FROM tblPerson 
                      WHERE tblPerson.Active;
                      AND--you no longer need the two subforms, but just the attendance subform, filtered by date. You'll have to add that Attend Check Box to that subform (and the table, of course).

                      Please don't think that you have wasted your time (or mine) by this extended exercise, which we may not use for this function. Hopefully you have learned something new that you can use in the future.

                      Hope this hepps!
                      Last edited by twinnyfo; Mar 15 '19, 01:49 PM.

                      Comment

                      • brikusi
                        New Member
                        • Mar 2019
                        • 44

                        #41
                        You're losing me now a bit.
                        I like what we have built.

                        Can't I keep the same concept of what we have now and just switch the names around? So rather all those who are mark( click the button) are those considered absent?

                        they then go to the 2nd sub form and I can record comments about them there?

                        Is that not an option? versus having to redo the design and how everything works?

                        secondly I made the changes in the post prior to this one. the only thing i notice is that when I run the form for today. Those I marked yesterday are still gone.

                        Comment

                        • twinnyfo
                          Recognized Expert Moderator Specialist
                          • Nov 2011
                          • 3653

                          #42
                          Can't I keep the same concept of what we have now and just switch the names around? So rather all those who are mark( click the button) are those considered absent?
                          Yes, that is my first comment exactly.

                          secondly I made the changes in the post prior to this one. the only thing i notice is that when I run the form for today. Those I marked yesterday are still gone.
                          Exactly what do you mean? Gone from the first list or the second list? Because it is based upon a date, those names marked from yesterday will not be on the second list today. Maybe I'm just confused.

                          Comment

                          • brikusi
                            New Member
                            • Mar 2019
                            • 44

                            #43
                            Ok great so I just changed the label of the sub form to Church List and the second form is Absentees, I kept everything else the same.

                            to the 2nd question. Let's say I logged someone yesterday as absent, from the 1st sub form with all the people listed. Today when I open the form to take attendance those who i marked as absent yesterday has disappeared from the church list (fsubPeople). So I can't mark them as absent today if i needed to.

                            I guess I'm saying, the church list (fsubPeople) needs to re-list everyone again for a new day. Does that make sense?

                            I am attaching two images.
                            Image 1 (Yesterday Attendance)3/14 you can see I marked Devonia, Barbara, and Carl as Absent

                            now If I change the date to 3/15, Devonia, Barbara, and Carl are not repopulated to the original list again.

                            Comment

                            • twinnyfo
                              Recognized Expert Moderator Specialist
                              • Nov 2011
                              • 3653

                              #44
                              I understand completely.

                              So, this is my bone-headed mistake.

                              Change the designing of the SQL statement to this:

                              Code:
                                  strSQL = _
                                      "SELECT tblPerson.PersonID, " & _
                                      "tblPerson.F_Name, " & _
                                      "tblPerson.L_Name " & _
                                      "FROM tblPerson " & _
                                      "LEFT JOIN " & _
                                          "(SELECT PersonID " & _
                                          "FROM tblAttendance " & _
                                          "WHERE AttendanceDate=#" & Me.txtDate & "#) " & _
                                          "AS T1 " & _
                                      "ON tblPerson.PersonID = T1.PersonID " & _
                                      "WHERE tblAttendance.PersonID Is Null " & _
                                      "ORDER BY tblPerson.L_Name, tblPerson.F_Name;"
                              NOW it should work! :-)

                              Comment

                              • twinnyfo
                                Recognized Expert Moderator Specialist
                                • Nov 2011
                                • 3653

                                #45
                                Notice how Goofy is scratching his head......

                                Comment

                                Working...