具有多个可搜索字段和 NULL 值的 MSAccess 动态搜索表单
MSAccess dynamic search form with multiple searchable fields and NULL values
我的 MSAccess 应用程序中有一个表单,可以跨 4 个字段搜索 master 数据库。您可以在 1 个字段中填写尽可能少的内容,也可以在所有 4 个字段中填写尽可能多的内容,或者在您想要的两者之间的任何地方填写。
要搜索的数据库字段是:
- rmanbr - 整数
- custNbr - 整数
- 客户名称 - 文本
- invcmnbr - 文本(因为它将存储发票编号 (######) 或贷项通知单编号 (CM-####)
表单有 4 个字段,可按以上各项排序:
- SrchRMANbr
- SrchCustNbr
- SrchCoName
- SrchInvCMNbr
我有一个查询选择要显示的所有数据。要过滤的 4 个字段用 Like "*" & [forms]![RMA Search]![FieldName] & "*"
填充到该特定查询的查询构建器的条件部分
数据库中的 rmanbr 和 customername 字段永远不会为 NULL,这是不允许的。但是,invcmnbr 和 custnbr 可以并且经常是没有值的 NULL。
所以,我的搜索表单是上面列出的 4 个 Srch
字段,用户可以在其中输入他们想要过滤的内容。有一个列表框旨在根据用户将用于过滤结果的文本框的 "On Change" 开始过滤结果。然后用户选择记录并继续他的快乐方式。
但是,ListBox 会从两个可以为 NULL 的字段中过滤掉所有 NULL 值,无论对应的 Srch
框是否为空,因此 custnbr
或 invcmnbr
字段未显示在列表框中。
我已经尝试将 Is Null
填充到我用来填充列表框的查询的 "Or" 条件中。我在 Query Builder Criteria 部分 "Is Null" 的第二行尝试了它,如果它们具有 NULL 值,即使我在 SrchRMANbr
字段中输入了一个数字,它也会显示所有行。理想情况下,在 RMANbr 中输入将由 RMANbr 过滤是否存在 NULL 值,因为这是一个唯一值(master table 中的任何 RMANbr 只能有 1 个)。如果我在条件中的 Like "*" & [forms]![RMA Search]![FieldName] & "*"
之后(在同一行)Or Is Null
它会让我更接近,但是对 SrchCustNbr
或 SrchInvCMNbr
字段的任何搜索都会产生筛选结果以及该字段的所有 NULL 值。
所以,简而言之,我需要一种方法来:
1) 在用户开始在任何字段中输入数据之前,在列表框中显示所有值,无论是否为 NULL。
2) 当用户开始将数据输入 SrchCustNbr
或 SrchInvCMNbr
字段时过滤掉 NULL 值。
3) 保留 NULL 值,但当用户开始将数字输入 SrchRMANbr
时按 RMA Nbr
正确过滤(因为这是主记录,所以它和它一样具体可以获得)
我希望我正确地传达了这个问题。如果您需要任何其他信息来帮助我解决问题,请告诉我。
如你所见,填表格!查询中的表达式很快就会变得非常混乱。
更糟糕的是,查询现在是 "married" 并附加到那个 ONE 表单。通常,我有一个很好的查询,我可以对不同的报告使用多次,而且通常甚至相同的查询也可以用于报告......但是有人出现并输入一个表达式,这意味着查询只有在表格已打开。
更糟糕的是,很难控制诸如拥有 5 个组合框之类的东西,但用户只在其中 3 个组合框中选择限制...并希望忽略其他 2 个。
我可能会再写 10 或页面来说明为什么将表单表达式放在查询中是不好的(此外......它使查询变得非常丑陋,难以阅读。而且,sql 然后是不再标准(它也不适用于基于服务器的系统)。
因此,解决方案是简单地从表单中获取值,并在代码中构建您自己的 where 子句。这样,您只需设计报告(或表格),并将它们附加到查询,但没有表格!条件放在查询中。
要将"send"条件添加到报告(或表格)中,您只需使用"where" 子句。这正是 ms-access 具有此功能的原因……它解决了无数问题……并将大大降低您的开发成本。
看看下面的屏幕截图,看看我的意思:
http://www.kallal.ca/ridesrpt/ridesrpt.html
当您点击 "print" 按钮时,使上述屏幕工作并启动具有选定限制的报告的代码很简单:
dim strWhere as string
' select sales rep combo
if isnull(cboSalesRep) = false then
strWhere = "SalesRep = " & cboSalesRep & ""
end if
' select what City for the report
if isnull(cboCity) = false then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "City = " & cobCity & ""
end if
注意第二次组合测试是如何设置的。您可以添加 "many" 更多您想要的条件。假设我们有一个复选框只包含特殊客户。我们可以在非常漂亮的提示屏幕上添加一个复选框
[x] Show Only Special customers
我们添加的代码是:
if chkSpeicalOnly = True then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "SpecialCust = true"
end if
当然,我们添加到漂亮的报告屏幕的每个组合和控件都需要一些代码,但不会比查询生成器更混乱..这样,每个查询都很好,干净,没有一堆高度不可维护的表格!表达式。
此外,这意味着您可以对不同的报告重复使用相同的查询,而不必担心某些应该打开的表单。所以,稍微多一点代码就可以解决乱七八糟的查询问题。对我来说,这是非常值得的交易。
使用此处发布的解决方案: 并由 Andre
指出
我只是在 CustNbr 和 InvCMNbr 字段中的原始 Like "*" & [forms]![RMA Search]![FieldName] & "*"
之后添加了 Or ([forms]![RMA Search]![SrchCustNbr] Is Null)
,这已经奏效了。
我的 MSAccess 应用程序中有一个表单,可以跨 4 个字段搜索 master 数据库。您可以在 1 个字段中填写尽可能少的内容,也可以在所有 4 个字段中填写尽可能多的内容,或者在您想要的两者之间的任何地方填写。
要搜索的数据库字段是:
- rmanbr - 整数
- custNbr - 整数
- 客户名称 - 文本
- invcmnbr - 文本(因为它将存储发票编号 (######) 或贷项通知单编号 (CM-####)
表单有 4 个字段,可按以上各项排序:
- SrchRMANbr
- SrchCustNbr
- SrchCoName
- SrchInvCMNbr
我有一个查询选择要显示的所有数据。要过滤的 4 个字段用 Like "*" & [forms]![RMA Search]![FieldName] & "*"
填充到该特定查询的查询构建器的条件部分
数据库中的 rmanbr 和 customername 字段永远不会为 NULL,这是不允许的。但是,invcmnbr 和 custnbr 可以并且经常是没有值的 NULL。
所以,我的搜索表单是上面列出的 4 个 Srch
字段,用户可以在其中输入他们想要过滤的内容。有一个列表框旨在根据用户将用于过滤结果的文本框的 "On Change" 开始过滤结果。然后用户选择记录并继续他的快乐方式。
但是,ListBox 会从两个可以为 NULL 的字段中过滤掉所有 NULL 值,无论对应的 Srch
框是否为空,因此 custnbr
或 invcmnbr
字段未显示在列表框中。
我已经尝试将 Is Null
填充到我用来填充列表框的查询的 "Or" 条件中。我在 Query Builder Criteria 部分 "Is Null" 的第二行尝试了它,如果它们具有 NULL 值,即使我在 SrchRMANbr
字段中输入了一个数字,它也会显示所有行。理想情况下,在 RMANbr 中输入将由 RMANbr 过滤是否存在 NULL 值,因为这是一个唯一值(master table 中的任何 RMANbr 只能有 1 个)。如果我在条件中的 Like "*" & [forms]![RMA Search]![FieldName] & "*"
之后(在同一行)Or Is Null
它会让我更接近,但是对 SrchCustNbr
或 SrchInvCMNbr
字段的任何搜索都会产生筛选结果以及该字段的所有 NULL 值。
所以,简而言之,我需要一种方法来:
1) 在用户开始在任何字段中输入数据之前,在列表框中显示所有值,无论是否为 NULL。
2) 当用户开始将数据输入 SrchCustNbr
或 SrchInvCMNbr
字段时过滤掉 NULL 值。
3) 保留 NULL 值,但当用户开始将数字输入 SrchRMANbr
时按 RMA Nbr
正确过滤(因为这是主记录,所以它和它一样具体可以获得)
我希望我正确地传达了这个问题。如果您需要任何其他信息来帮助我解决问题,请告诉我。
如你所见,填表格!查询中的表达式很快就会变得非常混乱。
更糟糕的是,查询现在是 "married" 并附加到那个 ONE 表单。通常,我有一个很好的查询,我可以对不同的报告使用多次,而且通常甚至相同的查询也可以用于报告......但是有人出现并输入一个表达式,这意味着查询只有在表格已打开。
更糟糕的是,很难控制诸如拥有 5 个组合框之类的东西,但用户只在其中 3 个组合框中选择限制...并希望忽略其他 2 个。
我可能会再写 10 或页面来说明为什么将表单表达式放在查询中是不好的(此外......它使查询变得非常丑陋,难以阅读。而且,sql 然后是不再标准(它也不适用于基于服务器的系统)。
因此,解决方案是简单地从表单中获取值,并在代码中构建您自己的 where 子句。这样,您只需设计报告(或表格),并将它们附加到查询,但没有表格!条件放在查询中。
要将"send"条件添加到报告(或表格)中,您只需使用"where" 子句。这正是 ms-access 具有此功能的原因……它解决了无数问题……并将大大降低您的开发成本。
看看下面的屏幕截图,看看我的意思:
http://www.kallal.ca/ridesrpt/ridesrpt.html
当您点击 "print" 按钮时,使上述屏幕工作并启动具有选定限制的报告的代码很简单:
dim strWhere as string
' select sales rep combo
if isnull(cboSalesRep) = false then
strWhere = "SalesRep = " & cboSalesRep & ""
end if
' select what City for the report
if isnull(cboCity) = false then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "City = " & cobCity & ""
end if
注意第二次组合测试是如何设置的。您可以添加 "many" 更多您想要的条件。假设我们有一个复选框只包含特殊客户。我们可以在非常漂亮的提示屏幕上添加一个复选框
[x] Show Only Special customers
我们添加的代码是:
if chkSpeicalOnly = True then
if strWhere <> "" then
strWhere = strWhere " and "
endif
strWhere = strWhere & "SpecialCust = true"
end if
当然,我们添加到漂亮的报告屏幕的每个组合和控件都需要一些代码,但不会比查询生成器更混乱..这样,每个查询都很好,干净,没有一堆高度不可维护的表格!表达式。
此外,这意味着您可以对不同的报告重复使用相同的查询,而不必担心某些应该打开的表单。所以,稍微多一点代码就可以解决乱七八糟的查询问题。对我来说,这是非常值得的交易。
使用此处发布的解决方案:
我只是在 CustNbr 和 InvCMNbr 字段中的原始 Like "*" & [forms]![RMA Search]![FieldName] & "*"
之后添加了 Or ([forms]![RMA Search]![SrchCustNbr] Is Null)
,这已经奏效了。