在ms Access 2010数据库中的“选择查询中使用之间”存在问题

时间:2019-05-03 08:28:38

标签: sql access-vba ms-access-2010

早晨,请有人可以帮助我使此SELECT查询正常工作吗?我有一个窗体(frm_Reports),在该窗体上有两个文本框(Text98和Text100都被格式化为采用ShortDate格式)和一个按钮(RunReport)。用户在Text98中输入开始日期,在Text100中输入结束日期,然后单击RunReport按钮。来自Text98和Text100的日期存储在变量中,作为Dates(分别称为stardate和enddate),然后运行SELECT查询(请参见下面的代码),以检索表中的所有记录(tbl_details)中具有输入日期(在a下)标题为DateTime的列)落在用户输入的开始日期和结束日期之间。问题是我无法使SELECT查询正常工作。

我不擅长sql类型的语句,因此我尝试一次构建查询字符串,同时对其进行测试。我已经成功地做到了这一点:

sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) > #" & startdate & "#;

但是,一旦我尝试将此字符串转换为BETWEEN类型查询,我就会得到

  

“运行时错误'13':类型不匹配。

    Private Sub RunReport_Click()

    Dim selectedreport As String
    Dim startdate As Date
    Dim enddate As Date
    Dim sqlstr As String

    selectedreport = Me.ComboReport.Column(1)
    startdate = Me.Text98
    enddate = Me.Text100
    'sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) > #28/04/2019#;" - THIS WORKS
    'sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) > #" & startdate & "#;" - THIS WORKS
    sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) BETWEEN #" & startdate & "#" And "#" & enddate & "#;" 'THIS DOES NOT WORK

    Dim dbs As Database
    Dim rst As Recordset

    Set dbs = CurrentDb
    Set rst = dbs.OpenRecordset(sqlstr)
    With rst
        While Not .EOF()
        vName = .Fields("DateTime").Value
        Debug.Print vName

    .MoveNext
    Wend
    End With

    dbs.Close

    End Sub

如果有人可以告诉我该说法出了什么问题并提出切实可行的建议,我将不胜感激。谢谢

3 个答案:

答案 0 :(得分:0)

我认为您必须检查两件事:

  1. 在您的第一个注释SQL中,您拥有一个固定值#28/04/2019#而不是enddate变量。您必须检查它是否也适用于该变量。

  2. 问题可能出在您的日期格式dd/mm/yyyy上。如果未显式显示,则如果日期为<= 12(可能是一个月),则Access查询解释器会将其读取为mm/dd/yyyy

最好的方法是使用格式来转换SQL中的所有日期,如下所示:

SELECT * FROM tbl_details WHERE (tbl_details.DateTime) BETWEEN #" & format(startdate,"mm/dd/yyyy") & "#" And "#" & format(enddate,"mm/dd/yyyy") & "#;"

答案 1 :(得分:0)

从VBA生成SQL时,最初Debug.Print SQL总是一个很好的理想选择。在这种情况下,您似乎甚至无法做到这一点,因为您构建的SQL字符串不正确-And必须在引号内:

sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) BETWEEN #" & startdate & "# And #" & enddate & "#;"
' instead of this:
sqlstr = "SELECT * FROM tbl_details WHERE (tbl_details.DateTime) BETWEEN #" & startdate & "#" And "#" & enddate & "#;"

其他几点:

  • 如果您的DateTime列中包含时间,则需要稍微更改代码。如果用户输入2019-05-03作为结束日期,则5月3日出现的值将被排除(例如2019-05-03 15:00)。
  • DateTime是错误的列名,因为它没有描述您的数据。您可能还需要考虑重命名tbl_details。详细信息是什么?
  • 您还应该继续为文本框指定有意义的名称。 txtStartDate而非Text98
  • 声明dbsrst时,最好添加该库(例如Dim dbs as DAO.Database),因为ADO和DAO库都使用相同的类。
  • 您也可以使用参数化查询,而不是在VBA中对SQL进行硬编码,因此不必生成SQL(有时可能很棘手)。

答案 2 :(得分:0)

请考虑使用通过QueryDefs进行的参数化查询,并根据数据类型避免任何混乱的串联或引号/符号括起来。然后将表单值绑定到querydef对象,并将querydef分配给记录集对象。

SQL (下面另存为存储的查询对象)

PARAMETERS [param_start] Date, [param_end] Date;
SELECT * FROM tbl_details 
WHERE (tbl_details.DateTime) BETWEEN [param_start] AND [param_end]

VBA (将查询参数绑定到报表的记录集)

Private Sub RunReport_Click()
    Dim qdef As QueryDef
    Dim rst As Recordset
    Dim selectedreport As String

    ' OPEN QUERY AND BIND PARAMS 
    Set qdef = CurrentDb.QueryDefs("mySavedParamQuery")

    qdef!start_param = Me.Text98
    qdef!end_param = Me.Text100

    ' ASSIGN QUERY RESULT TO RECORDSET
    Set rst = qdef.OpenRecordset()    

    With rst
        While Not .EOF()
            Debug.Print .Fields("DateTime").Value
            .MoveNext
        Wend
    End With

    Set qdef = Nothing    
    Set rst = Nothing
End Sub