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

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

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

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

解決済

3回答

10223閲覧

〖VBA〗IFを使用して1つの条件に対して複数処理をしたい

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2020/11/09 20:48

前提・実現したいこと

ユーザーフォームの処理ボタンを押下した際に、条件に応じて複数処理をしたいです。

【条件1】
コンボボックスで 設問3_アンケート が選択されている場合
Callを使用し 会員の重複_設問3 と 会員以外の回答者_設問3 の処理を実施

【条件2】
コンボボックスで 設問5_アンケート が選択されている場合
Callを使用し 会員の重複_設問5 と 会員以外の回答者_設問5 の処理を実施

発生している問題・エラーメッセージ

エラーはないですが、各設問の処理に対して 会員以外の回答者 しか処理がされず
会員の重複 が処理されず困っております。

該当のソースコード

VBA

1Private Sub CommandButton4_Click() 2 3 Application.ScreenUpdating = False 4 5 If ComboBox1 = "設問3_アンケート" Then 6 Call 会員の重複_設問3 7 Call 会員以外の回答者_設問3 8 ElseIf ComboBox1 = "設問5_アンケート" Then 9 Call 会員の重複_設問5 10 Call 会員以外の回答者_設問5 11 End If 12 13 Worksheets(1).Name = "照合結果" 14 15 Application.ScreenUpdating = True 16 17End Sub

設問5も下記と同様のコードですが、E列の部分がG列になります。

VBA

1Sub 会員の重複_設問3() 2 Dim sh1 As Worksheet 3 Dim maxrow As Long 4 Dim wrow As Long 5 Dim dicT As Object 6 Dim key As String 7 Set dicT = CreateObject("Scripting.Dictionary") 8 Set sh1 = Worksheets("Sheet1") 9 maxrow = sh1.Cells(Rows.Count, "E").End(xlUp).Row 'Sheet1 E列最大行 10 sh1.Range("E2:E" & maxrow).Interior.Pattern = xlNone 11 For wrow = 2 To maxrow 12 key = sh1.Cells(wrow, "E").Value 13 If dicT.exists(key) = False Then 14 dicT(key) = True 15 Else 16 Cells(wrow, "E").Interior.Color = RGB(255, 0, 0) 'E列の該当セルは背景を赤色 17 End If 18 Next 19End Sub

こちらも設問5も下記と同様のコードですが、E列の部分がG列になります。

VBA

1Sub 会員以外の回答者_設問3() 2 Dim x As Long 3 Dim i As Long 4 5 With Sheets("Sheet1") 6 x = .UsedRange.Cells(.UsedRange.Count).Row 7 .Range("E2:E" & x).Interior.Pattern = xlNone 8 For i = x To 2 Step -1 9 If Sheets("Sheet2").Range("A:A").Find(What:=.Cells(i, 5), LookAt:=xlWhole) Is Nothing Then '一致しない 10 .Cells(i, 5).Interior.Color = RGB(0, 0, 255) 'E列の背景を青色に 11 End If 12 Next i 13 End With 14End Sub

補足情報(FW/ツールのバージョンなど)

Office 2019を使用しています。

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

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

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

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

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

meg_

2020/11/09 22:44

デバッグはされましたか?(会員の重複_設問3() の中の動きを1行ずつ追ってみると原因が分かるのではないでしょうか?)
退会済みユーザー

退会済みユーザー

2020/11/09 23:56

各プロシージャ名ごとでは問題なく処理されます。 そのためCommandButton4_Clickのプロシージャ名で まとめて処理する際に問題があるかと思っていました。 何か原因お分かりでしたらご教授いただけないでしょうか。
guest

回答3

0

ベストアンサー

1案ですが、各プロシージャを呼び出すとき、列のクリアを行うか否かを指定するようにします。
最初に呼び出すプロシージャはクリアしないといけないので、以下のようになります。
Call 会員の重複_設問3(True)
Call 会員以外の回答者_設問3(False)
各プロシージャでは、クリアが指定された場合(trueの場合)のみ、クリアするようにします。
設問5も同様にします。
尚、Sub 会員の重複_設問3の
Cells(wrow, "E").Interior.Color = RGB(255, 0, 0)  は
sh1.Cells(wrow, "E").Interior.Color = RGB(255, 0, 0)
に変更しておきました。
(現在表示されているシートのE列に着色してしまう為、明示的にSheet1のE列に着色するようにしました)
設問5のプロシージャも同様に変更してください。

VBA

