仅重新查询数据表视图表单中的一条记录 (MS Access)
Posted
技术标签:
【中文标题】仅重新查询数据表视图表单中的一条记录 (MS Access)【英文标题】:Requery only one record in a datasheet view form (MS Access) 【发布时间】:2015-09-07 13:33:20 【问题描述】:我有一个看起来很简单的问题,但结果比我想象的要复杂。
我的子表单中有一个字段(列),它是一个组合框。 我在另一个子表单中有一个字段(列),我想通过它过滤这个组合框。
基本上,过滤前的组合框有大约 600 条记录,对于普通用户来说太多了。我创建了一个简单的 subForm,其字段链接到 mainForm,并且效果很好(即所选的记录字段 ID 显示在 mainForm 上)。
现在我想要的是这个组合框被这条记录过滤(即只显示相关字段)。问题是,如果我只是用这个给定的过滤器重新查询它,其他字段就会显示为空白。
我希望此过滤器仅适用于 NEW RECORDS 组合框,而不是整个数据表视图。
我所做的是:
Private Sub Sekacie_Operacie_GotFocus()
Dim SQL As String
SQL = CurrentDb.QueryDefs("qrySekacie_Operacie").SQL
Me.Sekacie_Operacie.RowSource = Replace(SQL, ";", "") & " WHERE Sekacie_Operacie.Operacia_ID = " & Me.Parent.Form!txtOP_ID
Me.Sekacie_Operacie.Requery
'works kinda as intended
End Sub
Private Sub Form_AfterInsert()
Me.Sekacie_Operacie.RowSource = CurrentDb.QueryDefs("qrySekacie_Operacie").SQL
Me.Refresh
End Sub
当我在我的过滤子表单中选择记录时:
Private Sub Form_Current()
Dim SQL As String
SQL = CurrentDb.QueryDefs("qrySekacie_Operacie").SQL
With Me.Parent.Form.subSekacie_Operacie_Modelu
.Form!Sekacie_Operacie.RowSource = SQL
.Form.Refresh
End With
End Sub
但是,这种解决方法有时仍会显示“空白”记录(我必须通过单击不同的记录来刷新表单),我觉得很奇怪,我不得不一直这样做。有没有更简单的方法可以做到这一点?
【问题讨论】:
【参考方案1】:一些直接的事情:
无需刷新整个子窗体,刷新控件即可。
Private Sub Form_AfterInsert()
' Me.Refresh ' replace this line with the following line
Me.Sekacie_Operacie.Refresh ' or is it Requery I can't remember
End Sub
以下代码可以改进
Private Sub Form_Current()
Dim SQL As String
SQL = CurrentDb.QueryDefs("qrySekacie_Operacie").SQL
With Me.Parent.Form.subSekacie_Operacie_Modelu
.Form!Sekacie_Operacie.RowSource = SQL
.Form.Refresh
End With
End Sub
' 使用这样的代码
Private Sub Form_Current()
Dim SQL As String
SQL = CurrentDb.QueryDefs("qrySekacie_Operacie").SQL
me.Sekacie_Operacie.RowSource = SQL
' I think the above line will cause the combo to refresh
' anyway (in some version of accees it might not,
' but, if needed add the following line
' me.Sekacie_Operacie.refresh
End Sub
以下行有可能产生错误 (也许当主窗体是新记录时)
WHERE Sekacie_Operacie.Operacia_ID = " & Me.Parent.Form!txtOP_ID
替换为
WHERE Sekacie_Operacie.Operacia_ID = " & nz(Me.Parent.Form!txtOP_ID,0)
请注意,添加此类代码将阻止子表单独立于主表单工作,并要求它具有父表单。
您可以通过以下方式解决此问题:
if not me.parent is nothing then
WHERE Sekacie_Operacie.Operacia_ID = " & nz(Me.Parent.Form!txtOP_ID,0)
end if
关于你的方法。
我觉得你在做什么有点奇怪。考虑一下:
假设查询 qrySekacie_Operacie 在没有任何 WHERE 子句的情况下运行时返回 100 行。当您将记录插入子表单时,您希望通过添加使用父 formMe.Parent.Form!txtOP_ID) 中的值的 WHERE 子句来限制组合,这可能会将显示的行数限制为 10。
值得注意的是,如果子表单中的任何其他行包含这 10 个之外的值,则组合将显示一个空白值。我想这就是你正在经历的。
我的第一个问题是为什么不使用父表单的 on current 事件来更改子表单组合框 SQL。看来这不是您需要的。
似乎其他值可以存在于子表单的数据集中,并且您只希望在此子表单中可以输入某些值,但您希望子表单显示已输入的任何值。
所以这很有趣。这就是我要做的:
创建一个仅在输入新记录时才可见的隐藏组合控件(没有控件源)。当这个新组合显示时,另一个组合被隐藏。
使用所需的 SQL 设置此新组合
使用插入前事件将值从新组合复制到旧组合。
容易小便?
让我知道你怎么样。
另一件事
我喜欢确保子表单包含对其进行“私有”控件操作的代码。
根据我的一般经验法则,在可能的情况下(这是 99% 的时间),我喜欢尝试保留子表单,以便它们能够以自己的方式作为表单工作。它们可以作为一个对象,因此如果它们独立工作,则表明它们的代码已封装在自己的代码模块中。
所以如果表单有 me.form.parent = nothing 那么代码的行为会有所不同,因为它是一个独立的表单。
因此,与其父表单代码模块具有设置子表单组合的 SQL 的代码,我将在子表单模块(称为 SetComboSQL)中编写一个公共子程序,可以调用(使用适当的参数。即 OPid )设置组合 SQL。
要在父表单中调用该过程,我会添加
私有子表单_Current()
Me.MySubformControlName.Form.SetComboSQL(OPid:=Me.txtOP_ID)
结束子
' 请注意,智能感知不会获取此属性,但它会起作用。使用调试器检查一下。
我希望这个技巧对您有用(因为它可以让您非常头疼。最基本的 OO 原则是封装。一个对象应该拥有影响其属性(和控件)的所有代码。
【讨论】:
以上是关于仅重新查询数据表视图表单中的一条记录 (MS Access)的主要内容,如果未能解决你的问题,请参考以下文章
在 MS Access 中根据表单中的多个组合框查询所有记录