You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MS Excel VBA读写MS Access数据库日期的异常问题

问题分析与解决方案

核心问题根源

你的代码中直接将VBA日期变量拼接进SQL字符串是错误核心:当日期类型变量与字符串拼接时,VBA会自动转成系统格式的字符串,但Access SQL要求日期必须用#包裹,否则会被错误解析,导致日期部分丢失,最终只剩无效时间(甚至解析为1900年的错误日期)。

同时代码存在几处语法/逻辑错误:

  • TestDateIntoDB中Dim SQLString As StringDim ADate As Date是语法错误,需拆分为两行声明
  • Format函数返回字符串,不能直接赋值给Date类型变量ADate
  • rs.Open SQLString, Conn行的注释与代码混写,导致执行逻辑混乱

正确解决方案

方案1:参数化查询(推荐,彻底规避格式问题+防SQL注入)

参数化查询是处理日期类型最可靠的方式,无需纠结格式适配:

Option Explicit

Public Conn                 As New ADODB.Connection
Public rs                   As New ADODB.Recordset
Public sconnect             As String
Public Const DATABASE_LOC   As String = "C:\Users\Robert\Documents\ASAP\db1\" '补全路径分隔符,避免拼接错误
Public Const DATABASE_NAME  As String = "Database1.accdb"

Sub TestDateInAndOut()
     TestDateIntoDB
     TestDateOutOfDB
End Sub

Sub TestDateIntoDB()
    Dim SQLString As String
    Dim ADate As Date
    Dim cmd As New ADODB.Command

    '日期赋值(任选一种即可)
    ADate = CDate("12/29/2022")
    'ADate = #12/29/2022#

    SQLString = "INSERT INTO Table1 (TheDate) Values(?)" '用?作为参数占位符

    OpenSQLConnection
    Set cmd.ActiveConnection = Conn
    cmd.CommandText = SQLString
    '指定参数类型为日期,直接传入变量
    cmd.Parameters.Append cmd.CreateParameter(, adDate, adParamInput, , ADate)
    cmd.Execute
    CloseSQLConnections

    Debug.Print "Date IN: " & CStr(ADate)
End Sub

Sub TestDateOutOfDB()
    Dim sSQLSting   As String

    OpenSQLConnection
    sSQLSting = "SELECT * From [Table1]"
    rs.Open sSQLSting, Conn

    Worksheets("Sheet1").Range("A1").CopyFromRecordset rs
    '读取时格式化日期输出,避免显示混乱
    Debug.Print "Date OUT: " & Format(Worksheets("Sheet1").Range("B1").Value, "mm/dd/yyyy")

    CloseSQLConnections
End Sub

Sub OpenSQLConnection()
    sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DATABASE_LOC & DATABASE_NAME & ";Persist Security Info=False;"
    Conn.Open sconnect
End Sub

Sub CloseSQLConnections()
    On Error Resume Next
    rs.Close
    Set rs = Nothing
    Conn.Close
    Set Conn = Nothing
End Sub

方案2:手动给日期加#包裹(不推荐,仍有格式风险)

若坚持用字符串拼接,必须将日期转成Access可识别的ISO格式并用#包裹:

'替换TestDateIntoDB中的SQL拼接行
SQLString = "INSERT INTO Table1 (TheDate) Values(#" & Format(ADate, "yyyy-mm-dd") & "#)"

注:yyyy-mm-dd是ISO标准日期格式,不受系统区域设置影响,Access解析不会出错。

额外注意事项

  • Access表中TheDate字段类型需设置为日期/时间(ShortDate仅为显示格式,字段本质仍为日期/时间类型)
  • 写入后Access显示12:00:18 AM是因为插入的日期默认时间部分为0,仅展示了时间;读取后出现1/0/1900是错误SQL拼接导致插入无效日期值,Excel解析后生成的默认错误日期。

内容的提问来源于stack exchange,提问作者rjbudz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:30:33