Access关闭详情窗体后刷新自定义SQL记录集并保留当前选中项
问题:Access窗体修改数据后保留原有设置并刷新显示
场景与现有代码
有两个Access窗体:连续型的概述窗体(frm_PartsOverview)和单条记录的详情窗体(frm_PartsDetail)。概述窗体通过临时DAO查询定义加载传递查询数据,打开时的代码如下:
Dim strSQL As String strSQL = "SELECT DISTINCT tbl_Parts.strPart, Title, Comment FROM [tbl_Parts] inner JOIN [tbl_PartModules] ON tbl_Parts.strPart = tbl_PartModules.strPart ORDER BY tbl_Parts.strPart DESC" Dim qdf As DAO.QueryDef, rst As DAO.Recordset Set qdf = CurrentDb.CreateQueryDef("") Dim strTmpConnQDF As String strTmpConnQDF = CStr(Application.TempVars("tempvar_StrCnxn")) qdf.Connect = strTmpConnQDF qdf.sql = strSQL qdf.ReturnsRecords = True Set rst = qdf.OpenRecordset Set Forms![frm_PartsOverview].Recordset = rst Forms![frm_PartsOverview].Requery 'No rst.Close to have the data still in the Form! Set qdf = Nothing
概述窗体支持通过按钮修改SQL筛选记录,每条记录配有“显示详情”按钮打开详情窗体。在详情窗体修改数据后,隐藏窗体时需要实现两个需求:
- 保留概述窗体原有设置(选中的记录、当前SQL筛选条件)
- 刷新概述窗体显示修改后的数据
尝试过在详情窗体隐藏按钮中调用Recalc、Refresh、Requery方法,但均无效,推测是直接赋值Recordset的方式导致。
解决方案
核心思路
直接赋值的DAO Recordset无法通过常规刷新方法更新,必须重新生成记录集并绑定,同时提前保存概述窗体的关键状态(当前SQL、选中记录的主键),刷新后再定位回原记录。
具体步骤
- 保存概述窗体状态
在概述窗体的“显示详情”按钮代码中,添加状态保存逻辑:
' 保存当前选中记录的主键(strPart为你的主键字段) TempVars("CurrentSelectedPart") = Me.strPart ' 保存当前使用的SQL语句(假设你用模块级变量strCurrentSQL存储当前筛选SQL) TempVars("CurrentOverviewSQL") = strCurrentSQL ' 打开详情窗体 DoCmd.OpenForm "frm_PartsDetail", , , "strPart = '" & Me.strPart & "'"
- 重新生成Recordset并定位原记录
修改详情窗体隐藏按钮的代码:
Me.Visible = False Dim strSQL As String Dim qdf As DAO.QueryDef, rst As DAO.Recordset Dim targetPart As String ' 读取保存的状态 strSQL = TempVars("CurrentOverviewSQL").Value targetPart = TempVars("CurrentSelectedPart").Value ' 重新生成传递查询的Recordset Set qdf = CurrentDb.CreateQueryDef("") qdf.Connect = CStr(Application.TempVars("tempvar_StrCnxn")) qdf.SQL = strSQL qdf.ReturnsRecords = True Set rst = qdf.OpenRecordset ' 重新绑定概述窗体的Recordset Set Forms!frm_PartsOverview.Recordset = rst Set qdf = Nothing ' 定位回之前选中的记录 With Forms!frm_PartsOverview ' 若主键是数字类型,去掉单引号 .Recordset.FindFirst "strPart = '" & targetPart & "'" End With
- 代码优化(可选)
将概述窗体的数据源加载逻辑封装为公共子过程,减少重复代码:
在概述窗体模块中添加:
Public Sub ReloadOverviewData(strSQL As String, Optional targetPart As String = "") Dim qdf As DAO.QueryDef, rst As DAO.Recordset Set qdf = CurrentDb.CreateQueryDef("") qdf.Connect = CStr(Application.TempVars("tempvar_StrCnxn")) qdf.SQL = strSQL qdf.ReturnsRecords = True Set rst = qdf.OpenRecordset Set Me.Recordset = rst Set qdf = Nothing ' 定位目标记录 If targetPart <> "" Then Me.Recordset.FindFirst "strPart = '" & targetPart & "'" End If End Sub
之后在详情窗体隐藏时直接调用:
Me.Visible = False Call Forms!frm_PartsOverview.ReloadOverviewData(TempVars("CurrentOverviewSQL").Value, TempVars("CurrentSelectedPart").Value)
原方法无效的原因
当直接给窗体Recordset属性赋值DAO记录集时,窗体的Requery、Refresh方法仅对绑定到表/查询名称的RecordSource有效,无法重新执行传递查询获取更新后的数据,必须重新生成并绑定记录集才能生效。
内容的提问来源于stack exchange,提问作者karlo922
相关产品推荐
相关产品推荐

