【问题标题】:MS Access displaying vba select query in datasheetMS Access 在数据表中显示 vba 选择查询
【发布时间】:2019-03-16 15:08:09
【问题描述】:

在ms access vba里面学习使用SQL。我已经了解了选择查询的工作原理,但它们不会像通过访问表单构建的那样立即输出到数据表。我需要复杂的 if else 链来获得我想要的东西,所以我不得不使用 vba 路由。 我已经尝试了其他问题中建议的几种方法,但它们并没有像我想要的那样工作。

我正在为一个按钮创建代码,该按钮根据复选框显示具有特定元素的数据表。下面的代码只是关于显示 Select 查询的元素。

我尝试了 .QueryDef 方法

Dim qd As QueryDef
Set qd = CurrentDb.CreateQueryDef("")

With qd
    .ReturnsRecords = True
    .sql = "SELECT * FROM EXPORT_CERTIFICATION WHERE EXPORT_CERTIFICATION.CertificationStatus = 'Certified'"
End With

当我输入查询名称而不是为空时,这有效但只有一次。它创建了一个新查询,它可以满足我的需求,但之后该按钮就不再执行任何操作了。

我应该创建一个表来接受输出并尝试将该表设置为由 sql 语句创建的记录集吗?我想避免使用另一个表,因为这只是用于查看。

这是我目前尝试的更简单解决方案的完整代码

Private Sub NDC_CERT_VIEW_Click()
Dim StrSQLclause As String
Dim db1 As DAO.Database, qry1 As DAO.QueryDef

Set db1 = CurrentDb()

Set qry1 = db1.QueryDefs("NDC_EXPORT_VIEW")

