ワークシートイベント
ワークシートイベントとは「ワークシートが○○した時、自動で対象のマクロを実行する」というようなイベントになります。ワークシートイベントはその名前の通り、ワークシートに対してのイベントなので、通常のマクロのように標準モジュールに記述ではなく、シートモジュールに記述しないといけません。
シートモジュールはVBAの画面で対象のシートをダブルクリックすると出てきます。
出てきたシートモジュールの上に、2つのリストボックスがあると思います。
そこを開いてあげることで、ワークシートイベントを自動でつけてあげることが出来るので、そこを利用してもいいです。
私はこのワークシートイベントについては全然詳しくないのですが、1つだけ是非使ってもらいたい物があるので紹介します。
そのワークシートイベントはChangeイベントです。
このChangeイベントはセルの値が変更された時、値を変更したセルが引数として渡されます。
つまりA1のセルを編集したら、A1のセルが引数に代入されますし、B1のセルが編集されたら、B1のセルが引数に代入されます。
これだけ説明しても全然わからない人も多いと思いますので、まずはコードを見てみてください。
Private Sub Worksheet_Change(Byval Target As Range)
MsgBox Target.Address
MsgBox Target.Value
End Sub
上記のコードをシートモジュールへ記載後、どこでもいいのでセルを編集して確定してみてください。2つのメッセージボックスが出てきて、編集したセルの場所と編集した内容が表示されたと思います。
Changeイベントを使うと、このように編集したセルを引数に渡してくれるのです。
※引数がわからない方はこちらを確認してみてください。
Changeイベントを使った便利な機能
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Object
Set rng = Intersect(Range("A1:A100"), Target)
If rng Is Nothing Then
Exit Sub
Else
If IsEmpty(rng.Value) Then
rng.Offset(0, 1).Value.ClearContents
Else
rng.Offset(0, 1).Value = Date
End If
End If
End Sub
このコードはRange("A1:A100")の部分が変更された時、変更したセルの横に変更した日付が表示されます。では今回はこのコードを解説していきたいと思います。
同じような使い方として、ChangeイベントとSelect Caseもご覧下さい。
Private Sub Worksheet_Change(Byval Target As Range)
この部分では、「ワークシートで変更があった時、このマクロを実行します」ということになります。
ですが、大切なのは()の中のByval Target As Rangeの部分です。
このByvalとは値渡しといいます。
ここでは詳しくは説明しませんが、この値渡し(Byval)の他に、参照渡し(Byref)があります。
これはメモリからの参照の場所の違いで、何も指定しないとByrefになる為、エラーになりますので、Byvalは忘れないようにしてください。
話を戻して、次のTargetは変数になります。
このTargetに変更があったセルの場所を代入するようになっています。
次のAs Rangeは、そのままの意味で変数の方をRange型にしています。
Dim rng As Object
これはただの変数なのでこちらをご覧下さい。
Set rng = Intersect(Range("A1:A100"), Target)
ここではIntersectという関数が出てきました。
このIntersectとは、そのまま訳すと「交わる」という意味があります。
Intersect(Range, Range)という文法になります。
ということは「A1~A100のセルの中で、Targetに代入されたセル=変更されたセルが交じり合う位置」を代入しています。
当然、A1~A100以外が変更された場合には代入されません。
If rng Is Nothing Then
ここでは「rngにセルを代入できていなかった時」という意味になります。
つまり「Set rng ~」で「A1~A100が変更されていたらrngにセルを代入」となっているので、rngが空の場合、次の処理を実行します。
Exit Sub
Exit=出口になるので、Subを終了するということになります。
つまりマクロが終了されるので、続きの処理はされません。
次のElseはIfの条件が「rngの変数が空の時」だったので、「rngに何かが代入されている時」の意味になります。
If IsEmpty(rng.Value) Then
Ifは先程も説明しているので飛ばします。
次のIsEmpty(rng.Value)が大事になります。
IsEmptyは「空」を意味します。
つまり「rngに代入されたセルの値が空の時」という意味になります。
rng.Offset(0, 1).Value.ClearContents
ここはあまり難しく考えなくて大丈夫です。
「rngの1つ右のセルの値を空にしてください」と書いています。
Offsetは「基準(rng)から(下, 右)方向に」を意味します。
ClearContentsは、そのままの意味で「コンテンツを削除=空にする」と覚えてください。
rng.Offset(0, 1).Value = Date
これはOffset(0, 1).Valueまではわかりますよね?
一つ右のセルです。
次のDateは、通常「yyyy/m/d」のフォーマットで年月日を取得します。
これはFormat関数を使って、【Format(Date, "yyyy年m月d日")】と記載してあげることで、表示形式は変更できます。
後は全てEndで閉じていくだけです。
このコードではA1~A100のセルに限定していますが、Range()の中の数字を変えてあげることで、A列以外を編集した時にも、編集日時を取得するように出来るので、応用してみてくださいね。
最後に
ワークシートイベントは他にも範囲選択をした時やシートがアクティブになった時など、色々種類があるので、これから使っていく中で便利だなと思うものがあったら紹介していこうと思います。
また、途中でもあげてますが、ChangeイベントとSelect Caseを使って、入力した文字を変換する方法も解説しているので、よかったら見てください。