2010-12-02 23 views
1

基本的に私はモジュールまたは公開関数を使用して、営業日のみの日付表を取得しようとしています。すべてのコードが懸念されている限り、特定の日付フィールド(私はいくつかの時間のデータベースが生産された後に追加した)何らかの理由でコードが正しく動作していないと私は "データ型「表現の不一致」私は99%がデータの問題であると確信しています。 2つの異なる日付を比較すると、10個のレコードでテストテーブルが作成され、実行されます。日付のNULL値を許可する必要があります - アクセスクエリのデータ型が一致しません

フィールドは[日付/時刻]に設定されています。私の質問は、とにかく ""を取り除くか、コードがこれらの空白をヌルとして受け入れるようにすることですか?またはそれらを変換する?

私は、クエリ内の関数を呼び出す場所です:

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 
+0

もっと具体的には - 質問を実行して少し下にスクロールすると、「下付き文字が範囲外です」が表示され、行がハイライト表示されます: – gfuller40

+0

ReDim dteHoliday(lngDiff) – gfuller40

答えて

0

コードは、あなたが負の値に配列をREDIMすることができないときYear(dteStartDate) > Year(dteEndDate)

+0

これは本当にコメントです。質問。著者にフィードバックを残すには、「コメントを追加」を使用してください。 – Conner

+0

@Conner:StackOverflowの潜在的な問題についてお読みいただきありがとうございます。私はあなたに保証します、しかし、私はこれを答えとして意味しました。 OPは、彼が「99%がこれがデータの問題だと確信している」と質問している。私は単にエラーの原因となるデータを特定していました。私は、違反記録を見つけて、彼が適切な是正処置であると感じたものを取るために、それをOPに任せました。 – mwolfe02

+0

私のレビューがあなたを怒らせないことを願っています。レビュープロセスは現在ベータ版であるため、まだまだ問題を解決する必要があります。これらの不具合の1つは、査読者が質問の完全な文脈を見ることができないということです。したがって、私はあなたの質問を見るだけです。私は、この特定の答えがかなり短く、簡単にコメントにすることができると評価しました。私は、SOが、よりローカライズされていない問題の将来のユーザーに役立つ可能性がある、より多くの説明を含む回答を組み込むことを検討していると思います。私はこれが常に可能ではないことを知っていますが、私はちょうど数秒で腸の決定をしました。よろしく。 – Conner

0

失敗しました。

lngEYear < lngYearの場合、lngDiffはゼロより小さくなります。

0

私はこの行ことはよく分からない:あなたが関数に値の他の種類を供給しようとする場合は、型の不一致エラーを取得しますので、

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

が、必要です。これはちょうどある

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

:エルス部分は「既知の不正な」答えを返すと

If dteStartDate <= dteEndDate Then 

、あなたのコードはここにない方法:いずれの場合では、あなたはまた、/の代わりのようなものを持っている必要がありますジムアンダーソンによって既に投稿された回答の拡大 とmwolfe02 。この回答を受け入れるか投票すると、それらも投票する必要があります。

+0

変数 'dteStartDate'と' dteEndDate'は型Dateとして宣言されているので、IsDate関数は常にtrueを返します。ただし、IsDateに文字列を渡しても型の不一致エラーは発生しません。むしろ、文字列を日付に変換できる場合、関数はtrueを返します。それ以外の場合はfalseを返します。 – phoog

0

パラメータがDateタイプと宣言されているため、データ型が一致しません。データベース内のDate/Time列にはNULL値を格納できますが、VBAのDate変数は保持できません。そのためVariant Sなどのパラメータを宣言し、あなたの関数の先頭にいくつかの型のチェックを行う必要があります。

これは別の答え(IsDateはいつもここにtrueを返しますと言って)に私のコメントが誤解であることを意味します。むしろ無意味IsDateチェックを削除するよりも、あなたはVariantDateからパラメータの種類を変更することで、チェックが有意義なものにする必要があります。

これが役に立ちます。

関連する問題