仅重新查询数据表视图表单中的一条记录 (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 表单交叉表查询

ms-access:仅显示特定日期内记录的报告

在 MS Access 中根据表单中的多个组合框查询所有记录

SQL Server基础操作(此随笔仅作为本人学习进度记录九!--游标)

MS 访问组合框

EF查询视图只得到一条记录