Access 2016数据表窗体排序/过滤时丢失参数查询参数值问题
解决Access数据表窗体排序/过滤时参数化查询丢失参数的问题
这个问题在Access里太常见了!当你用参数化查询作为数据表窗体的数据源时,初始加载时VBA传入的参数只会绑定一次,一旦用户触发排序或过滤,窗体就会直接调用原始查询,完全忘了之前传的参数,结果要么弹出烦人的参数输入框,要么返回错误数据。下面给你几个实用的解决办法,按简单到灵活排序:
方法1:让查询直接引用窗体控件(最省心)
不用再靠VBA传参数,直接修改你的参数化查询,让它从窗体控件里读取参数值:
- 打开查询
qry_GetSumEmployeesHoursByPeriodAndProject的设计视图 - 找到
periodID字段的条件行,把原来的参数提示(比如[请输入periodID])改成:
(把[Forms]![你的窗体名称]![txtPeriodID]你的窗体名称换成你实际的窗体名,txtPeriodID换成窗体上存储periodID的控件名称) - 同理,把
projectID字段的条件改成:[Forms]![你的窗体名称]![txtProjectID] - 保存查询后,你甚至可以直接在窗体设计视图里把
RecordSource设为这个查询,连初始加载的VBA都可以简化或者删掉——不管是初始加载还是排序/过滤,查询都会自动从窗体控件取参数,完美解决问题。
方法2:用VBA捕获排序/过滤事件,重新传入参数
如果你不想修改查询,或者参数需要动态计算(不是直接来自控件),可以在窗体的ApplyFilter事件里重新绑定带参数的数据源:
首先,先写一个通用的更新数据源的子过程:
Private Sub UpdateFormDataSource() Dim qdf As QueryDef Set qdf = CurrentDb.QueryDefs("qry_GetSumEmployeesHoursByPeriodAndProject") ' 传入参数 qdf.Parameters("periodID") = Me.txtPeriodID.Value qdf.Parameters("projectID") = Me.txtProjectID.Value ' 把查询的SQL(带参数值)设为窗体数据源 Me.RecordSource = qdf.SQL ' 释放对象 Set qdf = Nothing End Sub
然后在窗体的加载事件和过滤/排序事件里调用这个子过程:
Private Sub Form_Load() ' 初始加载时设置数据源 UpdateFormDataSource End Sub Private Sub Form_ApplyFilter(Cancel As Integer, ApplyType As Integer) ' 排序或过滤时重新设置数据源 UpdateFormDataSource End Sub
这样每次用户点击列标题排序或者使用过滤功能时,都会重新传入最新的参数值,不会再丢失参数。
方法3:动态构建带参数值的SQL字符串
另一种思路是直接用包含参数值的SQL语句作为窗体的数据源,而不是调用参数化查询:
Private Sub UpdateFormDataSource() Dim strSQL As String ' 注意:如果参数是文本类型,要给值加单引号;数字类型直接写就行 strSQL = "SELECT * FROM qry_GetSumEmployeesHoursByPeriodAndProject " & _ "WHERE periodID = " & Me.txtPeriodID.Value & " AND projectID = " & Me.txtProjectID.Value ' 文本类型参数的写法示例: ' strSQL = "SELECT * FROM qry_GetSumEmployeesHoursByPeriodAndProject " & _ ' "WHERE periodID = '" & Me.txtPeriodID.Value & "' AND projectID = '" & Me.txtProjectID.Value & "'" Me.RecordSource = strSQL End Sub
同样在Form_Load和Form_ApplyFilter事件里调用这个子过程,效果和方法2类似,但这种方式把参数直接硬编码到SQL里,避免了查询参数的问题。
内容的提问来源于stack exchange,提问作者Ilija Misov
相关产品推荐
相关产品推荐

