日付に曜日を配置する

ラボ

日付に曜日を配置する

 今回は月間予定表のような表に日付と曜日を入力するプログラムをVBAで作りたいと思います。
  VBAを使用しなくても、セルに数式マクロを仕込む事でもできるのですが、プログラミングの練習という事で作ってみます。
 初心者向けの内容ですので、VBAのプログラムを始めて間もない方は是非挑戦してみてください。

プログラムの仕様

 今回は、「〇〇〇〇年 〇月度」の所に「2022/4/1」などと入力すると、日付とともに曜日を自動入してくれるものとします。
 月末は大の月、小の月をカレンダー通りにセットしてくれるようにしたいと思います。

 完成すると以下のような表になります。

プログラミング

 日付の1~28日は常にありますので固定で構いませんが、今回は逐次書き込んでいきます。29日~31日は月によって変動しますので条件分岐して入力を分けます。31日が無い月などは、日付・曜日ともに空白を入力します。

 こうすることで前に値があるときでも正しく表記されます。

 曜日に関しては日付を取得すればFormat関数で得られますので、それほど難しくはありません。


 あとはFor文で1~31までループして、必要な値を入れていけばいいでしょう。

 プログラムを実行するきっかけは、セルの変化を拾うイベントを使う事にします。

プログラムコード

まずは日付と曜日を入力していくコードです。以下のコードは標準モジュールに書きます。

Sub macro()
    Dim i As Long
    Dim myDay As Date
    
    If IsDate(Range("A1")) Then
        myDay = Range("A1")
    Else
        MsgBox "A1セルに日付をセットしてください"
        Exit Sub
    End If
        
    For i = 1 To 31
    
        If i < 29 Then
            Cells(i + 2, "A") = i
            Cells(i + 2, "B") = Format(myDay + i - 1, "aaa")
        Else
            If Day(myDay + i - 1) < 29 Then '翌月になってしまうとき
                Cells(i + 2, "A") = ""
                Cells(i + 2, "B") = ""
            Else
                Cells(i + 2, "A") = i
                Cells(i + 2, "B") = Format(myDay + i - 1, "aaa")
            End If
        End If

    Next i

End Sub

最初の If IsDate(Range(“A1”)) Then ですが、A1セルに日付が入っていないとエラーとなるので、それを確かめています。

上の図では、2022年2月度 となっていますが、これはセルの書式設定のユーザー定義で、以下のように変更しています。

これで、2022/2/1 とすれば 2022年2月度 と表示されるようになります。
このようなテクニックはよく使うので覚えておくとよいでしょう。

続くFor文では、1~31まで巡回しています。Cellsでは行に合うように2を足しています。
29未満の場合は、そのまま日付と曜日を入力しています。
曜日はFormat関数で”aaa”とすると得られます。

29日からは該当する日付を得て、翌月になっていれば29未満なので空白を入力するようにします。

イベントプロシージャでマクロを実行

 上記のマクロを実行させる処理は、シートのA1セルが書き換わったタイミングで行うようにしてみます。

 初心者には少々難しいかもしれませんが、いずれこのような処理を行う事もあるかと思いますので参考にしてみてください。

プログラムコードは、プロジェクトウインドウのシートをクリックしてシートモジュールに書きます。
シートモジュールでは、上部に「Worksheet」が選択できるようになります。選択したら右の枠から「Change」を選択すると、Worksheet_Changeというイベントプロシージャが書き加えられます。

プロシージャ内に図のようなコードを書いていきます。

 Worksheet_Changeというイベントプロシージャは、シートの内容が書き換えられるたびに呼ばれますので扱うときに注意が必要です。
 具体的には、Worksheet_Change内部でセルの値を書き換えると、そのことでWorksheet_Changeが呼ばれて無限ループのような状態になってしまいます。

 これを防止するために用いるのが Application.EnableEvents = False になります。
これで一時的にイベントプロシージャの動作を無効にして二重に呼び出すのを抑止しています。

 今回の場合は、If Target.Address() = “$A$1” Then の条件分岐で、A1に変化があった時のみに限定しているので、これを使わなくても動きます。

 続いて、Call macro で日付・曜日入力を行います。

 最後に、Application.EnableEvents = True としてイベント動作を元に戻しています。
これを忘れるとイベント動作が起こらずExcelの動作がおかしくなります。
もしそうなった場合は、一旦保存して終了し、再度開けば元に戻ります。

最後に

 いかがだったでしょうか。イベントプロシージャを用いる方法が難しいと感じた場合はボタンを設置して、macro関数を割り当てても良いでしょう。
 ちなみにボタンは印刷されないはずです。(最初の設定ではそうなっているはずです。)

 このような動作はセル内に数式マクロをセットすることでもできます。数式マクロがセル一つ一つに入力していくのに対して、VBAを使った処理では全体を一括りに捉えてプログラミングしていくことになります。

 VBAでのプログラミングでは、数式マクロを使う方法に比べて、変数が使えたりFor文などの繰り返し処理が使えるので、より高度な仕組みを作ることができます。

 これまで数式マクロで行っていた処理をVBAで置き換えてみるのも勉強になりますので挑戦してみてはいかがでしょうか。

コメント

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