我有一个相当简单的问题,但事实证明它比我想象的更复杂。
我的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
然而,这种解决方法仍然显示"空白"有时候记录(我必须通过点击不同的记录刷新表格),我觉得很奇怪我必须一直这样做。有没有更简单的方法来实现这个目标?
答案 0 :(得分:0)
一些直接的事情:
无需刷新整个子表单,只需刷新控件即可。
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。
值得注意的是,如果子窗体中的任何其他行包含除这些中的一个之外的值,则组合将显示空值。我认为这就是你所经历的。
我的第一个问题是为什么不使用父窗体的on current事件来更改子窗体组合框SQL。看来这不是你需要的。
似乎其他值可以存在于子窗体的数据集中,并且您只希望在此子窗体中可以输入某个值,但您希望子窗体显示已输入的任何值。
这样有趣。这就是我要做的事情:
创建一个隐藏的组合控件(没有控件源),只有在输入新记录时才可见。当显示这个新组合时,另一个组合被隐藏。
使用所需的SQL
使用before insert事件将新组合的值复制到旧组合中。
容易发脾气?
请告诉我你的事。
另一件事
我喜欢确保子表单封装了对其进行操作的代码“私有”控件。
根据我的一般经验法则,在可能的情况下(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是封装。一个对象应该拥有影响它的属性(和控件)的所有代码。