名前をつけた特定のセルの値が変更されたら、それに応じた関数を実行したい、ということがよくあります。このために、ワークシートのイベントとして "Worksheet_Change" が用意されています。
その際に気になるのが、たとえばそこに "ABC" という文字があって、"DEF" に変更したあと、再び "ABC" に戻して他のセルに移動した場合、こちらの気分としては変更したつもりがないのに、このイベントが発生してしまうことです。
そこを神経質に切り抜けるには、セルが初めて選択されたタイミングでその値を記録しておき、Change イベントの中でその記録と突き合わせる、というようにやればよろしかろう。ということで、それをやってみました。
Sheet1
'----- セルの値を変更する前の値を記録
Private oldValueOfSelectedCell
'----- セルの選択
Private Sub Worksheet_SelectionChange(ByVal target As Range)
oldValueOfSelectedCell = target.Text
End Sub
'----- セルの値の変更
Private Sub Worksheet_Change(ByVal target As Range)
SheetChanged target, oldValueOfSelectedCell
End Sub
標準モジュール SheetChanged()
'----- シート1の Worksheet_Change イベントからこちらが呼ばれる
Public Sub SheetChanged( _
ByVal target As Range, ByVal oldValue As String)
Dim myName
Application.MoveAfterReturn = False
Application.EnableEvents = False
'実際には値の変更がなかった場合には終了
If target.Text = oldValue Then GoTo exitSub
'そのセルが名前を持っていなかった場合にも終了
On Error Resume Next
myName = target.Name.Name
If Err.Number <> 0 Then GoTo exitSub
On Error GoTo 0
'変更したセル名が対象であれば所定の Proc を実行
If myName = "TargetCell" Then ExcMyProc myName, oldValue, target.value
exitSub:
'選択を箸置きに戻す
ActiveSheet.Cells(1, 1).Select
Application.EnableEvents = True
End Sub
'----- 変更があった場合に実行する内容
Public Sub ExcMyProc(cellName, oldValue, value)
MsgBox cellName & " が " & oldValue & " から " & value & " に変更された"
End Sub
ここで、チェックしているのは "TargetCell" という名前のついたセルで、そこが変更されたら ExcMyProc() を呼ぶ、というようになっています。
"If myName = "〇〇" Then ××" の行を必要な分列挙していけば、複数の対象セルに拡大できます。
一度変更して、そのまま再度変更しようとすると、Enterキーを押してもセルを移動しないようにしたので、Change の前の SelectionChange イベントが発生しないため、ちょっと具合が悪い。そこで、仕事が終わったらセルの選択を強制的に左上の「箸置き」に戻すようにしました。1行目の行高さと1列目の列幅をそれぞれ 0 にしておけば、それほど気になりません。
この方法は、特定のセルを選択したときに何かをさせたい、といった場合に使えます。そのセルをすでに選択していると、普通はいくらそこをクリックしても新たな選択にならないので。