Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Необходимо разрешить Null или значения для дат - несоответствие типа данных запроса доступа

Автор вопроса: gfuller40Ответов: 4

В основном я пытаюсь использовать модуль или общедоступные функции, чтобы вытащить datediff, который предназначен только для рабочих дней. Все работает, что касается кода, но по какой-то причине с определенным полем даты (которое я добавил после того, как база данных некоторое время находилась в производстве) код работает неправильно, и я получаю "Тип данных Несоответствие в выражении". Я на 99% уверен, что это проблема с данными. Если я сравню две разные даты, которые он запустит, я создам тестовую таблицу с 10 записями, и она запустится.

Поле установлено на Дата/Время. Я предполагаю, что мой вопрос в том, есть ли способ избавиться от "" или сделать так, чтобы код принимал эти пробелы как нули? или конвертировать их?

Здесь я вызываю функцию в запросе:

Exp1: Рабочие дни([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
  • В частности, если я запускаю запрос и немного прокручиваю вниз, появляется сообщение об ошибке Subscript out of range и выделяется строка: gfuller40 02.12.2010

vbams-access

Ответы

Ответ 1 · mwolfe02

Код не работает, когда Year(dteStartDate) > Year(dteEndDate)

Ответ 2 · Jim Anderson

Вы не можете преобразовать массив в отрицательное значение.

Когда lngEYear ‹ lngYear, lngDiff будет меньше нуля.

Ответ 3 · RolandTumble

Я не уверен, что эта строка:

If IsDate(dteStartDate) And IsDate(dteEndDate) Then 'added here begin

необходимо, так как вы получите ошибки несоответствия типов, если попытаетесь передать в функцию значения других типов. В любом случае у вас также/вместо этого должно быть что-то вроде:

If dteStartDate <= dteEndDate Then

с частью Else, возвращающей "известный плохой" ответ, как здесь делает ваш код:

Else                'Add
    BusinessDays = -1 ' add
End If   'add

Это просто расширение ответов, уже опубликованных Джимом Андерсоном и mwolfe02. Если вы примете этот ответ / проголосуете за него, вы также должны проголосовать за них....

Ответ 4 · phoog

Вы получаете несоответствие типа данных, потому что вы объявили параметры как тип Date. В то время как столбец Date/Time в базе данных может содержать нулевое значение, переменная Date в VBA не может. Поэтому вы должны объявить параметры как Variants и выполнить некоторую проверку типов в начале вашей функции.

Это означает, что мой комментарий к другому ответу (в котором говорится, что IsDate здесь всегда будет возвращать true) вводит в заблуждение. Вместо того, чтобы удалять бессмысленную проверку IsDate, вы должны сделать проверку осмысленной, изменив тип параметра с Date на Variant.

Надеюсь это поможет.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы