【问题标题】:Requery only one record in a datasheet view form (MS Access)仅重新查询数据表视图表单中的一条记录 (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

但是,这种解决方法有时仍会显示“空白”记录(我必须通过单击不同的记录来刷新表单),我觉得很奇怪,我不得不一直这样做。有没有更简单的方法可以做到这一点?

【问题讨论】:

    标签: ms-access vba


    【解决方案1】:

    一些直接的事情:

    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
      
    2. 以下代码可以改进

      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
    
    1. 以下行有可能产生错误 (也许当主窗体是新记录时)

      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。看来这不是您需要的。

    似乎其他值可以存在于子表单的数据集中,并且您只希望在此子表单中可以输入某些值,但您希望子表单显示已输入的任何值。

    所以这很有趣。这就是我要做的:

    1. 创建一个仅在输入新记录时才可见的隐藏组合控件(没有控件源)。当这个新组合显示时,另一个组合被隐藏。

    2. 使用所需的 SQL 设置此新组合

    3. 使用插入前事件将值从新组合复制到旧组合。

    4. 容易小便?

    让我知道你怎么样。


    另一件事

    我喜欢确保子表单包含对其进行“私有”控件操作的代码。

    根据我的一般经验法则,在可能的情况下(这是 99% 的时间),我喜欢尝试保留子表单,以便它们能够以自己的方式作为表单工作。它们可以作为一个对象,因此如果它们独立工作,则表明它们的代码已封装在自己的代码模块中。

    所以如果表单有 me.form.parent = nothing 那么代码的行为会有所不同,因为它是一个独立的表单。

    因此,与其父表单代码模块具有设置子表单组合的 SQL 的代码,我将在子表单模块(称为 SetComboSQL)中编写一个公共子程序,可以调用(使用适当的参数。即 OPid )设置组合 SQL。

    要在父表单中调用该过程,我会添加

    私有子表单_Current()

    Me.MySubformControlName.Form.SetComboSQL(OPid:=Me.txtOP_ID)
    

    结束子

    ' 请注意,智能感知不会获取此属性,但它会起作用。使用调试器检查一下。

    我希望这个技巧对您有用(因为它可以让您非常头疼。最基本的 OO 原则是封装。一个对象应该拥有影响其属性(和控件)的所有代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-12
      • 2017-05-06
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多