プログラムでの日付の扱い方

VBA入門講座

はじめに

 Excelで日付を扱うとき、注意すべきことは、以下の点です。
 ・入力により自動変換が起こる
 ・シリアル値と書式設定で日付を扱っている

 また、プログラミングでは、日付専用の変数型や関数が存在するので、これらを意識する事です。

 とはいえ、よく使うものは決まっているのでそれらに慣れていけば良いでしょう。

日付入力による自動変換

 文字列で入力した値が、日付と認識できる場合、Excelでは自動で日付型に変換されます。
 これは、日付に限ったことではなく、金額などでも値と書式設定が同時に設定されます。

 CSVファイルでデータをやり取りする時など、失敗したくなければ、Excelが認識しやすい形にした方が良いでしょう。
 以下のようなフォーマットが扱いやすいと思います。
 
 2023/8/11   このフォーマットを推奨します
 2023年8月11日

 逆に以下のようなフォーマットは注意が必要でしょう。
 
 令和5年8月11日   元号が変わると対応しずらい
 2023年8月     日付が無い。(暗黙で1日となる)
 8/11        年が無い。(暗黙で今年が年となる)

シリアル値と書式設定

 日付が表示されているセルを転記するためには、値(シリアル値)だけでなく書式設定のコピーも必要になります。
 この辺のノウハウについては、以下のページにまとめてあります。
 ・日付のコピーで起こる不具合

 結論としては、前回やったように値+書式設定をコピーするか、Copyコマンドを使用して両者を一気にコピーしてしまう事になるでしょう。

値+書式設定をコピー

Sub 日付CopyTest1()
    Range("C2") = Range("B2")
    Range("C2").NumberFormatLocal = Range("B2").NumberFormatLocal
End Sub

Copyコマンドを使用

Sub 日付CopyTest2()
    Range("B2").Copy
    Range("C2").PasteSpecial Paste:=xlPasteAll
End Sub

Copyコマンド

 RangeオブジェクトのCopyコマンド(メソッド)を使えば、日付に限らずセルの属性を他のセルにコピー出来ます。
 このコマンドは、Excel操作のコピーと同じです。

  Range(“B2”).Copy
  Range(“C2”).PasteSpecial Paste:=xlPasteAll

 上記のようにコピー貼り付け(ペースト)は別の動作となります。
 コピー元でCopyすると、一旦クリップボードと呼ばれる場所に保存されます。
 PasteSpecialが貼り付け操作で、 Paste:=xlPasteAll 貼り付けオプションとなります。
 xlPasteAll 「全て」となります。

日付型と日付用の関数

 VBAでは日付型Dateがあります。
 同じ綴りでDate関数もありますがこちらは今日の日付を返します。混同しないようにしましょう。
 定義と初期化は以下のようになります。
 
 Dim myDay As Date
 myDay = #12/1/2023#

 直接日付を代入する場合は##で囲みます。

 日付型の扱い方に付いては以下のページも参考にしてみてください。
 ・日付の扱い方

 ここではすぐに使えそうなサンプルコードを示します。

年、月、日を抽出する

 それぞれの値は数値で出力されます。

Sub 日付Sample()
    Dim myDay As Date
    myDay = #12/1/2023#
    
    Debug.Print myDay           '日付を出力 2023/12/01
    Debug.Print Year(myDay)     '年を出力 2023
    Debug.Print Month(myDay)    '月を出力 12
    Debug.Print Day(myDay)      '日を出力 1

End Sub

今日の日付を取得(Date関数)

 関数の Date は今日の日付を返します。Date型とは前後の文脈で判断します。

Sub 日付Sample1()
    Debug.Print Date
End Sub

日付型を生成する(DateSerial関数)

 年、月、日を個別にセットして日付型を生成します。

Sub 日付Sample2()
    Dim y As Long, m As Long, d As Long
    Dim myDay As Date
    y = 2023
    m = 4
    d = 1
    myDay = DateSerial(y, m, d)
    Debug.Print myDay           '出力 2023/04/01
End Sub

日時の比較

 日付はIf文などで、大・小・等しいなどの判別が出来ます。

Sub 日付Sample3()
    Dim myDay As Date
    myDay = #12/1/2023#
    
    If myDay > #11/30/2023# Then
        Debug.Print "日付が大きい"
    End If
End Sub

日付の計算

 日付ならではの計算には、DateAdd関数(日付の加算・減算)やDateDiff関数(日付の間隔)が使われます。
 詳細は以下のページを参照してください。

 ・DateAdd関数(日付の加算・減算)
 ・DateDiff関数(日付の間隔)

'日付の追加
Sub testDateAdd()
    Debug.Print DateAdd("d", 10, #9/24/2023#)
    '2023/09/24 の10日後で、2023/10/04 と表示されます。
End Sub
'日付の間隔
Sub test_DateDiff()
    Dim sDay As Date, eDay As Date
    sDay = DateSerial(Year(Date), 1, 1)
    eDay = DateSerial(Year(Date) + 1, 1, 1)
    Debug.Print Year(Date) & "年は、" & DateDiff("d", sDay, eDay) & "日。"
    '2023年は、365日。などと表示されます。
End Sub

日時の書式を設定する(Format関数)

 Format関数は日付以外の書式設定にも使われます。
 使い方は分かりやすいと思いますので是非マスターしてください。

Format関数の書式

 Format( 変数 , “書式設定” )

 日付を扱う場合は変数の所に日付型の変数を入れます。
 書式設定についてはExcelの「セルの書式設定」の「ユーザ定義」にある書式を参照すると良いと思います。
 返り値は、文字列となります。

Sub testFormat()
    Dim myDay As Date
    myDay = #12/1/2023#
    
    Debug.Print Format(Date, "ggge年mm月dd日(aaa)")    '令和5年09月11日(月)
    Debug.Print Format(Date, "開催日 yyyy/mm/dd")      '開催日 2023/09/11
End Sub

 Format関数については以下のページも参照してください。
 ・Format関数

まとめ

 VBAプログラミングで日付を扱う場合は、
 2023/8/11 という形を基本とした方が扱いやすいと思います。
 その方がCSVファイルなど外部のデータとのやり取りでトラブルが少ないと考えられるからです。
 
 一方、表記を和暦に変えたりしたい場合は、予めセルの書式を設定して置いたり、Format関数で表現するのが良いでしょう。
 
 このようにプログラムを組むときは、「データ」「表記」を区別して考えて使用するように心掛けた方が良いでしょう。
 
 日付の扱いは初心者の方々には難しいかもしれません。
 1つ2つ得意なパターンを身に付けて使い回していくようにしましょう。


コメント

タイトルとURLをコピーしました