OK, I found a better way to iterate through the Tasks for my Form Load Event. Before, I was setting up a Recordset that matched the List Box's contents perfectly. Now, I'm referencing the List Box directly (allowing me to do away with the Recordset).
Form Load Event:
Code:
Private Sub Form_Load()
' Well, I do declare!
Dim rstMembers As DAO.Recordset
Dim rstResponders As DAO.Recordset
' Set the Recordset to the (Active) Member currently being viewed
Set rstMembers = CurrentDb().OpenRecordset("SELECT TOP 1 * FROM qryActiveMembers WHERE [MemberID]=" & Me!MemberID, dbOpenSnapshot) ' Read-only
' Set the Recordset to a list of every Task the current (Active) Member
' percormed for the current Call
Set rstResponders = CurrentDb().OpenRecordset("SELECT * FROM Responders WHERE [CallID]=" & Me!CallID & " AND [MemberID]=" & Me!MemberID, dbOpenSnapshot) ' Read-only
' Make sure there are actually Tasks to highlight
If Not rstResponders.RecordCount = 0 Then
' Make sure we have an accurate Record count by forcing Access to load the
' whole Recordset
rstResponders.MoveLast
rstResponders.MoveFirst
' Loop through each Record in the Responders Recordset
For i = 0 To rstResponders.RecordCount - 1
' For each Record in the Recordset, loop through the contents of the List
' Box (Me!Tasks) to find the matching Task
For j = 0 To Me!Tasks.ListCount - 1
' Check to see if the List Box's current Task matches the one from the
' Recordset
' NOTE: We have to typecast the List Box contents to an Integer to match
' it against the Recordset's value (Why??!?)
If rstResponders("TaskID") = CInt(Me!Tasks.Column(0, j)) Then
' If the Record and List Box item match, highlight the List Box item!
Me!Tasks.Selected(j) = True
' Also highlight the matching item from our Hidden List Box. We can use
' this to compare against the "real" one to find changes (See the
' After_Update Event)
Me!Tasks_Orig.Selected(j) = True
End If
Next j
' Go to the next Record and start the loop over
rstResponders.MoveNext
Next i
End If
' Display the Member whose Tasks we are showing (instead of their ID)
Me!FullName = rstMembers("FullName")
' Close the Recordsets
rstMembers.Close
rstResponders.Close
' Unset the Recordset Objects
Set rstMembers = Nothing
Set rstResponders = Nothing
End Sub
And, using my Form Load Event, I was able to throw together the following After Update Event for my List Box which seems to work rather well.
After Update Event:
Code:
Private Sub Tasks_AfterUpdate()
' Danger Will Robinson! DANGER!!!
On Error GoTo Error_Will_Robinson
' Declare my database Objects
Dim work As Workspace
Dim rstResponders As DAO.Recordset
' Declare and initialize a variable for tracking the status of the Transaction
Dim boolTransActive As Boolean
boolTransActive = False
' Set my database Objects
Set work = DBEngine(0) ' For Transactions!
' Set the Recordset to a list of every Task the current (Active) Member
' performed for the current Call
Set rstResponders = CurrentDb().OpenRecordset("SELECT * FROM Responders WHERE [CallID]=" & Me!CallID & " AND [MemberID]=" & Me!MemberID, dbOpenDynaset)
' Start the Transaction and switch my tracking variable to True
work.BeginTrans
boolTransActive = True
' Loop through each item in the List Box
For i = 0 To Me!Tasks.ListCount - 1
' Check each List Box item to see if it is selected or not
If Me!Tasks.Selected(i) = True Then
' If it IS selected (highlighted), then compare it against the hidden List Box
If Not Me!Tasks_Orig.Selected(i) = True Then
' If the same item is NOT selected in the hidden List Box, then it is a
' new one and needs to be added to the Responders Table
With rstResponders
.AddNew
!CallID = Me!CallID
!MemberID = Me!MemberID
!TaskID = Me!Tasks.Column(0, i)
.Update
End With
' Mark the hidden List Box's item as selected to allow to more updates
Me!Tasks_Orig.Selected(i) = True
End If
Else
' If the List Box item IS NOT selected (highlighted), compare it to the
' same item on the hidden List Box
If Not Me!Tasks_Orig.Selected(i) = False Then
' If the hidden List Box's item IS selected, the Task should be REMOVED
' from the Responders Table
' Find the Record in our Recordset
strCriteria = "[CallID]= " & Me!CallID & _
" And [MemberID]=" & Me!MemberID & _
" And [TaskID]=" & Me!Tasks.Column(0, i)
rstResponders.FindFirst strCriteria
' If the Record exists, delete it from the Recordset
If Not rstResponders.NoMatch Then
With rstResponders
.Delete
End With
End If
' Deselect the hidden List Box's item to allow to more updates
Me!Tasks_Orig.Selected(i) = False
End If
End If
Next i
' Commit the transaction and unset our tracking variable
work.CommitTrans
boolTransActive = False
' Function Closing/Cleanup code block
FunctionClosing:
' Close the Recordset
rstResponders.Close
' Unset the database Objects
Set rstResponders = Nothing
Set work = Nothing
' Leave the function so we don't run into an infinite loop!
Exit Sub
' If an error is encountered, run the following code block
Error_Will_Robinson:
' If we're currently in the middle of a Transaction, rollback any changes
' made to the database. Don't forget to unset the tracking variable!
If boolTransActive = True Then
work.Rollback
boolTransActive = False
End If
' Display a detailed error message to the user
MsgBox "The following error was encountered while attempting to update Responder Tasks. Please contact your System's Administrator." & _
vbCrLf & vbCrLf & _
Err.Number & ": " & Err.Description
' Jump to the Function Closing/Cleanup code block
Resume FunctionClosing
End Sub
Even though I've figured this out, I'd still like to see how you can use pbaldy's code to perform the same thing. . .