仅重新查询数据表视图表单中的一条记录(MS Access)

时间:2015-09-07 13:33:20

标签: vba ms-access access-vba

我有一个相当简单的问题,但事实证明它比我想象的更复杂。

我的subForm中有一个字段(列),它是一个ComboBox。 我在另一个subForm中有一个字段(列),我希望通过它来过滤这个组合框。

基本上,过滤前的comboBox有大约600条记录,太多不能由临时用户滚动。我创建了一个简单的subForm,其字段链接到一个mainForm,这非常有效(即所选的记录字段ID显示在mainForm上)。

现在我想要的是这个comboBox被这条记录过滤掉(即只显示相关字段)。问题是,如果我只是用这个给定的过滤器重新查询它,其他字段显示为空白。

我希望此过滤器仅适用于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 个答案:

答案 0 :(得分:0)

一些直接的事情:

  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
    
  3. '使用像这样的代码

    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
      
    2. 替换为

          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。

      值得注意的是,如果子窗体中的任何其他行包含除这些中的一个之外的值,则组合将显示空值。我认为这就是你所经历的。

      我的第一个问题是为什么不使用父窗体的on current事件来更改子窗体组合框SQL。看来这不是你需要的。

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

      这样有趣。这就是我要做的事情:

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

      2. 使用所需的SQL

      3. 设置此新组合
      4. 使用before insert事件将新组合的值复制到旧组合中。

      5. 容易发脾气?

      6. 请告诉我你的事。

        另一件事

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

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

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

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

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

        Private Sub Form_Current()

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

        End Sub

        '请注意,intellisense不会接受这个原则,但它会起作用。使用调试器来检查它。

        我希望你发现这个技巧很有用(因为它可能是一个巨大的头痛保护程序。最基本的OO PRINCIPAL是封装。一个对象应该拥有影响它的属性(和控件)的所有代码。