category name  »  page title date

特定のセルの値変更に反応

名前をつけた特定のセルの値が変更されたら、それに応じた関数を実行したい、ということがよくあります。このために、ワークシートのイベントとして "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 にしておけば、それほど気になりません。
この方法は、特定のセルを選択したときに何かをさせたい、といった場合に使えます。そのセルをすでに選択していると、普通はいくらそこをクリックしても新たな選択にならないので。