[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Changeイベントを複数書けない』(初心者うに)
VBA初心者です。 いくつか「changeイベント+複数」で検索したスレッドを拝見したのですが、 応用できず、アドバイスをお願いします。
指定範囲に数字の入力があった場合、 その計算結果が入っている別セルの値が4を下回っていたら それぞれ異なるメッセージボックスを表示させるのが目標です。 その指定範囲が12か所あるので、各所に入力したタイミングで それぞれの計算結果に対して各メッセージボックスを出したいのですが、併記できません。
ifで併記してみて、最初に記述した箇所以外は動かなかったコードです。
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("D10:AH10")) Is Nothing Then Exit Sub If Range("AM10") < 4 Then MsgBox Range("B6").Value & "の" & ActiveSheet.Name & "の" & Range("B10").Value & "が" _ & vbCrLf & "4を下回っています。" End If
If Intersect(Target, Range("D18:AH18")) Is Nothing Then Exit Sub If Range("AM18") < 4 Then MsgBox Range("B14").Value & "の" & ActiveSheet.Name & "の" & Range("B18").Value & "が" _ & vbCrLf & "4を下回っています。" End If
'繰り返し
End Sub
また、いろいろと例示されているコードを試すなかで分からなかったのは下記2点です。 ・If Not Intersectを使うメリット ・Select Caseに向かないケース
これからもっと勉強したいと思っているので、様々なアドバイスをいただけると幸いです。 なお現在不規則勤務のため、失礼ながらお返事が数日遅れることがありますが、 どうぞよろしくお願いいたします。
< 使用 Excel:Office365、使用 OS:Windows10 >
参考に
Private Sub Worksheet_Change(ByVal Target As Range) If Intersect(Target, Range("D10:AH10,D18:AH18")) Is Nothing Then Exit Sub Select Case Target.Row Case 10 If Range("AM10").Value < 4 Then MsgBox Range("B6").Value & "の" & _ ActiveSheet.Name & "の" & Range("B10").Value & "が" _ & vbCrLf & "4を下回っています。" End If Case 18 If Range("AM18") < 4 Then MsgBox Range("B14").Value & "の" & _ ActiveSheet.Name & "の" & Range("B18").Value & "が" _ & vbCrLf & "4を下回っています。" End If End Select End Sub
(ピンク) 2020/05/14(木) 11:22
まず、インデントを付けてから、ブレークポイントを設定し何が起こっているのかを把握するのが先決だとおもいます。
そのうえで、複数の条件判定を扱いたいのであれば、Nothingだったら終了するのではなく、Nothing【じゃなかったら】処理する。というように考えてみましょう。
Private Sub Worksheet_Change(ByVal Target As Range) Stop
If Not Intersect(Target, Range("D10:AH10")) Is Nothing Then If Range("AM10") < 4 Then MsgBox _ Range("B6").Value & "の" & ActiveSheet.Name & "の" & _ Range("B10").Value & "が" & _ vbCrLf & "4を下回っています。" End If End If
If Not Intersect(Target, Range("D18:AH18")) Is Nothing Then If Range("AM18") < 4 Then MsgBox _ Range("B14").Value & "の" & ActiveSheet.Name & "の" & _ Range("B18").Value & "が" _ & vbCrLf & "4を下回っています。" End If End If '繰り返し End Sub
(もこな2 ) 2020/05/14(木) 11:23
試してないけど ↓ のように書けるはず
Private Sub Worksheet_Change(ByVal Target As Range) Select Case True Case Not Intersect(Target, Range("D10:AH10")) Is Nothing: If Range("AM10") < 4 Then MsgBox Range("B6").Value & "の" & ActiveSheet.Name & "の" & Range("B10").Value & "が" & vbCrLf & "4を下回っています。" Case Not Intersect(Target, Range("D18:AH18")) Is Nothing: If Range("AM18") < 4 Then MsgBox Range("B14").Value & "の" & ActiveSheet.Name & "の" & Range("B18").Value & "が" & vbCrLf & "4を下回っています。" End Select End Sub
※ 個人的には読みやすいと思っています。(もちろん異論のあることは承知してます)
(チオチモリン) 2020/05/14(木) 11:33
Select Case を使うと、例えば10行目と18行目を同時に編集したときに、一方にしか対応できないです 同時に編集されることはないという前提条件があればいいのですが。 (´・ω・`) 2020/05/14(木) 12:33
どうも、入力されたセルが【指定箇所】の範囲内だったら
変更されたセルがある行の【AM列】の値をチェックし、4以下であれば、 4行上のB列 & その行のB列 が4を超えている
というように読める気がします。
もし、一定のルールがあるなら、そもそも12個のパターン全部を書く必要ないとおもいますがいがでしょうか?
(もこな2 ) 2020/05/14(木) 12:48
Private Sub Worksheet_Change(ByVal Target As Range) Dim c As Range For Each c In Target If Not Intersect(c, Range("D10:AH10,D18:AH18")) Is Nothing Then If Cells(c.Row, "AM").Value < 4 Then MsgBox Cells(c.Row - 4, "B").Value & "の" & _ ActiveSheet.Name & "の" & Cells(c.Row, "B").Value & "が" _ & vbCrLf & "4を下回っています。" End If End If Next c End Sub
(ピンク) 2020/05/14(木) 13:37
みなさま、ご回答ありがとうございます。 すべてうまく動きました! もこな2さまのコードはブレークポイントを確認してからStopを削除して動きました。 今回は違う行を同時に編集することはないので、いずれも望み通りの結果になりました。
そして、新たな視点をありがとうございます。 もこな2さまの仰る通りでございます。 指定範囲は8行ずつ下がり、チェックするのは必ずAM列で、いずれもその4行上のB列の内容を表示したいのです。 なぜ気づかず併記しか頭になかったのか、お恥ずかしい……。 その後にピンクさまが書いてくださったコードも走りました。
でも近々レイアウトの違うシートで同じことをするので、 いろんなパターンを併記できるコードも使わせていただきます。
超初心者がこっぱずかしいことを言いますが、VBAって楽しいですね! みなさま、本当にありがとうございました。
(初心者うに) 2020/05/14(木) 14:23
もこな2さまにお伝えし忘れていました。
>Nothing【じゃなかったら】処理する ためにIf Not Intersectにする必要があるのですね。 なぜnoを重ねなければいけないのか、そのまま素直に書いたらダメなのかが疑問でしたが、 理解できました。 アドバイスありがとうございました。 (初心者うに) 2020/05/14(木) 14:41
>理解できました。 との事なので蛇足ながら VBA の演算子(演算子の優先順位) https://excelwork.info/excel/priority_of_operator/ とか一読されるとよいかも
つまり
( Not Intersect(c, Range("D10:AH10,D18:AH18")) )Is Nothing なのか
Not ( Intersect(c, Range("D10:AH10,D18:AH18")) Is Nothing )なのか ということなんですが
>If Not Intersectにする必要が....
と書かれていますとちょっと...
(チオチモリン) 2020/05/14(木) 18:16
>指定範囲は8行ずつ下がり、チェックするのは必ずAM列で、いずれもその4行上のB列の内容を表示したいのです。 D10:AH10〜D98:AH98 8行ずつ 計12行に対応してみました。
Private Sub Worksheet_Change(ByVal Target As Range) Dim c As Range For Each c In Target If (c.Row - 8) Mod 8 = 2 And c.Row <= 98 And c.Column >= 4 And c.Column <= 34 Then If Cells(c.Row, "AM").Value < 4 Then MsgBox Cells(c.Row - 4, "B").Value & "の" & _ ActiveSheet.Name & "の" & Cells(c.Row, "B").Value & "が" _ & vbCrLf & "4を下回っています。" End If End If Next End Sub
(ピンク) 2020/05/14(木) 19:01
Private Sub Worksheet_Change(ByVal Target As Range) Dim MyRNG As Range Dim i As Long
'▼チェック範囲を特定 With Range("D10:AH10") Set MyRNG = .Cells
For i = 1 To 11 Step 1 Set MyRNG = Union(MyRNG, .Offset(i * 8)) Next i End With
'▼変更のあったセルがチェック範囲にあるか判定して、変更のあったセルがチェック範囲に1つもなければ、即終了 If Intersect(MyRNG, Target) Is Nothing Then Exit Sub
'▼ ↑で終了していないときだけ処理 With Cells(Target.Row, "B") If Cells(.Row, "AM").Value < 4 Then MsgBox .Offset(-4).Value & "の" & Me.Name & "の" & .Value & "が" & vbCrLf & "4を下回っています。" End If End With
End Sub
(もこな2 ) 2020/05/14(木) 20:49
Private Sub Worksheet_Change(ByVal Target As Range)
'▼変更のあったセルがチェック範囲にあるか判定して、変更のあったセルがチェック範囲に1つもなければ、即終了 If Intersect(Intersect(Range("B10,B18,B26,B34,B42,B50,B58,B66,B74,B82,B90,B98").EntireRow, Range("D:AH")), Target) Is Nothing Then Exit Sub
'▼ ↑で終了していないときだけ処理 With Cells(Target.Row, "B") If Cells(.Row, "AM").Value < 4 Then MsgBox .Offset(-4).Value & "の" & Me.Name & "の" & .Value & "が" & vbCrLf & "4を下回っています。" End With End Sub
(もこな2) 2020/05/15(金) 12:51
みなさま、アドバイスありがとうございます。 返信が遅くなり申し訳ありません。
チオチモリンさまのご指摘の通り、カッコの優先順位の話とは捉えられていませんでした。 あやうく構文であるかのようにうろ覚えしてしまうところでした。
ピンクさま、Modを使うんですね。 VBAをさわりはじめる以前も関数としてあまり使ったことがなかったので、 自分では出てこなかったと思います。
もこな2さま、2種類もありがとうございます。 私には「行数を減らしてみたバージョン」がわかりやすかったです。 まだ、変数でスッキリと収納する頭にはなっていないようです。
(初心者うに) 2020/05/18(月) 14:42
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.