none
【Excel VBA】Accessからエクスポートした時刻データについて RRS feed

  • 質問

  • Accessに格納されている時刻のデータ(データ型:日付/時刻型、書式:時刻(S))を、Excelへエクスポートしました(1:00)。

    エクスポートした時刻(1:00)とExcelで手入力した時刻(1:00)を、VBAのIF文で同じかどうか判定したところ、違うという判定結果となりました。Excel上での見え方は、同じ(1:00)であるにも関わらず、違うという判定結果になった理由が分かりません。

    ご存じの方がおりましたらご教示ください。よろしくお願いします。

    【補足】

    ・VBAではなく、Excel上で、IF関数で判定したところ、同じという判定結果になりました。

    2019年8月15日 14:24

すべての返信

  • Excelで手入力した時刻(1:00)

    VBA でセル値を確認すると、Double 型の 4.16666666666667E-02 に相当する値になっているかと思います。下記と同じ値ですね。

    Dim date1 As Date
    date1 = #1:00:00 AM#
    
    ' 1日 ÷ 24時間 = 0.041666666… Dim dbl2 As Double dbl2 = 1.0 / 24.0 ’ True になる Debug.Print date1 = dbl2

    ただし Excel のワークシート上では、日付値としてもミリ秒精度までしか持ち合わせていません。それより細かい端数は無視されて、「同じ値」として扱われるようになっています。

    Dim d0 As Double
    Dim d1 As Double
    Dim d2 As Double
    Dim d3 As Double
    
    d0 = CDbl("0.041666666666666657")
    d1 = CDbl("0.041666666666666664")  '← #1:00:00 AM# はコレ
    d2 = CDbl("0.0416666666666667")
    d3 = CDbl("0.041666666666666706")
    
    ' これだけ見ると、すべて同じ値に見える
    ' しかし実際には同じ値ではない!
    Debug.Print "d0 ="; d0
    Debug.Print "d1 ="; d1
    Debug.Print "d2 ="; d2
    Debug.Print "d3 ="; d3
    
    ' これらはすべて False
    Debug.Print "d0 = d1 は: "; d0 = d1
    Debug.Print "d1 = d2 は: "; d1 = d2
    Debug.Print "d2 = d3 は: "; d2 = d3
    Debug.Print "d3 = d0 は: "; d3 = d0
    
    ' これらはすべて True
    Debug.Print "d0 < d2 は: "; d0 < d1
    Debug.Print "d1 < d2 は: "; d1 < d2
    Debug.Print "d2 < d3 は: "; d2 < d3
    Debug.Print "d3 > d0 は: "; d3 > d0
    
    ' 微妙な差異がある
    Debug.Print "d1 - d0 = "; Format(d1 - d0, "0.00000000000000000000000000000000")
    Debug.Print "d2 - d1 = "; Format(d2 - d1, "0.00000000000000000000000000000000")
    Debug.Print "d3 - d2 = "; Format(d3 - d2, "0.00000000000000000000000000000000")
    
    'それぞれの変数内のビット表現
    ' d0 : 0 01111111010 0101010101010101010101010101010101010101010101010100
    ' d1 : 0 01111111010 0101010101010101010101010101010101010101010101010101
    ' d2 : 0 01111111010 0101010101010101010101010101010101010101010101011010
    ' d3 : 0 01111111010 0101010101010101010101010101010101010101010101011011
    
    
    ' セルに表示して比較してみると、Excel 上では同じ値に見えるし、
    ' ワークシート上でも同じ値として取り扱われてしまう。
    Sheet1.[B1].Value = d0
    Sheet1.[B2].Value = d1
    Sheet1.[B3].Value = d2
    Sheet1.[B4].Value = d3
    
    ' 一応、「数値書式」と「時刻書式」で表示してみる
    Sheet1.[C1:D4].FormulaR1C1 = "=RC2"
    Sheet1.[C1:C4].NumberFormat = "0.0000000000000000"
    Sheet1.[D1:D4].NumberFormat = "h:mm:ss.000"
    
    
    ' ワークシート上では同じ値として扱っているが、
    ' 内部値は実際に異なるので、VBA でその差を検出できる
    Dim v() As Variant
    v = Sheet1.[B1:B4].Value
    
    ' これらは True となる
    Debug.Print v(1, 1) = d0
    Debug.Print v(2, 1) = d1
    Debug.Print v(3, 1) = d2
    Debug.Print v(4, 1) = d3

    ゆえに時刻部をもつ日付を比較する場合は、「Format して文字列として一致判定する」か、もしくは「Double 値同士として引き算してみて、その結果の絶対値が十分に小さい値であれば、同じ時刻であると見做す」などの対処が必要です。

    2019年8月16日 6:25