我正在使用以下提供程序在Excel工作表中使用SQL
Set m_Connection = CreateObject("ADODB.Connection")
m_Connection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & ThisWorkbook.FullName & ";Extended Properties=""Excel 12.0;HDR=Yes;"";"
我有两个文本框(从和到),用户在其中输入两个日期从,到,以选择与此日期选择相对应的记录
我面临以下问题:
首先,我尝试了这段代码,我从工作表中获取所有字段,无论日期是什么,除非我有空白工作表,否则在列日期中单元格为空的那些都是空的,所以我没有出现错误,但是我在两个日期之间的状况不起作用
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE CDATE([ClipDate]) BETWEEN #01/09/2017# AND #14/03/2019#;
我尝试不使用BETWEEN
,但是得到了相同的错误结果(除了空的记录,所有记录都被选择为ClipDate)
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE CDATE([ClipDate]) >= #01/09/2017# AND CDATE([ClipDate]) <= #14/03/2019#;
我尝试了以下操作,通过将#替换为“”,这次我得到了很好的日期选择(我想要的日期选择),但是如果有任何单元格,我将收到一个错误消息,提示“无效使用Null”日期列为空。
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE CDATE([ClipDate]) >= "01/09/2017" AND CDATE([ClipDate]) <= "14/03/2019";
最后我尝试了一下,并得到了与上一个相同的结果,即在空白单元格的情况下无效使用Null
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE CDATE([ClipDate]) BETWEEN "01/09/2017" AND "11/03/2019";
这是“发件人”到“
”的屏幕在我的Excel工作表中,我有这些日期
我认为问题在于CDATE
在NULL
值上不起作用,这是正常的,我必须找到一种仅在不为null的情况下进行转换的方法,但我不知道如何。
任何人都可以帮忙吗?
答案 0 :(得分:3)
考虑parameterization,它受ADO支持,并允许将VBA值绑定到准备好的SQL查询中,以实现可维护性和可读性,并避免使用诸如#
等类型的附件。
Sub RunSQL()
On Error GoTo ErrHandle
Dim m_Connection As Object, cmd As Object, rst As Object
Dim sqlStr As String
Const adCmdText = 1, adDate = 7, adParamInput = 1
' CONNECTION
Set m_Connection = CreateObject("ADODB.Connection")
m_Connection.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & ThisWorkbook.FullName & _
";Extended Properties=""Excel 12.0;HDR=Yes;"";"
' PREPARED STATEMENT WITH NO DATA BUT PLACE HOLDERS
sqlStr = "SELECT [ListName] AS [List name] " _
& " FROM [Database$]" _
& " WHERE CDATE([ClipDate]) BETWEEN ? AND ?"
' CONFIGURE ADO COMMAND
Set cmd = CreateObject("ADODB.Command")
With cmd
.ActiveConnection = m_Connection
.CommandText = sqlStr
.CommandType = adCmdText
' BIND VALUES
.Parameters.Append .CreateParameter("fromdate", adDate, adParamInput, , _
CDate(Search.txtClipFrom.value))
.Parameters.Append .CreateParameter("todate", adDate, adParamInput, , _
CDate(Search.txtClipTo.value))
End With
' CREATE RECORDSET FROM COMMAND EXECUTION
Set rst = cmd.Execute
ThisWorkbook.Worksheets("RESULTS").Range("A2").CopyFromRecordset rst
rst.Close: m_Connection.Close
MsgBox "Successfully completed!"
ExitHandle:
Set cmd = Nothing: Set rst = Nothing: Set m_Connection = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitHandle
End Sub
答案 1 :(得分:2)
使用 CVDate -和 ISO序列作为值:
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE CVDate([ClipDate]) BETWEEN #2017/09/01# AND #2019/03/14#;
修改。过滤掉无效的日期字符串:
SELECT [ListName] AS [List name]
FROM [Database$]
WHERE
IsDate([ClipDate]) AND
CVDate(IIf(IsDate([ClipDate]), [ClipDate], Null)) BETWEEN #2017/09/01# AND #2019/03/14#;
编辑2 :要分割dd / mm / yyyy格式的文本日期:
WHERE
IsDate([ClipDate]) AND
DateSerial(Mid([ClipDate], 7, 4), Mid([ClipDate], 4, 2), Mid([ClipDate], 1, 2)) BETWEEN #2017/09/01# AND #2019/03/14#;