在我的GUI中,我有几种方法来过滤数据库。由于我缺乏知识,我的VBA编程使用嵌套的IF语句爆炸了。我现在在使用ACCESS方面越来越好,并且想找到一种更简洁的方法来执行多个过滤器。我的表格是连续的。
有没有一种简单的方法可以完成以下任务(我制作了一个玩具模型示例):
我有一个组合框SITE
,可以在其中按工作地点A, B, C
进行过滤。通过SITE过滤后,我有三个复选框,然后用户可以根据用户选择的内容按项目编号1-10
,11-20
,21-30
进行过滤。
是否可以附加多个过滤器(或过滤器过滤的数据)?例如,按站点A
过滤,然后按项目编号A
过滤1-10
?
当前,对于“每个”复选框,然后为每个站点添加一个IF语句。然后使用Form.Filter = . . . And . . .
和Form.FilterOn = True
。
相对于使用VBA,我可以利用属性表上的SQL进行过滤吗?
答案 0 :(得分:2)
对于这些类型的过滤器,我要做的就是在更改过滤器控件之一时构造一条SQL语句。它们都引用相同的子例程以节省代码重复。
此SQL语句的处理方式取决于您要执行的操作。访问功能非常灵活。将其用作RecordSource,直接执行它,并将结果用于其他用途,甚至只是将其打印到标签上。
要尝试对流程进行模块化,请参见以下示例:
Dim str As String
str = "SELECT * FROM " & Me.cListBoxRowSource
Me.Field1.SetFocus
If Me.Field1.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField1 LIKE '*" & Me.Field1.Text & "*'"
End If
Me.Field2.SetFocus
If Me.Field2.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField2 LIKE '*" & Me.Field2.Text & "*'"
End If
Me.Field3.SetFocus
If Me.Field3.Text <> "" Then
str = AppendNextFilter(str)
str = str & " SQLField3 LIKE '*" & Me.Field3.Text & "*'"
End If
Me.cListBox.RowSource = str
修改了变量以保护罪恶感。
我的AppendNextFilter方法只是检查SQL语句中是否已经存在WHERE
。如果是这样,请附加AND
。否则,请附加WHERE
。
答案 1 :(得分:1)
做出许多假设(因为您在问题中遗漏了很多信息),因此您可以执行以下操作:
Dim sSql as String
sSql = "Select * from MyTable"
Set W = Me.cboSite.Value
sSql = sSql & " WHERE MySite = " & W & ""
Set X = Me.Chk1
Set Y = Me.Chk2
Set Z = Me.Chk3
If X = True Then
sSql = sSql & " And MyItem between 1 and 10"
If Y = True Then
sSql = sSql & " And MyItem between 11 and 20"
If Z = True Then
sSql = sSql & " And MyItem between 21 and 30"
End If
DoCmd.ExecuteSQL sSql
同样,这完全是“空中代码”,未经检查,可能需要进行一些编辑,因为我有一段时间没有接触Access了,我的VBA可能会生锈。但这应该使您走上正确的轨道。
答案 2 :(得分:0)
我在访问中使用组合框过滤的方式是,我首先设计一个包含所有要过滤数据的查询。查询必须包含用于过滤的字段。 QueryAllData =>“ SELECT Table.Site,Table.ItemNumber,FROM表;”然后复制查询并将其命名为QueryFilteredData并设计报告以使用QueryFilteredData显示数据。 然后创建一个具有站点组合框,ItemNumber组合框和子报表对象的表单,并为SourceObject分配报表名称。使用“值列表”作为组合框“行来源”类型,并键入“行来源”的值以使其正常工作。为了更新报告,我总是取消分配SubReport.SourceOject来更新QueryFilteredData,然后重新分配SubReport.SourceObject
Combobox_Site_AfterUpdate()
Combobox_ItemNumber_AfterUpdate
End Sub
Combobox_ItemNumber_AfterUpdate()
Select Case Combobox_ItemNumber.value
Case Is = "1-10"
Store_Filters 1,10
Case Is = "11-20"
Store_Filters 11,20
Case Is = "21-30"
Store_Filters 21,30
Case Else
Store_Filters 1,10
End Sub
Private Sub Store_Filters(Lowest as integer, Highest as integer)
Dim SRpt_Recset As Object
Dim Temp_Query As Variant
Dim Temp_SourceObject as Variant
Temp_SourceObject = SubReport.SourceObject
SubReport.SourceObject =""
Set SRpt_Recset = CurrentDb.QueryDefs("QueryFilteredData")
Filter_Combo_Box1 = " ((QueryAllData.[Sites])= " & Chr(39) & Combo_Box1 & Chr(39) & ") "
Filter_Combo_Box2 = (Filter_Combo_Box1 AND (QueryAllData.ItemNumber <= Highest)) OR (Filter_Combo_Box1 AND (QueryAllData.ItemNumber >= Lowest));"
Temp_Query = " SELECT " & Query_Name & ".* " & _
"FROM " & Query_Name & " " & _
"WHERE (" & Filter_Combo_Box2 & ") ORDER BY [Field_Name_For_Sorting];"
SRpt_Recset.SQL = Temp_Query
'Debug.print Temp_Query
SubReport.SourceObject = Temp_SourceObject
End Sub
组合框工作后,如果数据要像站点和项目号一样进行更改,则您可能需要更改组合框的行源,以使用使用从QueryAllData中选择不同站点的查询。我不知道是否Filter_Combo_Box2步骤,所以它可能需要一些更正。希望这会有所帮助。