MsgBox ("Here")
If (Certified_Check And Not Revised_Check And Not Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' "
ElseIf (Not Certified_Check And Revised_Check And Not Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' "
ElseIf (Not Certified_Check And Not Revised_Check And Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null "
ElseIf (Not Certified_Check And Not Revised_Check And Not Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = '' "
ElseIf (Certified_Check And Revised_Check And Not Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' "
ElseIf (Not Certified_Check And Revised_Check And Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null Or EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' "
ElseIf (Not Certified_Check And Not Revised_Check And Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' "
ElseIf (Certified_Check And Not Revised_Check And Not Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' "
ElseIf (Not Certified_Check And Revised_Check And Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' Or EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null "
ElseIf (Certified_Check And Not Revised_Check And Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' Or EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null "
ElseIf (Certified_Check And Revised_Check And Not Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' "
ElseIf (Certified_Check And Revised_Check And Doc_Exceptions_Check And Not Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null Or EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' "
ElseIf (Certified_Check And Revised_Check And Doc_Exceptions_Check And Pending_Check) Then
    StrSQLclause = "Select * From EXPORT_NDC_CERTIFICATION Where EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Certified' Or EXPORT_NDC_CERTIFICATION.CertificationStatus = 'Revised' Or EXPORT_NDC_CERTIFICATION.DocumentException Not Is Null Or EXPORT_NDC_CERTIFICATION.CertificationStatus = '' "
Else
    MsgBox ("No Status Selected")
    Exit Sub
End If
MsgBox (StrSQLclause)
MsgBox ("Here3")

qry1.sql = StrSQLclause
MsgBox ("Here4")
DoCmd.OpenQuery "NDC_EXPORT_VIEW"

MsgBox ("Here6")

【问题讨论】:

  • 为什么不直接保存为命名查询,然后在数据表视图中打开该查询? ...DoCmd.OpenQuery "YourQueryName"
  • 每个复选框组合需要执行的 SQL 是不同的,我有一个 if else 链可以在组合之间进行选择。每个 if 块将 SQL 语句保存到一个字符串,然后在该块之后,我希望执行 select 语句并将其显示在数据表中。我尝试使用现有的选择查询,然后更新其 SQl,但这似乎不起作用。
  • 哪里失败了,错误信息是什么?
  • 如果将Not Is Null 更改为Is Not Null 会发生什么?
  • 请意识到您实际上是在问我们如何在数据表视图中显示损坏的 SQL。这是不可能的。

标签: sql vba ms-access select datasheet


【解决方案1】:

就个人而言,我使用以下代码来显示记录集。

像 Darren 的回答一样,我创建了一个名为 frmDynDS 的表单,默认视图设置为数据表视图,并且我使用以下代码向其中添加了 255 个控件(在设计表单时运行查看):

Dim i As Long
Dim myCtl As Control
For i = 0 To 254
    Set myCtl = Application.CreateControl("frmDynDS", acTextBox, acDetail)
    myCtl.Name = "Text" & i
Next i

然后,我将以下代码添加到表单的模块中:

Public Myself As Object

Public Sub LoadRS(myRS As Object)
    'Supports both ADODB and DAO recordsets
    Dim i As Long
    Dim myTextbox As textbox
    Dim fld As Object
    i = 0
    With myRS
        For Each fld In myRS.Fields
            Set myTextbox = Me.Controls("Text" & i)
            myTextbox.Properties("DatasheetCaption").Value = fld.Name
            myTextbox.ControlSource = fld.Name
            myTextbox.ColumnHidden = False
            myTextbox.columnWidth = -2
            i = i + 1
        Next fld
    End With
    For i = i To 254
        Set myTextbox = Me.Controls("Text" & i)
        myTextbox.ColumnHidden = True
    Next i
    Set Me.Recordset = myRS
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set Myself = Nothing 'Prevent memory leak
End Sub

然后,我在公共模块中获得了以下代码:"

Public Sub DisplayRS(rs As Object)
    Dim f As New Form_frmDynDS
    f.LoadRS rs
    f.Visible = True
    Set f.Myself = f
End Sub

完成所有这些设置后,显示记录集就非常简单了。只需执行以下操作:

DisplayRS CurrentDb.OpenRecordset("SELECT * FROM EXPORT_CERTIFICATION WHERE EXPORT_CERTIFICATION.CertificationStatus = 'Certified'")

这将打开表单,使适当数量的控件可见,设置标题,调整单元格宽度以适应标题,然后将控件绑定到记录集。表单将一直持续到关闭,您可以使用此代码同时打开多个记录集。

请注意,运行此代码时不能在记录集中使用参数,因为它会在过滤/排序时崩溃。

【讨论】:

  • 这可能是一个菜鸟问题。我在哪里运行该控件添加代码?
  • 公共模块应该可以工作。只需将它包装在一个子中,然后从即时窗口中调用它。记得先创建表单并在设计视图中打开它。
  • 这很好用。我找到了一个更简单的方法,但这种方法有更多的扩展用途,我肯定会在即将到来的增强功能中使用它。谢谢埃里克
【解决方案2】:

我建议使用预构建的表单和查询来实现您在此处尝试实现的目的。

但是,话虽如此,您正在学习在 VBA 中使用 SQL,所以这里是如何使用代码来做到这一点(其他方式很可能):

  • 创建一个基本表单并为每个表单添加正确数量的控件 记录。
  • 为表单设置Has Module 属性(在Other 选项卡)到
  • Default View 设置为DataSheet
  • 将表单另存为MyForm

添加一个 VBA 代码模块并添加此代码:

Sub Test()

    Dim qd As DAO.QueryDef
    Dim rs As DAO.Recordset
    Dim frm As Form_MyForm

    Set qd = CurrentDb.CreateQueryDef("", "PARAMETERS Stats Text(255); " & _
                                          "SELECT * FROM EXPORT_CERTIFICATION " & _
                                          "WHERE CertificationStatus = Stats")

    qd.Parameters("Stats") = "Certified"

    Set rs = qd.OpenRecordset

    Set frm = New Form_MyForm

    'The record source for the form
    Set frm.Recordset = rs

    'The record source fields attached to each control.
    frm.Text0 = "FieldA"
    frm.Text2 = "Field"
    frm.Text3 = "CertificationStatus"

    frm.Visible = True

    Debug.Assert False 'Form will disappear when code ends, so pause here.

End Sub

将出现一个包含您的记录集的表单。

【讨论】:

  • 关于在绑定表单中使用带有参数的查询的强烈警告:对绑定到带有参数的 DAO 记录集的表单进行排序和过滤可能会导致 Access 硬崩溃,从而丢失任何未保存的工作。见this question
  • @Erik - 从来不知道。我会阅读您链接到的问题。
  • 抱歉,查看链接问题后删除了我的第一条评论。
  • 感谢达伦的回复。对于 frm.Text0... 部分,我必须列出所有列标题吗?你也能解释一下SQL语句吗? “PARAMETERS Stats Text(255);”是什么意思?做?以及为什么“CertificationStatus = Stats”只能在下一行更改(?)它
  • 查询的PARAMETERS 部分是在查询中包含参数的另一种方式——而不是盲目地将任何传递的文本字符串添加到 WHERE 子句中,它允许您指定您期望的数据类型(避免任何 SQL 注入攻击)并且还允许查询不绑定到特定的参数源,例如表单 - 通常你会说“WHERE SomeValue = GetSomeValueFromForm”,使用参数你可以从表单中提供值,或变量或函数的结果,然后运行查询 - 它与打开的特定表单无关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 2011-05-08
  • 1970-01-01
相关资源
最近更新 更多