未绑定主窗体列表框关联绑定子窗体触发3021无当前记录错误问询
Problem Background
I've seen plenty of Q&A about the 3021 error, but none that match this specific scenario.
Environment Setup
- Create a blank Access 2016 database
- Add a regular table with 1 ID column and 1 Title string column
- Create a form based on this table, add a text box to display data, save and close it
- Create a second form, add a list box with its row source set to the above table. Configure it to have 2 columns, with the first column width set to 0
- Add the first form as a subform to the second form, linking them using Master/Child fields (Master field = List1, Child field = ID) to let the main form's listbox control navigation of the subform's detail records
- Add this code to the subform's Current event:
debug.print Me.Recordset.Fields("ID")
Observed Behavior
- When loading the second form for the first time, the 3021 "No Current Record" error occurs (this was expected)
- No error occurs when selecting a listbox item for the first time
- The 3021 error is triggered again when selecting a listbox item for the second time
Questions
- Can this issue be reproduced? (I suspect it might not be, and wonder if my Access installation is corrupted, but I'm not sure)
- If it can be reproduced, why is there a difference between the first and second selection? What alternative solutions are available?
Answers
1. Can this issue be reproduced?
Absolutely—this is a reproducible behavior in a fresh Access 2016 setup, so it’s not likely your installation is corrupted. The error stems from how Access handles recordset synchronization between linked master and child forms during repeated listbox selections.
2. Why the first/second selection difference?
Let’s break down the sequence:
- First form load: The subform opens without a linked record (no listbox item is selected), so the
Currentevent fires on an empty recordset—hence the expected 3021 error. - First listbox selection: Access establishes the master-child link for the first time, loads the matching record into the subform’s recordset, and the
Currentevent triggers with a valid active record—no error here. - Second selection: When you switch to a new listbox item, Access first clears the subform’s current recordset before loading the new matching one. The
Currentevent fires during this gap when there’s no active record, so trying to accessMe.Recordset.Fields("ID")throws the 3021 error.
The first selection sets up the link from scratch, but subsequent selections involve tearing down the existing record context first—creating that brief window where the recordset has no current record.
Fixes & Alternatives
Here are reliable ways to resolve the error:
Option 1: Guard against empty records in the Current event
Modify your subform’s Current event code to check if there’s an active record before accessing fields:
If Not (Me.Recordset.EOF Or Me.Recordset.BOF) Then Debug.Print Me.Recordset.Fields("ID") End If
This skips the field access when the recordset is in that transitional empty state.
Option 2: Reference the bound control directly
If you only need the ID value, use the bound control instead of the recordset—it’s more resilient during synchronization:
If Not IsNull(Me.ID) Then Debug.Print Me.ID End If
Bound controls update after the recordset is fully synchronized, so you avoid accessing a non-existent record.
Option 3: Move logic to the main form’s listbox AfterUpdate event
Instead of relying on the subform’s Current event, trigger the code after the listbox selection is fully processed:
- Remove the code from the subform’s
Currentevent - Add this to the main form’s listbox
AfterUpdateevent (replaceYourSubformControlwith your actual subform control name):With Me.YourSubformControl.Form If Not (.Recordset.EOF Or .Recordset.BOF) Then Debug.Print .Recordset.Fields("ID") End If End With
This ensures the subform’s recordset is fully loaded before you access its fields.
内容的提问来源于stack exchange,提问作者PAHTDC

