当搜索字段为空时,在搜索表单中强制执行空查询
Force empty query in search form when search fields are blank
我创建了一个搜索表单,它使用其中的字段来过滤包含的子表单。这工作正常,除非搜索字段为空,查询中的所有记录都会显示。
我希望 用户在开始填写搜索条件之前看不到任何记录(仅当搜索字段为空时)。
注意:并非所有搜索条件都是必需的,因此在使用表单时某些字段可能为空。
另一个注意事项:我没有尝试过滤掉查询中的空白字段。
*** 编辑: 我有一个表格,我们称之为 frmA。在这个表单中有一个子表单,我们称它为 sfmB。 sfmB 的记录源是我们称为 qryB 的查询。
示例查询(再次正常工作):
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
AND (FieldB Like "*" & [Forms]![frmA]![FieldB] & "*") AND ...;
尝试过:
WHERE (IIf(IsNull([Forms]![frmA]![FieldA])=True, "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*"))...
也试过:
WHERE (IIf([Forms]![frmA]![FieldA])="", "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*")...
也试过:
WHERE (IIf([Forms]![frmA]![FieldA])=Null, "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*")...
试试这个:
WHERE ([Forms]![frmA]![FieldA] Not Is Null) AND (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
所有记录的原因 return 是空表单控件 return any 值,因为您没有使用通配符连接任何内容,所以 returns此搜索模式 **
在 LIKE
评估中。如下所示,带有空字符串或空值,此搜索模式 returns all 具有 any non-empty 字符的记录。
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & '' & "*")
AND (FieldB Like "*" & '' & "*") AND ...;
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & NULL & "*")
AND (FieldB Like "*" & NULL & "*") AND ...;
要解决此问题,请考虑将不会出现在您的列中的字符与 NZ()
替换字符连接起来。下面的逻辑现在将 return 按原样按形式搜索值的所有记录。但是,如果表单值为空,NZ()
将替换为 ~
,并且列中包含此字符的任何记录都将 return。假设该列中不存在 tilda,则没有记录输出。
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & NZ([Forms]![frmA]![FieldA], '~') & "*")
AND (FieldB Like "*" & NZ([Forms]![frmA]![FieldB], '~') AND ...;
事实证明,要完全实施,必须动态替换 NZ()
替换值。因此,考虑根据互斥条件合并 VBA:
当所有字段为空时,NZ()
应该使用 tilda (~
)。
当至少有一个字段是non-empty时,所有剩余的空字段'NZ()
应该使用通配符,星号(*
).
Dim i As Integer, num_search_fields As Integer
Dim strSQL As String
Dim var As Variant
i = 0
num_search_fields = 5
' LOOP THROUGH ALL SEARCH FIELDS
For Each var in Array("FieldA", "FieldB", "FieldC", "FieldD", "FieldE")
If IsNull(Forms("frmA").Controls(var).Value) Then
i = i + 1
End If
Next var
' CONDITIONALLY BUILD SQL
If i = num_search_fields Then
strSQL = "SELECT FieldA, FieldB, FieldC, FieldD, FieldE" _
& " FROM tblA" _
& " WHERE (FieldA Like '*' & NZ([Forms]![frmA]![FieldA], '~') & '*')" _
& " AND (FieldB Like '*' & NZ([Forms]![frmA]![FieldB], '~') & '*')" _
& " AND (FieldC Like '*' & NZ([Forms]![frmA]![FieldC], '~') & '*')" _
& " AND (FieldD Like '*' & NZ([Forms]![frmA]![FieldD], '~') & '*')" _
& " AND (FieldE Like '*' & NZ([Forms]![frmA]![FieldE], '~') & '*')"
Else
strSQL = "SELECT FieldA, FieldB, FieldC, FieldD, FieldE" _
& " FROM tblA" _
& " WHERE (FieldA Like '*' & NZ([Forms]![frmA]![FieldA], '*') & '*')" _
& " AND (FieldB Like '*' & NZ([Forms]![frmA]![FieldB], '*') & '*')" _
& " AND (FieldC Like '*' & NZ([Forms]![frmA]![FieldC], '*') & '*')" _
& " AND (FieldD Like '*' & NZ([Forms]![frmA]![FieldD], '*') & '*')" _
& " AND (FieldE Like '*' & NZ([Forms]![frmA]![FieldE], '*') & '*')"
End If
' ASSIGN SQL STRING TO SUBFORM RECORDSOURCE
Forms!frmA!subform.Form.RecordSource = strSQL
Forms!frmA!subform.Form.Requery
如果您希望在 all 搜索条件为空时不返回任何记录,那么您必须在 WHERE 子句中明确且单独地测试此条件。类似于:
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE
NOT ( IsNull([Forms]![frmA]![FieldA])
AND IsNull([Forms]![frmA]![FieldB])
AND IsNull([Forms]![frmA]![FieldC])
AND IsNull([Forms]![frmA]![FieldD])
AND IsNull([Forms]![frmA]![FieldE]) )
AND (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
AND (FieldB Like "*" & [Forms]![frmA]![FieldB] & "*") AND ...;
因此,如果 frmA 上的所有搜索字段均为空,则 NOT (...)
括号内的条件将为 TRUE
,NOT
会将其变为 FALSE
并且所以你的整个 WHERE
子句将是 FALSE
并且不会返回任何行。如果搜索字段有任何值,则 NOT (...)
内将是 FALSE
,NOT
将变成此 TRUE
,然后是您的其余部分应用的任何其他条件WHERE
条款将发挥作用。
编辑 - 我刚刚 re-read 来自 Parfait 的回答,实际上我认为这是一个更简洁的解决方案!
我创建了一个搜索表单,它使用其中的字段来过滤包含的子表单。这工作正常,除非搜索字段为空,查询中的所有记录都会显示。
我希望 用户在开始填写搜索条件之前看不到任何记录(仅当搜索字段为空时)。
注意:并非所有搜索条件都是必需的,因此在使用表单时某些字段可能为空。
另一个注意事项:我没有尝试过滤掉查询中的空白字段。
*** 编辑: 我有一个表格,我们称之为 frmA。在这个表单中有一个子表单,我们称它为 sfmB。 sfmB 的记录源是我们称为 qryB 的查询。
示例查询(再次正常工作):
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
AND (FieldB Like "*" & [Forms]![frmA]![FieldB] & "*") AND ...;
尝试过:
WHERE (IIf(IsNull([Forms]![frmA]![FieldA])=True, "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*"))...
也试过:
WHERE (IIf([Forms]![frmA]![FieldA])="", "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*")...
也试过:
WHERE (IIf([Forms]![frmA]![FieldA])=Null, "", FieldA
Like "*" & [Forms]![frmA]![FieldA] & "*")...
试试这个:
WHERE ([Forms]![frmA]![FieldA] Not Is Null) AND (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
所有记录的原因 return 是空表单控件 return any 值,因为您没有使用通配符连接任何内容,所以 returns此搜索模式 **
在 LIKE
评估中。如下所示,带有空字符串或空值,此搜索模式 returns all 具有 any non-empty 字符的记录。
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & '' & "*")
AND (FieldB Like "*" & '' & "*") AND ...;
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & NULL & "*")
AND (FieldB Like "*" & NULL & "*") AND ...;
要解决此问题,请考虑将不会出现在您的列中的字符与 NZ()
替换字符连接起来。下面的逻辑现在将 return 按原样按形式搜索值的所有记录。但是,如果表单值为空,NZ()
将替换为 ~
,并且列中包含此字符的任何记录都将 return。假设该列中不存在 tilda,则没有记录输出。
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE (FieldA Like "*" & NZ([Forms]![frmA]![FieldA], '~') & "*")
AND (FieldB Like "*" & NZ([Forms]![frmA]![FieldB], '~') AND ...;
事实证明,要完全实施,必须动态替换 NZ()
替换值。因此,考虑根据互斥条件合并 VBA:
当所有字段为空时,
NZ()
应该使用 tilda (~
)。当至少有一个字段是non-empty时,所有剩余的空字段'
NZ()
应该使用通配符,星号(*
).
Dim i As Integer, num_search_fields As Integer
Dim strSQL As String
Dim var As Variant
i = 0
num_search_fields = 5
' LOOP THROUGH ALL SEARCH FIELDS
For Each var in Array("FieldA", "FieldB", "FieldC", "FieldD", "FieldE")
If IsNull(Forms("frmA").Controls(var).Value) Then
i = i + 1
End If
Next var
' CONDITIONALLY BUILD SQL
If i = num_search_fields Then
strSQL = "SELECT FieldA, FieldB, FieldC, FieldD, FieldE" _
& " FROM tblA" _
& " WHERE (FieldA Like '*' & NZ([Forms]![frmA]![FieldA], '~') & '*')" _
& " AND (FieldB Like '*' & NZ([Forms]![frmA]![FieldB], '~') & '*')" _
& " AND (FieldC Like '*' & NZ([Forms]![frmA]![FieldC], '~') & '*')" _
& " AND (FieldD Like '*' & NZ([Forms]![frmA]![FieldD], '~') & '*')" _
& " AND (FieldE Like '*' & NZ([Forms]![frmA]![FieldE], '~') & '*')"
Else
strSQL = "SELECT FieldA, FieldB, FieldC, FieldD, FieldE" _
& " FROM tblA" _
& " WHERE (FieldA Like '*' & NZ([Forms]![frmA]![FieldA], '*') & '*')" _
& " AND (FieldB Like '*' & NZ([Forms]![frmA]![FieldB], '*') & '*')" _
& " AND (FieldC Like '*' & NZ([Forms]![frmA]![FieldC], '*') & '*')" _
& " AND (FieldD Like '*' & NZ([Forms]![frmA]![FieldD], '*') & '*')" _
& " AND (FieldE Like '*' & NZ([Forms]![frmA]![FieldE], '*') & '*')"
End If
' ASSIGN SQL STRING TO SUBFORM RECORDSOURCE
Forms!frmA!subform.Form.RecordSource = strSQL
Forms!frmA!subform.Form.Requery
如果您希望在 all 搜索条件为空时不返回任何记录,那么您必须在 WHERE 子句中明确且单独地测试此条件。类似于:
SELECT FieldA, FieldB, FieldC, FieldD, FieldE
FROM tblA
WHERE
NOT ( IsNull([Forms]![frmA]![FieldA])
AND IsNull([Forms]![frmA]![FieldB])
AND IsNull([Forms]![frmA]![FieldC])
AND IsNull([Forms]![frmA]![FieldD])
AND IsNull([Forms]![frmA]![FieldE]) )
AND (FieldA Like "*" & [Forms]![frmA]![FieldA] & "*")
AND (FieldB Like "*" & [Forms]![frmA]![FieldB] & "*") AND ...;
因此,如果 frmA 上的所有搜索字段均为空,则 NOT (...)
括号内的条件将为 TRUE
,NOT
会将其变为 FALSE
并且所以你的整个 WHERE
子句将是 FALSE
并且不会返回任何行。如果搜索字段有任何值,则 NOT (...)
内将是 FALSE
,NOT
将变成此 TRUE
,然后是您的其余部分应用的任何其他条件WHERE
条款将发挥作用。
编辑 - 我刚刚 re-read 来自 Parfait 的回答,实际上我认为这是一个更简洁的解决方案!