こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

エクセルVBAのif文で同じ処理をまとめる方法

エクセルのVBAのif文で質問です。
・J1セルに「1302」が入っており、K1セルが空欄だった場合、K1セルに「0000」を入力する
という場合、
If .Range(J1).Value = "1302" And .Range(K1).Value = "" Then
 .Range(K1).Value = "'0000"
End If
となりますが、これがJ1=1302だけではなく2117や4101など、10種類以上の異なる値で同じ処理が必要な場合
同じ形のプログラムを羅列していく以外の書き方はありますでしょうか?
if~End ifがいくつも並んでいて、うまくスッキリとまとめられないのだろうかと思い質問しました。
よろしくお願いいたします。

投稿日時 - 2017-12-25 17:13:30

QNo.9411549

暇なときに回答ください

質問者が選んだベストアンサー

Case文を使うと条件が併記できます。

If .Range(K1).Value = "" Then
 Select Case .Range(J1).Value
  Case "1302","2117","4101"
   .Range(K1).Value = "0000"
 End Select
End If

ばらしても同じ

If .Range(K1).Value = "" Then
 Select Case .Range(J1).Value
  Case "1302"
   .Range(K1).Value = "0000"
  Case "2117","4101"
   .Range(K1).Value = "0000"
 End Select
End If

投稿日時 - 2017-12-25 18:08:08

お礼

読みやすく、条件が増えた際にも対応が容易でしたのでこちらの上の形を使わせていただきました。
4桁の異なる値を基準に考えるのではなく、空欄を基準にselect caseで作っていけばよかったのですね。大変勉強になりました。
質問では省きましたがこの処理は10000行ほどに対して行うので、プログラム修正前と修正後でかかる時間が半分に短縮されました。
本当にありがとうございました。

投稿日時 - 2017-12-26 12:27:55

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(6)

ANo.6

せっかくExcelを使うんですからシート上に対応リストを持ってはいかがでしょう。
添付の図の例ではM列を対応リストとして使用しています。

Sub Sample()
  'K1が空白でなければ終了
  If Range("K1") <> "" Then End
  
  'M列に該当するものがあればK1=0000
  nCount = WorksheetFunction.CountIf(Range("M:M"), Range("J1"))
  If nCount = 1 Then Range("K1") = "0000"
End Sub

投稿日時 - 2017-12-26 00:42:41

お礼

わざわざ画像までご用意していただきありがとうございました。
あらかじめリストを作成しておくのが当方のケースではちょっと難しかったのですが、今後の参考にさせていただきます。
ありがとうございました。

投稿日時 - 2017-12-26 12:41:44

ANo.5

>同じ形のプログラムを羅列していく以外の書き方はありますでしょうか?
回答No.4と凡そ同じですが次のようなコードで良いと思います。
Sub test()
Dim m
Dim d, i, k, n
d = Range("J1").Value
k = "K1"
n = 0
m = Array(1302, 2117, 4101, 3320, 5313, 6354, 7682, 8812, 9231, 10332)
For i = 0 To UBound(m)
If d = m(i) Then
If Range(k).Value = "" Then Range(k).Value = "0000"
i = UBound(m)
End If
Next i
End Sub

比較対象が複数のとき配列変数へ代入してForループでチェックし、一致する条件が見付かったときループから抜け出す方法になります。

投稿日時 - 2017-12-25 23:13:59

お礼

配列をすっかり忘れており、Arrayで対応することに思い至りませんでした。こちらのやり方も見やすくわかりやすいですね。
教えていただきありがとうございました。

投稿日時 - 2017-12-26 12:48:43

ANo.4

私も、フレキシブルに対応でき、可読性を疎かにしない策として
Select Case を推します。

例えば(K列は数値を文字列で表示しているとして)
Sub sample()
  If Range("K1").Value = "" Then
    Select Case Range("J1").Value
      Case "1302"
        Range("K1") = "0000"
      Case "2117"
        Range("K1") = "0000"
      Case "4101"
        Range("K1") = "0000"
      'Case Else
      '  Range("K1") = ""
    End Select
  End If
