从表单上的多个组合框控制 Access SQL 查询

Posted

技术标签:

【中文标题】从表单上的多个组合框控制 Access SQL 查询【英文标题】:Controlling an Access SQL query from multiple combo boxes on a form 【发布时间】:2011-03-25 11:55:39 【问题描述】:

按照各种半相关的教程试图弄清楚如何将驻留在表单上的组合框字段发送到查询,我陷入了正确的混乱之中。

我正在使用查询来生成联系人详细信息的子集,从中为邮寄广告活动制作标签。我希望组合框为空或结合使用,因此我可以过滤选择的组合。 我已经让我的组合框进行查找以检索它们的值,并找到了一个关于使用 IS NULL 的好教程,但我不明白 VBA 创建“查看结果”和“清除表单”命令按钮所必需的。

这些是我在查询字段条件中引用的组合框的名称:

[Forms]![SearchForm]![cboStatus]
[Forms]![SearchForm]![cboNewsletter]

这些字段分别称为状态和描述。

我正在过滤的查询被称为

qryFilter

这些是我的命令按钮的名称:

cmdResults 
cmdClear

cmdResults 应该将每个组合框值发送到查询,无论它们是 null 还是选中,但我无法让它工作,并且 clear 应该使组合框为 null。

我希望扩展它以包含更多标准,但我想先让它发挥作用!

任何帮助表示赞赏,在此先感谢, 抢

编辑: 试图改编帕特里克的这段代码:

Private Sub cmdResults_Click()
 Dim tsSql As String
 tsSql = "SELECT * FROM qryAll WHERE "

If cboNewsletter <> "" And Not IsNull(cboNewsletter) Then
 tsSql = tsSql & "qryCorrespondence.NID = " & cboNewsletter & " "
    If (cboStatus <> "" And Not IsNull(cboStatus)) Then
    tsSql = tsSql & " AND "
    End If
 End If

If cboStatus <> "" And Not IsNull(cboStatus) Then
  tsSql = tsSql & "tblCustomers.Status = " & cboStatus & " "
End If

Dim rs As New ADODB.Recordset
rs.Open tsSql, CurrentProject.AccessConnection, 3, 3
End Sub

最后一行给了我一个错误,它在调试器中突出显示了以下行:

    rs.open tsSql, CurrentProject.AccessConnection, 3, 3,

并且在 WHERE 子句中说语法错误

有什么建议吗?

【问题讨论】:

你得到的错误是什么?它试图创建一个记录集......这甚至可能不是你最终需要做的。您正在编写的查询,它适用于表单上的什么? 感谢您的帮助,我希望使用该查询来即时创建我的客户数据库的子集,即列出我们一个多月未联系的当前客户或潜在客户没有收到任何东西的客户。然后我希望将生成的表插入到相关记录的表中。 编辑了我原来的帖子 要确定sql有什么问题,您可以在按钮单击事件上放置一个断点,然后在添加过滤器后在即时窗口中执行一个?tssl。它将为您提供 sql 的字符串表示形式……这样看起来更容易。 tsSql 字符串几乎可以用于任何事情,我通常使用 sup 表单并将源设置为 tssql,这样看起来很不错。 然后您可能可以摆脱 rs.open 行。 一直在使用 Debug.Print,我从 tsSql 字符串中得到的只是 SELECT * FROM qryAll WHERE。看起来它不喜欢 IF 语句? 【参考方案1】:

这是按表单查询接口的典型情况。我的做法是在表单模块中有一个编写 WHERE 子句的子例程,如下所示:

  Private Function GetWhere() As String
    Dim strTemp As String

    If Not IsNull(Me!cboStatus) Then
       strTemp = strTemp & " AND tblCustomers.Status = " & Chr(34) & Me!cmbStatus & Chr(34)
    End If
    If Not IsNull(Me!cboNewsletter) Then
       strTemp = strTemp & " AND qryCorrespondence.NID = " & Chr(34) & Me!cboNewsletter & Chr(34)
    End If
    strTemp = Mid(strTemp, 6)
    If Len(strTemp) > 0 Then
       GetWhere = " WHERE " & strTemp
    End If
  End Function

(上面的代码假设tblCustomers.StatusqryCorrespondence.NIDqryAll的SELECT语句中可用)

