使用带变量的cdate函数在Vba中查询

时间:2014-03-12 00:22:17

标签: sql vba ms-access access-vba

在microsoft access sql视图中使用以下查询,使用硬编码日期可以轻松实现

SELECT Salary.First, Salary.Last,FROM Salary, allowances
WHERE Salary.PayThroughDate = CDate("2014-05-06") AND Salary.SSN = allowances.SSN

但是使用变量而不是硬编码日期将此查询嵌入到Vba中是另一项业务。它只是不起作用:

Dim ddate As Variant
Dim getDay As Integer
Dim getMonth As Integer
Dim getYear As Integer
getDay = Day(Me.DTPicker2.Value)
getMonth = Month(Me.DTPicker2.Value)
getYear = Year(Me.DTPicker2.Value)
ddate = getDay & "/" & getMonth & "/" & getYear
ddate = Format(ddate, "dd/mm/yyyy")

query1 = "SELECT Salary.First, Salary.Last FROM Salary, allowances WHERE Salary.PayThroughDate =  " & CDate(ddate) & " AND Salary.SSN =
     

allowances.SSN

这个Vba Sql混合中的任何想法?我错过了单引号还是双引号?

2 个答案:

答案 0 :(得分:0)

当您将SQL直接发送到JET而不是从MS Access的普通用户界面运行它时,您需要以美国格式制作日期格式。很久以前我遇到过这个问题,但是通过使用这个函数将我的日期格式化为文本来解决它,JET期望的方式是:

Function SQLDate(varDate As Date) As String
'---------------------------------------------------------------------------------------
'Purpose    Formats a date in the american way so that it can be used in
'           SQL (by the JET-engine)
'Accepts    varDate - the date that should be converted to text
'Returns    The date converted to text, in american format with both the day and
'           the month using 2 characters.  (01 is january)
'---------------------------------------------------------------------------------------
'Changelog
'HANY 20100407: Stopped using the FORMAT-function for the date-value, as I found some
'               cases where the format did not return the date as specified.
'---------------------------------------------------------------------------------------

    'SQLDate = "#" & Format$(varDate, "mm\/dd\/yyyy") & "#"
    SQLDate = "#" & Format(Month(varDate), "00") & "/" & Format(Day(varDate), "00") & "/" & Format(Year(varDate), "0000") & "#"
End Function

在上面的示例中,您现在添加日期& SQLDate(CDate(ddate)) &而不是& CDate(ddate) &

答案 1 :(得分:-1)

等效查询是:

query1 = "SELECT Salary.First, Salary.Last 
FROM Salary, allowances 
WHERE (Salary.PayThroughDate =Cdate(" & ddate & ") )
AND (Salary.SSN = allowances.SSN)"

您遇到的问题是,在构造sql字符串时,首先将cdate值转换为字符串值。它和

一样
WHERE (Salary.PayThroughDate =" & format(ddate,"general date") & ")

如果您稍后进行cdate转换,则可以正常工作。另一个几乎相同的查询是

...
WHERE Salary.PayThroughDate =#" & ddate & "#
...

Cdate和#标签都采用字符串日期,并转换为日期类型(使用稍微不同的规则)。由于日期类型实际上存储为double的整数部分,因此您也可以执行:

WHERE Salary.PayThroughDate =cdbl(#" & ddate & "#)

WHERE Salary.PayThroughDate =clng(#" & ddate & "#)

WHERE Salary.PayThroughDate =" & clng(cdate(ddate) & "

- 该数字将被转换为字符串,成为sql字符串的一部分,但数字在SQL中正常工作:它们不需要使用#tag或转换函数来使它们工作。

但你开始时有一个日期值:

v =Me.DTPicker2.Value

因此您可以直接将其转换为数字,而不必先将其转换为字符串:

d = clng(Me.DTPicker2.Value)
...
WHERE (Salary.PayThroughDate = " & d & ")

这是在Access / VBA中处理日期的最快且最不容易出错的问题,但是当您开始使用SQL Server时会撤消,这会以不同的方式存储日期。

另外,我在构造测试示例时看到您正确使用了ISO日期格式,但在从日期值构造字符串时切换到美国日期格式。那是个错误。为了避免SQL中的错误和“恶意日期猜测”,您应该坚持使用ISO格式:

v =Me.DTPicker2.Value
sdate = format(v,"yyyy-mm-dd")