需要为日期允许 Null 或“”值 - 访问查询数据类型不匹配
Posted
技术标签:
【中文标题】需要为日期允许 Null 或“”值 - 访问查询数据类型不匹配【英文标题】:Need to Allow Null or "" values for Dates - Access Query Data type mismatch 【发布时间】:2010-12-02 18:30:10 【问题描述】:基本上,我正在尝试使用模块或公共函数来提取仅适用于工作日的 datediff。就代码而言,一切正常,但由于某种原因,特定日期字段(我在数据库投入生产一段时间后添加的日期字段)代码无法正常工作,我得到“数据类型表达式不匹配”。我 99% 确定这是数据问题。如果我比较它运行的两个不同日期,我创建了一个包含 10 条记录的测试表并且它运行。
该字段设置为日期/时间。我想我的问题是,无论如何要摆脱“”或使其成为代码将接受这些空白作为空值?或转换它们?
这是我在查询中调用函数的地方:
Exp1: BusinessDays([IntCallDate],[aIntCall1])
这是模块中的代码...
感谢您的帮助 - 非常感谢!!!
Public Function BusinessDays(dteStartDate As Date, dteEndDate As Date) As Long
On Error GoTo err_workingDays
Dim lngYear As Long
Dim lngEYear As Long
Dim dteStart As Date, dteEnd As Date
Dim dteCurr As Date
Dim lngDay As Long
Dim lngDiff As Long
Dim lngACount As Long
Dim dteLoop As Variant
Dim blnHol As Boolean
Dim dteHoliday() As Date
Dim lngCount As Long, lngTotal As Long
Dim lngThanks As Long
If IsDate(dteStartDate) And IsDate(dteEndDate) Then 'added here begin
dteStart = dteStartDate
dteEnd = dteEndDate
lngYear = DatePart("yyyy", dteStart)
lngEYear = DatePart("yyyy", dteEnd)
If lngYear <> lngEYear Then
lngDiff = (((lngEYear - lngYear) + 1) * 7) - 1
ReDim dteHoliday(lngDiff)
Else
ReDim dteHoliday(6)
End If
lngACount = -1
For lngCount = lngYear To lngEYear
lngACount = lngACount + 1
'July Fourth
dteHoliday(lngACount) = DateSerial(lngCount, 7, 4)
lngACount = lngACount + 1
'Christmas
dteHoliday(lngACount) = DateSerial(lngCount, 12, 25)
lngACount = lngACount + 1
'New Years
dteHoliday(lngACount) = DateSerial(lngCount, 1, 1)
lngACount = lngACount + 1
'Thanksgiving - 4th Thursday of November
lngDay = 1
lngThanks = 0
Do
If Weekday(DateSerial(lngCount, 11, lngDay)) = 5 Then
lngThanks = lngThanks + 1
End If
lngDay = lngDay + 1
Loop Until lngThanks = 4
dteHoliday(lngACount) = DateSerial(lngCount, 11, lngDay)
lngACount = lngACount + 1
'Memorial Day - Last Monday of May
lngDay = 31
Do
If Weekday(DateSerial(lngCount, 5, lngDay)) = 2 Then
dteHoliday(lngACount) = DateSerial(lngCount, 5, lngDay)
Else
lngDay = lngDay - 1
End If
Loop Until dteHoliday(lngACount) >= DateSerial(lngCount, 5, 1)
lngACount = lngACount + 1
'Labor Day - First Monday of Septemeber
lngDay = 1
Do
If Weekday(DateSerial(lngCount, 9, lngDay)) = 2 Then
dteHoliday(lngACount) = DateSerial(lngCount, 9, lngDay)
Else
lngDay = lngDay + 1
End If
Loop Until dteHoliday(lngACount) >= DateSerial(lngCount, 9, 1)
'MsgBox dteHoliday(5)
lngACount = lngACount + 1
'Easter
lngDay = (((255 - 11 * (lngCount Mod 19)) - 21) Mod 30) + 21
dteHoliday(lngACount) = DateSerial(lngCount, 3, 1) + lngDay + _
(lngDay > 48) + 6 - ((lngCount + lngCount \ 4 + _
lngDay + (lngDay > 48) + 1) Mod 7)
Next
For lngCount = 1 To DateDiff("d", dteStart, dteEnd)
dteCurr = (dteStart + lngCount)
If (Weekday(dteCurr) <> 1) And (Weekday(dteCurr) <> 7) Then
blnHol = False
For dteLoop = 0 To UBound(dteHoliday)
'MsgBox dteHoliday(dteLoop) & " " & dteLoop
If (dteHoliday(dteLoop) = dteCurr) Then
blnHol = True
End If
Next dteLoop
If blnHol = False Then
lngTotal = lngTotal + 1
'MsgBox dteCurr
End If
End If
Next lngCount
BusinessDays = lngTotal
Else 'Add
BusinessDays = -1 ' add
End If 'add
err_workingDays:
MsgBox "Error No: " & Err.Number & vbCr & _
"Description: " & Err.Description
Resume exit_workingDays
End Function
【问题讨论】:
更具体地说 - 如果我运行查询并向下滚动一点,则会弹出一个错误“下标超出范围”并突出显示该行: 【参考方案1】:Year(dteStartDate) > Year(dteEndDate)
时代码失败
【讨论】:
这真的是评论,而不是问题的答案。请使用“添加评论”为作者留下反馈。 @Conner:感谢您审查 *** 上的潜在问题。不过,我向你保证,我的意思是作为一个答案。 OP 在他的问题中表示,他“99% 确定这是一个数据问题”。我只是在识别会导致错误的数据。我让 OP 来查找违规记录并采取他认为适当的纠正措施。 希望我的评论没有冒犯您。审查过程目前处于测试阶段,因此仍需要解决一些问题。其中一个问题是审稿人无法查看问题的完整背景。因此,我只有你的问题要看。我评估说这个特定的答案相当简短,很容易成为评论。我认为 SO 正在寻求包含更多解释的答案,这些解释可能有利于未来用户较少本地化的问题。我知道这并不总是可能的,但我只是在几秒钟内做出了直觉决定。问候。 我想的也差不多。没有冒犯。说到上下文,如果在审阅过程中添加了某种与 cmets 相关的 [Review] 标签可能会有所帮助。我最初很困惑为什么在这样一个旧线程上突然出现活动。当我在您的个人资料上看到最近的活动时,这更有意义。如果您对审核过程有任何意见(因为它仍处于测试阶段,并且您似乎是一位活跃的审核者-Kudos!),您可以考虑传递我的建议。继续努力帮助改善 SO 社区!【参考方案2】:您不能将数组重新调整为负值。
当 lngEYear
【讨论】:
【参考方案3】:我不确定这条线:
If IsDate(dteStartDate) And IsDate(dteEndDate) Then 'added here begin
是必需的,因为如果您尝试将其他类型的值提供给函数,则会出现类型不匹配错误。在任何情况下,你也/相反应该有类似的东西:
If dteStartDate <= dteEndDate Then
Else 部分返回“已知错误”答案,您的代码在此处执行的方式:
Else 'Add
BusinessDays = -1 ' add
End If 'add
这只是 Jim Anderson 已经发布的答案的扩展 和 mwolfe02 .如果你接受这个答案/投票,你也应该投票给他们......
【讨论】:
因为变量dteStartDate
和dteEndDate
被声明为Date 类型,所以IsDate 函数将始终返回true。但是,将字符串传递给 IsDate 不会导致类型不匹配错误。相反,如果字符串可以转换为日期,则该函数将返回 true;否则,它将返回 false。【参考方案4】:
由于您已将参数声明为Date
类型,因此您遇到了数据类型不匹配的问题。虽然数据库中的 Date/Time
列可以包含空值,但 VBA 中的 Date
变量不能。因此,您必须将参数声明为 Variant
s,并在函数的头部进行一些类型检查。
这意味着我对另一个答案的评论(说IsDate
将始终在此处返回 true)具有误导性。与其删除无意义的IsDate
检查,不如通过将参数类型从Date
更改为Variant
来使检查有意义。
希望这会有所帮助。
【讨论】:
以上是关于需要为日期允许 Null 或“”值 - 访问查询数据类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SELECT 查询:在为不同字段配对日期时折叠 NULL 值
SQL - 更新查询 - 更新到下一个不为 NULL 的日期值