[[20191023232443]] 『結果の出るセルの値が変更したら』(Can) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『結果の出るセルの値が変更したら』(Can)

Changeイベントで
例えば、
A3に
=B3×C3×D3
とある場合、B3〜D3へ数値を入れることで
A3が変化しますが、
イベント設定vbaで「A3が変化したらmsg boxを出す」というコードはできますか?
これを、B3〜D3へのイベント記述無しでできますでしょうか

< 使用 Excel:Excel2016、使用 OS:Windows10 >


 数式ならCalculateイベントが発生するので、
 お遊びレベルですが・・(実際の使用には自己責任で)。

  Private Sub Worksheet_Calculate()
      Const cel2Watch As String = "A3"
      Dim oldVal

      Application.EnableEvents = False
      Application.Undo

      oldVal = Range(cel2Watch).Value

      Application.Undo

      If oldVal <> Range(cel2Watch).Value Then
         MsgBox "Changed!"
      End If

      Application.EnableEvents = True
  End Sub

(半平太) 2019/10/24(木) 00:05


被ったかな?

Undoを使えば一応できると思います。
雑に書いたのでデバッグは自己責任でよろしくお願いいたします。
(特にコピーペーストした場合などに正常に動きません。)

Private Sub Worksheet_Change(ByVal Target As Range)

Dim buf As String, buf2 As String
Dim bufRng As Range

buf = Target
buf2 = Cells(3, 1)
Set bufRng = ActiveCell

Application.EnableEvents = False
Application.Undo
bufRng.Select

If Cells(3, 1).Value <> buf2 Then

    Target.Value = buf
    MsgBox 1
Else
    Target.Value = buf
End If

Application.EnableEvents = True

End Sub

参考:[[20070815233805]]
(高橋) 2019/10/24(木) 00:17


 じゃあ別案で。こんな対応策もあるでしょう。

 (1)そのシートとは別のシート(例えば、Sheet2)に
    =Sheet1!A3
    とセットしておけば、
 (2)Sheet2のCalculationイベントが起きたときに、
    A3が変化したと認識できます。

 むろん、Sheet2には、他の計算式は置かない前提です。

(γ) 2019/10/24(木) 00:25


 >じゃあ別案で。こんな対応策もあるでしょう。

 γさんのは、いいアイデアですねぇ。

 Undoなんて危ないことをする必要もない。

 Sheet2のモジュールにこれだけで済んでしまう。
  ↓
 Private Sub Worksheet_Calculate()
     MsgBox "Changed!"
 End Sub

 ※機会があったら、私も使わせて頂きます。

(半平太) 2019/10/24(木) 09:38


半平太さん、コード例の追加を頂き、ありがとうございました。
感知するセルが複数という場合には、
Calculationでは対応できなくなるのが弱点です。
# 特定範囲の計算というのが感知できれば、他シート利用しなくてよいのですけど。
# これは余りに既存機能への影響が大きすぎるんで、MSさんもそこまでは踏み込まない。
 
| これを、B3〜D3へのイベント記述無しでできますでしょうか
実は、発生源を対象としたChangeイベントプロシージャーが本筋だと
思うんですよ。いくつあっても対応できますしね。
 
なお、UNDOを使った手法だと、計算で使っているセルを変更したときに、
カーソルの自動移動が利かなかったり、ちょっとした副作用があるんですよね。

(γ) 2019/10/24(木) 10:19


 >感知するセルが複数という場合には、 
 >Calculationでは対応できなくなるのが弱点です。

 成程です。

 すると、複数のケースも考慮し、かつUndoは使わないとなると、元の方式で
 Sheet2に前回値を覚えさせて置くことにし、Sheet1のCalculationで何とかする案が考えられます。

 問題は、どうやって前回値を覚えさせるかですが、
 ThisworkbookのOpenイベントでそれをやってしまえばいいかかもです。

 ---標準モジュールに---------

 Public Const adrToWatch As String = "A3,B4:B6" '複数のエリアを文字で指定する

 ---Thisworkbookモジュールに---------’開始値をSheet2に覚えさせる

 Private Sub Workbook_Open()
     Dim Wsh(1 To 2) As Worksheet
     Dim Temp As Range

     Set Wsh(1) = Sheets("Sheet1")
     Set Wsh(2) = Sheets("Sheet2")

     For Each Temp In Wsh(1).Range(adrToWatch).Areas
         Temp.Copy Wsh(2).Range(Temp.Address) 
     Next
 End Sub

 ---Sheet1のモジュールに-----------

 Private Sub Worksheet_Calculate()
     Dim Wsh(1 To 2) As Worksheet
     Dim Temp As Range, cel As Range

     Set Wsh(1) = Sheets("Sheet1")
     Set Wsh(2) = Sheets("Sheet2")

     For Each Temp In Wsh(1).Range(adrToWatch).Areas
         For Each cel In Temp
             If Wsh(2).Range(cel.Address).Value <> cel.Value Then
                 MsgBox cel.Address & " Changed!"
                 Wsh(2).Range(cel.Address).Value = cel.Value '変更後の値にアップデート
             End If
         Next
     Next
 End Sub

(半平太) 2019/10/24(木) 17:08


前回値には ID を使う方法もありかも。

サンプルなので Worksheet_Activate のみ

 Private Sub Worksheet_Activate()
     Dim W1 As Range
     For Each W1 In ActiveSheet.Range("A3,B4:B6")
         W1.ID = W1.Value
     Next
 End Sub

 Private Sub Worksheet_Calculate()
     Dim W1 As Range
     For Each W1 In ActiveSheet.Range("A3,B4:B6")
         If W1.ID <> W1.Value Then
             MsgBox W1.Address & " : " & W1.ID & " → " & W1.Value
             W1.ID = W1.Value
         End If
     Next
 End Sub

(チオチモリン) 2019/10/24(木) 18:05


 こんばんは!

 わちきもちょっと書いてみました。。。

 ↓こんなことではなくて?? 勘違いでしたらお許しをm(__)m

 Option Explicit
Private Sub Worksheet_Calculate()
Static x As Variant
If x <> Range("A3").Value Then MsgBox "違ったよ"
x = Range("A3").Value
End Sub
(SoulMan) 2019/10/24(木) 19:57

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.