VBA MS Access 中存在空白记录时数据类型不匹配

VBA data type mismatch when blank record exists in MS Access

如果包含日期的特定字段中没有空白记录,我有以下 vba 查询可以正常工作。当特定记录中存在空白时会发生错误。

我想做什么?: 从我的数据库中提取一个日期范围内的计数。开始日期和结束日期是格式为 "MM/DD/YYYY" 的单元格引用,包含日期的日期数据库字段格式为 Date/Time、"short date".

如果我的字段列不包含任何空白,则查询有效:

Dim startdate As Date
Dim enddate As Date
strSql = "SELECT Count(*) FROM tablename WHERE datevalue(Date_field_name) >= " & Format(startdate, "\#mm-dd-yyyy\#") & "AND datevalue(Date_field_name) <= " & Format(enddate, "\#mm-dd-yyyy\#")

我试过添加 IS NOT NULL 但这不起作用:(

strSql = "SELECT Count(*) FROM tablename WHERE ANOTHER_Field_Name IS NOT NULL AND datevalue(Date_field_name) >= " & Format(startdate, "\#mm-dd-yyyy\#") & "AND datevalue(Date_field_name) <= " & Format(enddate, "\#mm-dd-yyyy\#")

请帮帮我!!这让我抓狂。

编辑完整代码:

Public Sub counter()
Dim cn As Object
Dim rs As Object
Dim strSql As String
Dim strConnection As String
Dim myCounter As Variant
Dim startdate As Date
Dim enddate As Date
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0; " & _
    "Data Source=Data.mdb"
strSql = "SELECT Count(*) FROM tablename WHERE datevalue(Date_field_name) >= " & Format(startdate, "\#mm-dd-yyyy\#") & "AND datevalue(Date_field_name) <= " & Format(enddate, "\#mm-dd-yyyy\#")
cn.Open strConnection
'Set rs = cn.Execute(strSql)

While (rs.EOF = False)
If (Not IsNull(rs(Sent_To_Tech_Date).Value)) Then
myCounter = myCounter + 1
End If
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub

我通常会看到这种情况是用 NZ 函数处理的,因此该字段永远不会留空。所以像这样:

strSql = "SELECT Count(*) FROM tablename WHERE datevalue(Nz(Date_field_name,"01-01-1969")) >= " & Format(startdate, "\#mm-dd-yyyy\#") & "AND datevalue(Nz(Date_field_name,"01-01-1969")) <= " & Format(enddate, "\#mm-dd-yyyy\#")

这也脱离了这样的假设,即您只是显示一些精简的代码,因为您声明变量然后 运行 一个查询,而没有将这些变量更改为日期。

“01-01-1969”日期应该适合您要查找的内容,但如果不相应地进行调整。另外,我的手绘 SQL 并不令人惊奇,所以某些语法可能有点偏差。

代码更正:

strSql = "SELECT Count(*) FROM tablename WHERE datevalue(IIf(IsNull(Date_field_name),"01-01-1969", Date_Field_Name)) >= " & Format(startdate, "\#mm-dd-yyyy\#") & " AND datevalue(IIf(IsNull(Date_field_name),"01-01-1969", Date_Field_Name)) <= " & Format(enddate, "\#mm-dd-yyyy\#")

如果这不符合您的喜好,请看这里:http://www.w3schools.com/sql/sql_isnull.asp还有其他替代方法可以处理空值。

第三轮,我认为 Null 的想法是转移注意力,很确定它有很多不需要的格式,而且 "Format" 部分实际上并没有将它设置为日期,所以它不会正确地进行比较。试试看:

strSql = "SELECT Count(*) FROM tablename WHERE Date_field_name >= #" & startdate & "# AND Date_Field_Name <= #" & enddate & “#”

如果您的结束日期和开始日期将采用非日期格式,请使用

strSql = "SELECT Count(*) FROM tablename WHERE Date_field_name >= #" & Format(startdate,"\#mm-dd-yyyy\#") & "# AND Date_Field_Name <= #" & Format(enddate,"\#mm-dd-yyyy\#") & “#”

在查询字符串中很可能有一个正确的方法来执行此操作,但我没有 运行 遍历它。对于这种情况,我分两步进行:

我将 运行 标准 SELECT 查询 return 感兴趣日期范围内的所有记录,而不是 运行 计数查询。 然后我将遍历记录集中的所有项目,丢弃任何为空的项目,并对其余项目进行计数。

While (myRecordSet.EOF = False)
  If (Not IsNull(myRecordSet(Date_field_name).Value)) Then
    myCounter = myCounter + 1
  End If
  myRecordSet.MoveNext
Wend

我认为这不是最佳方式,但我过去使用过它并且我知道它有效。