Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access VBA - use Bookmark to remove filter and stay on current record

In Access 2010, I have a form which can be opened to a specific record or records using a filter:

DoCmd.OpenForm "frmStories", , , "StoryID = " & someNumber  'open one record
DoCmd.OpenForm "frmStories", , , someCriteria               'open multiple records

Using the code below (source) lets me remove the filter and remain on the current record... or so I thought. Parts of the form - namely the fields calculated by VBA - still think they're on the first record, use StoryID = 1, and consequently display the wrong results.

Dim varFilterID As Variant

Public Sub Form_ApplyFilter(Cancel As Integer, ApplyType As Integer)
    
    'Note current record if filter is removed
    If ApplyType = acShowAllRecords Then
        varFilterID = Me.StoryID
    End If
    
End Sub

Private Sub Form_Current()        
    ' If the filter is OFF, and we have a stored ID from the filter setting,
    ' use standard bookmark code to return to the record selected for the filter.

    If Me.FilterOn = False Then
        If Nz(varFilterID) <> "" Then
            Dim rs As DAO.Recordset
            Set rs = Me.RecordsetClone
            rs.FindFirst = "StoryID = " & varFilterID
            Debug.Print "varFilterID=" & varFilterID & " storyID = " & Me.StoryID & " 1st"
            If rs.NoMatch = False Then Me.Bookmark = rs.Bookmark
            ' Reset the stored filterID so that the code does not keep forcing this
            ' selection as the user navigates through the records.
            varFilterID = Null
            Set rs = Nothing
            Debug.Print "varFilterID=" & varFilterID & " storyID = " & Me.StoryID & " 2nd"

        End If
    End If
    
    'other stuff    
End Sub

Stepping through the code showed that it works fine the first time, reaches the end of the sub and then restarts when Form_Current is triggered again (why?) at which point Me.StoryID reverts to 1. This makes me think the problem has something to do with the event firing order (ApplyFilter seems to trigger ''after'' Current has finished).

Paging to the previous record and back fixes it; and when placed in a command button, the code works perfectly.

What am I doing wrong? Alternatively, is there another approach I could take? (I need to filter on several non-contiguous records, so loading the form with .FindFirst is not an option.)

ETA: I added some Print.Debug lines to see what was going on. This is the result:

ApplyType
varFilterID=35 storyID = 1 1st
varFilterID=35 storyID = 35 1st
varFilterID= storyID = 35 2nd
varFilterID= storyID = 1 2nd      <- resets between Current's End Sub and the last Current

EDIT (5 years later): SOLVED! I posted my solution below. Tl;dr Exit Sub is god.

like image 345
Notiophilus Avatar asked Nov 01 '25 06:11

Notiophilus


1 Answers

The problem is the following: If rs.NoMatch = False Then Me.Bookmark = rs.Bookmark moves the current record in the form, triggering another Form_Current, potentially triggering an endless loop.

You can try rate limiting the Form_Current to only trigger once every second:

Private lastCurrent As Date
Private Sub Form_Current()
   If lastCurrent < Now() - #00:00:01# Then Exit Sub
   LastCurrent = Now()

Note that, depending on how long your code takes to run, you might need to increase the number of seconds.

Note, though, that this is likely is an XY problem. You can move to a specific record when opening a form without applying a filter in the following way

Dim frm As Form
Application.ScreenUpdating = False
DoCmd.OpenForm "frmStories"
Set frm = Forms!frmStories
Dim rs As RecordSet
Set rs = frm.RecordsetClone
strCriteria = "StoryID = " & someNumber
rs.FindFirst strCriteria
If rs.NoMatch = False Then frm.Bookmark = rs.Bookmark
Application.ScreenUpdating = True

Further techniques to achieve this might be things like using OpenArgs, which is one I often use.

like image 189
Erik A Avatar answered Nov 02 '25 21:11

Erik A



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!