需要为日期允许 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) &gt; 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 .如果你接受这个答案/投票,你也应该投票给他们......

【讨论】:

因为变量dteStartDatedteEndDate 被声明为Date 类型,所以IsDate 函数将始终返回true。但是,将字符串传递给 IsDate 不会导致类型不匹配错误。相反,如果字符串可以转换为日期,则该函数将返回 true;否则,它将返回 false。【参考方案4】:

由于您已将参数声明为Date 类型,因此您遇到了数据类型不匹配的问题。虽然数据库中的 Date/Time 列可以包含空值,但 VBA 中的 Date 变量不能。因此,您必须将参数声明为 Variants,并在函数的头部进行一些类型检查。

这意味着我对另一个答案的评论(说IsDate 将始终在此处返回 true)具有误导性。与其删除无意义的IsDate 检查,不如通过将参数类型从Date 更改为Variant 来使检查有意义。

希望这会有所帮助。

【讨论】:

以上是关于需要为日期允许 Null 或“”值 - 访问查询数据类型不匹配的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SELECT 查询:在为不同字段配对日期时折叠 NULL 值

SQL - 更新查询 - 更新到下一个不为 NULL 的日期值

使用 NSPredicate 查询 CloudKit 以获取空白(或 null 或其他)的日期

什么基于可空表单字段的访问查询条件将返回我需要的内容?

日期分区或日期分片

mybatis想给其中某个字段赋成null,mapper层怎么判断这个传进来的null是 需要赋空值还是需要略过不更新