質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

8706閲覧

VBAのWorksheet_Changeで単一セルでの変更と複数範囲での変更で挙動を変えたい

soxhog

総合スコア1

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2020/06/18 11:21

VBAのWorksheet_Changeで単一セルでの変更と複数範囲での変更で挙動を変えたい

やりたいのは複数セルがコピペなどで一度に変更されたときには何もしない。単一セルが変更されたときだけ処理をしたいです。
A列には日付と時間、B列には国名が入力されています。
そしてA列とB列に入力された値が他の行にもある場合MsgBoxを出したいのですが、
上の行のA列とB列をコピーして、その下に貼り付ける場合もあるのでその場合はMsgBoxを出したくありません。

イメージ
A1 = 2020/6/18 12:00 B1 = アメリカ
A2 = 2020/6/18 13:00 B2 = 日本
A3 = 2020/6/18 13:30 B3 = 中国

上記の状態の時A3:B3をコピーしてA下記のように4:B4に貼り付ける。このときにはMsgBoxを出したくない。

A1 = 2020/6/18 12:00 B1 = アメリカ
A2 = 2020/6/18 13:00 B2 = 日本
A3 = 2020/6/18 13:30 B3 = 中国
A4 = 2020/6/18 13:30 B4 = 中国

そして例えばB4の値を消してもう一度B4に中国と入力したときにはMsgBoxを出したい

B4の値を消して
A1 = 2020/6/18 12:00 B1 = アメリカ
A2 = 2020/6/18 13:00 B2 = 日本
A3 = 2020/6/18 13:30 B3 = 中国
A4 = 2020/6/18 13:30 B4 = ""

もう一度B4に中国と入力
A1 = 2020/6/18 12:00 B1 = アメリカ
A2 = 2020/6/18 13:00 B2 = 日本
A3 = 2020/6/18 13:30 B3 = 中国
A4 = 2020/6/18 13:30 B4 = 中国

コードは以下のように書いていますがうまくできずMsgBoxが出てしまいます

該当のソースコード

VBA

1Private Sub Worksheet_Change(ByVal Target As Range) 2 Dim tf As Boolean, r As Range 3 tf = False 4 For each r In Target 5 If r.Column = 1 Then 6 tf = True 7 End If 8 If r.Column = 2 Then 9 If tf = False Then '単一セルのときだけ処理したい 10 'ここに入力されたものが他の行にないかどうかの処理が続きます 11 . 12 . 13 . 14 If 同じものが見つかったとき Then 15 Dim rc As Integer 16 rc = MsgBox("同じものがあるで。このまま続けるん?", vbYesNo) 17 If rc = vbNo Then 18 r.Value = "" 19 r.Offset(0, -1) = "" 20 Exit Sub 21 End If 22 End If 23 End If 24 End If 25 Next r 26End Sub

試したこと

変数tfをグローバル変数にしたりしましたがもちろん意味なかったです。
For eachでTargetを繰り返して処理してると思ってたんですが違ったのでしょうかね。。。

優しき方、どうかご教授のほどお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

やりたいのは複数セルがコピペなどで一度に変更されたときには何もしない。単一セルが変更されたときだけ処理をしたいです。

Target.Cells.Countで更新されたセルの数が取得できるので、これが1の時だけ処理をするようにすればいいでしょう。

実際のコードはもっと列があり、それぞれの列に色々な条件で動く処理が書かれている

vba

1Private Sub Worksheet_Change(ByVal Target As Range) 2 If Target.Cells.Count = 1 Then '単一セルの更新 3 Select Case Target.Column 4 Case 1 5 MsgBox "更新された列:" & Target.Column & " 更新値:" & Target.Value 6 7 Case 2 8 MsgBox "更新された列:" & Target.Column & " 更新値:" & Target.Value 9 10 Case 3 11 MsgBox "更新された列:" & Target.Column & " 更新値:" & Target.Value 12 13 End If 14 End If 15End Sub

For eachでTargetを繰り返して処理してると思ってたんですが違ったのでしょうかね。。。

あってますよ。
ただ、更新されたのが1セルだけの時の処理なら For each は不要ですよね。

投稿2020/06/18 12:17

編集2020/06/18 13:15
hatena19

総合スコア34347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

soxhog

2020/06/18 13:07

早速の回答ありがとございます! 今試す環境がないので明日会社で試してみます! 実際のコードはもっと列があり、それぞれの列に色々な条件で動く処理が書かれているので今回のケースが必要でした! 非常に助かりました!明日動作確認でき次第ベストアンサーに選ばせていただきます!
soxhog

2020/06/19 02:16

朝試してみたところ、無事思った通りに動いてくれました! またSelect caseでの処理の仕方も今まで知らなく大変勉強になりました。 VBAに触れ始めてまだ数週間ですが、お陰様でまだまだ頑張れそうです! ありがとうございました!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問