在 cmdResults 的 OnClick() 事件中,可以这样使用:

  Dim strSQL As String

  strSQL = "SELECT * FROM qryAll"
  strSQL = strSQL & GetWhere()

  [do with strSQL whatever you want]

如果两个组合框都没有选择值,上述代码将返回所有记录。

对于您的 cmbClear,您只需将两个组合框设置为 Null 的代码。

【讨论】:

感谢您回答大卫,这对我很有帮助,我的 VBA 知识很差,但我正在学习。如何将整个 SQL 字符串传递到查询中,而不是将表单字段传递到预构建查询的 SQL 中?我试过“DestinationList.RecordSource = strSQL”但无济于事! 我将上面代码中构造的 SQL 字符串用于两件事之一,将记录插入临时表,或将它们加载到表单中。如果您有一个想要显示记录的表单,那么只需将表单的 Recordsource 属性设置为 SQL 字符串。【参考方案2】:

在 Access 中确实没有干净的方法来做到这一点。

假设我有三个组合框,名为:

cmb名称 城市银行 cmbState

还有一个按钮名为:

btnDoWork

现在,如果我想根据按钮单击的组合按钮的内容运行查询,它可能看起来像这样:

Private Sub btnDoWork_Click()
     Dim tsSql as String
     tsSql = "SELECT * FROM tblUser WHERE "

  If cmbName <> "" and Not ISNull(cmbName) Then
     tsSql = tsSql & "user_name = " & cmbName & " "
    if (cmbCity <> "" and Not IsNull(cmbCity)) or (cmbState <> "" and Not IsNull(cmbState))
         tsSql = tsSql & " AND "
    end if
 End If

 if cmbCity <> "" and not isnull(cmbcity) then
      tsSql = tsSql & "city = " & cmbcity & " "
      if cmbState <> "" and Not IsNull(cmbState) then
           tsSql = tsSql & " AND "
      end if
 end if

if cmbState <> "" and not is null(cmbState) then
      tsSql = tsSql & "state = " & cmbState
end if

MyControl.RowSource = tsSql

End Sub 

如果您愿意,我相信您可以将其更改为包含空值。我的版本不包括空值。

如果您尝试在多列列表框或其他控件中返回结果,则需要确保控件的行源类型设置为表/查询,并且您可以将控件源设置为:

MyControl.RowSource = tsSql

【讨论】:

如果我想将其更改为 cmbName 和 cmbCity 是否只删除最后的 if 语句?倒数第二行的3s需要换成2s吗? 是的,然后您必须删除在城市检查中添加 AND 的 if 语句。这三个代表游标类型和锁定类型,因此您打算使用哪种类型进行锁定。这里有更多信息:w3schools.com/ADO/met_rs_open.asp 我不同意“在 Access 中没有干净的方法来做到这一点”。您只需要即时编写 SQL。 与许多其他 sql 应用程序相比,考虑到其他“企业”应用程序的能力,“动态编写 SQL”并不完全干净。 我觉得这很有趣。 @Patrick,您似乎认为访问“企业”应用程序(因为您使用比较的“其他”)。我不知道您可能在谈论什么应用程序,因为据我所知只有两个这样的应用程序可以与 Access 相媲美(FileMaker Pro 和 OpenOffice Base),而且据我所知,它们也没有让这变得容易.我认为最初的问题使用了令人困惑的术语,也许我只是以不同的方式解释了这个问题。另一方面,你的答案就像我的答案一样写了即时 SQL,所以我们似乎对它的解释是一样的。【参考方案3】:

我找到了一个有效的代码 按以下条件输入查询设计器:

[Forms]![myForm]![myControl] OR [Forms]![myForm]![myControl] Is Null 如果您的问题是如何使组合框为空,您将需要使用comboBox = Null 而不是comboBox ="",因为这会给字符串一个空字符串,而Null 正在彻底清理它。

【讨论】:

以上是关于从表单上的多个组合框控制 Access SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

表链接表单上的 MS Access 绑定组合框

如何在 Access 中将一个控件源与来自用户表单的多个组合框一起使用?

Access 2013 - 由表单上的组合框过滤的嵌入式查询

如何过滤表单中具有多个组合框的 Access 子表单?

访问:如果从组合框中选择了以“(REF)”开头的值,则勾选表单上的复选框

当用户从 MS Access 的组合框中选择“其他”时,如何显示输入表单?