1Private Sub CommandButton4_Click() 2 3 Application.ScreenUpdating = False 4 5 If ComboBox1 = "設問3_アンケート" Then 6 Call 会員の重複_設問3(True) 7 Call 会員以外の回答者_設問3(False) 8 ElseIf ComboBox1 = "設問5_アンケート" Then 9 Call 会員の重複_設問5(True) 10 Call 会員以外の回答者_設問5(False) 11 End If 12 13 Worksheets(1).Name = "照合結果" 14 15 Application.ScreenUpdating = True 16 17End Sub 18 19Sub 会員の重複_設問3(ByVal clear_flag As Boolean) 20 Dim sh1 As Worksheet 21 Dim maxrow As Long 22 Dim wrow As Long 23 Dim dicT As Object 24 Dim key As String 25 Set dicT = CreateObject("Scripting.Dictionary") 26 Set sh1 = Worksheets("Sheet1") 27 maxrow = sh1.Cells(Rows.Count, "E").End(xlUp).row 'Sheet1 E列最大行 28 If clear_flag = True Then 29 sh1.Range("E2:E" & maxrow).Interior.Pattern = xlNone 30 End If 31 For wrow = 2 To maxrow 32 key = sh1.Cells(wrow, "E").Value 33 If dicT.exists(key) = False Then 34 dicT(key) = True 35 Else 36 sh1.Cells(wrow, "E").Interior.Color = RGB(255, 0, 0) 'E列の該当セルは背景を赤色 37 End If 38 Next 39End Sub 40 41Sub 会員以外の回答者_設問3(ByVal clear_flag As Boolean) 42 Dim x As Long 43 Dim i As Long 44 45 With Sheets("Sheet1") 46 x = .UsedRange.Cells(.UsedRange.Count).row 47 If clear_flag = True Then 48 .Range("E2:E" & x).Interior.Pattern = xlNone 49 End If 50 For i = x To 2 Step -1 51 If Sheets("Sheet2").Range("A:A").Find(What:=.Cells(i, 5), LookAt:=xlWhole) Is Nothing Then '一致しない 52 .Cells(i, 5).Interior.Color = RGB(0, 0, 255) 'E列の背景を青色に 53 End If 54 Next i 55 End With 56End Sub 57 58

投稿2020/11/10 06:29

tatsu99

総合スコア5493

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

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

退会済みユーザー

退会済みユーザー

2020/11/10 11:05

回答ありがとうございます。 回答いただいた内容で問題なく処理ができました。
guest

0

今回の件の場合、プロシージャを2つに分けたとこが問題かも?

んと。。。
会員の重複
とか
会員以外の回答者
とかといっても、
どうなっているときにそう判断できるかがわかりません。

おそらく、

もし、あるセルの値が、
同じ列の中に1個より多ければ、重複(=赤く塗りつぶす)
そうでなければ、さらにA列を見て0個なら非会員(青く塗りつぶす)
いずれでもなければ何もしない

ということをやりたいのだとしたら、
一連で考えた方が簡単では?

ExcelVBA

1Option Explicit 2 3Dim mrngTable As Range 4 5Private Sub UserForm_Initialize() 6 Set mrngTable = ThisWorkbook.Worksheets(1).UsedRange 7 8 With Me.ComboBox1 9 .AddItem "設問3" 10 .AddItem "設問5" 11 End With 12End Sub 13 14Private Sub CommandButton1_Click() 15 Dim ixCol As Variant 16 17 Select Case Me.ComboBox1.Value 18 Case "設問3": ixCol = "E" 19 Case "設問5": ixCol = "G" 20 End Select 21 22 注意データ強調 ixCol 23End Sub 24 25Private Sub 注意データ強調(ByVal ixCol As Variant) 26 Dim Rng As Range 27 Dim ixColor As Long 28 29 With mrngTable 30 Set Rng = Intersect(.Cells, .Offset(1), .Columns(ixCol)) 31 End With 32 33 Rng.Interior.Color = xlNone 34 35 With Application.WorksheetFunction 36 For Each c In Rng 37 If .CountIf(Rng, c) > 1 Then 38 ixColor = vbRed 39 ElseIf .CountIf(mrngTable.Columns(1), c) = 0 Then 40 ixColor = vbBlue 41 Else 42 ixColor = xlNone 43 End If 44 45 If ixColor > -1 Then 46 c.Interior.Color = ixColor 47 End If 48 Next 49 End With 50End Sub

CountIf関数で処理速度が不満なら、
その時に、それに代わる関数を自作したら
よいかと思います。

※動作確認は行っていません。
処理の流れのイメージを再確認してください。

投稿2020/11/10 10:05

編集2020/11/10 10:13
mattuwan

総合スコア2163

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

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

0

設問の以下処理で、せっかく重複の処理で赤色にした背景が消されてますね。

.Range("E2:E" & x).Interior.Pattern = xlNone

なので、処理はされてますよ。多分。

投稿2020/11/10 00:07

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/11/10 00:38

ご回答ありがとうございます。 原因理解しました。 大変恐縮ですが、こちら同時に処理する事は可能でしょうか?
退会済みユーザー

退会済みユーザー

2020/11/10 01:04

プロシージャを分ける必要がないなら if ~ 重複の処理 else if ~ 設問の処理 でルーチンまとめるとか。 プロシージャを分ける必要があるすると、 .Range("E2:E" & x).Interior.Pattern = xlNone これが必要であるかによります。 現状の流れを汲めば、 重複の Interior.Pattern = xlNone を残して、 設問の Interior.Pattern = xlNone を消すとか。 この場合、設問プロシージャが個別に必要な場面があれば適切でないです。 上記で実現できそうになければ、要件を提示下さい。
退会済みユーザー

退会済みユーザー

2020/11/10 01:12

もしくは、.Range("E2:E" & x).Interior.Pattern = xlNone が必要な局面が限られるのであれば、 この処理だけをサブルーチンにしては如何でしょう。引数で列なり行なり指定できますし。 今回の場合、 call 上述のサブルーチン call 重複(背景クリアを除く) call 設問(背景クリアを除く) の流れで処理できるようになります。
退会済みユーザー

退会済みユーザー

2020/11/10 11:04

ご丁寧にありがとうございます。 今後の参考に致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問