End Sub
こんな感じで色々対応できます。
ただし、条件が多くなってくると If より少し遅くなってしまいますので、
その辺はうまいこと調整してやってください。

んで、今回の例示だとK1セルが空白であることが前提ですから、
実はココ(最初の If )は無視してもあまり変わらないのかもしれませんね。
つまり、
Sub sample2()
  Select Case Range("K1").Value & Range("J1").Value
    Case "1302": Range("K1") = "0000"
    ' (略)
  End Select
End Sub
まぁ、大きく変わりませんが、こうですね。

↑こんな意味で、そこそこフレキシブルに対応できるヤツですので、
覚えておいて損はないと思いますよ。

投稿日時 - 2017-12-25 18:58:36

お礼

ベストアンサーの方と同様のアプローチで分かりやすくご提示いただいてありがとうございました。
このやり方は今後も使うシチュエーションが多いと思いますのでしっかり覚えておきます。

投稿日時 - 2017-12-26 12:44:30

ANo.3

下記のようなことではないか。
VBAをやり始めると、すぐ起こる必要な手法ではないか。事前に事例集を読んで備えよ。
配列に10数個の値を作っておいて、配列の要素をi とするとして、 iを0からUBoundまで、 繰り回して聞けば、仕舞いのことではないか?
Sub test01()
Range("K1").Clear
d = Array(1, 3, 8, 13, 12, 45, 23)
MsgBox UBound(d) '上例では0-6の6が表示される
For i = 0 To UBound(d)
If Range("A1") = d(i) And Range("K1").Value = "" Then
Range("K1") = "'" & "0000"
End If
Next i
End Sub
それよりも、小生最近使わないせいで、"'" & "0000"の部分の方が手間取った。

投稿日時 - 2017-12-25 18:10:28

お礼

いままで配列を使うことが全然なかったためArrayの存在をすっかり忘れていました。ご提示いただきありがとうございました。

投稿日時 - 2017-12-26 12:45:39

ANo.1

とりあえず2通りの方法を。

■IF文の条件をORでつないで複数記述する。

Public Sub test()

'カッコで囲ったORで条件を繋げて、カッコの外でAND条件も書く
If (Range("J1").Value = "1302" Or Range("J1").Value = "2117" Or Range("J1").Value = "4101") And Range("K1").Value = "" Then
Range("K1").Value = "0000"
End If

End Sub

■あらかじめ比較対象の文字列複数個を入れたDictionaryというものを使う

Public Sub test2()

'こちらは、If文の数式の前に、事前に条件となる文字列を複数個入れたDictionaryというものを用意しておき、
'If文の中では直接イコールで比較するのではなく、Dictionaryが持つ機能で「対象の文字が入ってる?」という
'確認を行います。

'Dictionary「jouken」を作る
Dim jouken As Object
Set jouken = CreateObject("scripting.dictionary")

'条件を入れるときは、実際の文字列と、索引になる文字列の2情報が必要。ここではどちらも同じものを設定します
 '必要に応じてここの処理をふやせば10個でも20個でも大丈夫ですし、
 'なんなら事前にExcelシートのどこかに条件を書いておいて、ループでDictionaryに入れてもよいですね。
jouken.Add "1302", "1302"
jouken.Add "2117", "2117"
jouken.Add "4101", "4101"

'Dictionaryに対象の文字列が入っているかどうかは「Exists」という命令で判断できます。
 '入っていたらTrueになりますので、以下のように記述できます。
If jouken.exists(Range("J1").Value) And Range("K1").Value = "" Then
Range("K1").Value = "1111"
End If

End Sub

投稿日時 - 2017-12-25 17:59:41

お礼

dictionaryというオブジェクトを知りませんでしたので
ご説明を読ませていただき他サイトも見てみましたが、このような使い方ができるオブジェクトがあるのですね。勉強になりました。
ありがとうございました。

投稿日時 - 2017-12-26 12:39:13

あなたにオススメの質問