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

このQ&Aのポイント
  • エクセルVBAのif文で異なる値に対して同じ処理を行いたい場合、効率的にまとめる方法はありますか?
  • エクセルVBAのif文で複数の値に対して同じ処理を行いたい場合、効果的なコーディング方法を教えてください。
  • エクセルVBAのif文を使って異なる値に対して同じ処理をまとめる方法を教えてください。
回答を見る
  • ベストアンサー

エクセル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がいくつも並んでいて、うまくスッキリとまとめられないのだろうかと思い質問しました。 よろしくお願いいたします。

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

  • ベストアンサー
  • kichi8000
  • ベストアンサー率41% (658/1580)
回答No.2

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

shima-008
質問者

お礼

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

その他の回答 (5)

  • mt2015
  • ベストアンサー率49% (258/524)
回答No.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

shima-008
質問者

お礼

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

  • bunjii
  • ベストアンサー率43% (3589/8248)
回答No.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ループでチェックし、一致する条件が見付かったときループから抜け出す方法になります。

shima-008
質問者

お礼

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

回答No.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 まぁ、大きく変わりませんが、こうですね。 ↑こんな意味で、そこそこフレキシブルに対応できるヤツですので、 覚えておいて損はないと思いますよ。

shima-008
質問者

お礼

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

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.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"の部分の方が手間取った。

shima-008
質問者

お礼

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

  • _backyarD
  • ベストアンサー率34% (199/580)
回答No.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

shima-008
質問者

お礼

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

関連するQ&A

  • Excel VBA If文の処理について

    Excel VBA If文の処理方法で質問です。 http://www.sigoto.co.jp/excel/statement/state09.htm を参考にしながら作ってます。 ▲空白なら の方法は記載されていますが… If 要素.Value = Empty Then ~ ▲セルに(文字・数値に関係なく)情報があるなら… という定義をしたいのですがどうやればよろしいでしょうか? If 要素.Value != Empty Then ~ これだとエラーが返りました。VBAは (※Else以外の方法で) 否定文の処理方法ってありますか? *内容抜粋* Set cell = Range("G5:I9") If cell.Value = "" Then '…ここの定義どうやれば良いか? ・ ・ End If アドバイスよろしくお願い致します。

  • VBAで処理フラグの立て方

    こういった条件でやりたいのですがうまくいきません・・・ 処理フラグの立て方は間違っていないと思うのですが・・・ ちょっとセルとかは変えてあります。 もしE3の値が4で割り切れたら8行目を削除し次の処理は行わない もしE3の値が4で割り切れなかったらE4の値が4で割り切れるか処理をする。 割り切れたら18行目を削除 E3とE4の値両方が4で割り切れなかったら8行目を削除し1行あがるので17行目を削除したいです Sub rdlt() If Range("I1").Value = 0 Then Range("I1").Value = 1 '処理は一度きり If Range("E3").Value Mod 4 = 0 Then Rows("8:8").delete '4で割れたとき8行目を削除 Range("J1").Value = 1 '4で割れたときは次の処理用にフラグ End If If Range("J1").Value = 0 Then 'E3が4で割れなかったときは処理する If Range("E4").Value Mod 4 <> 0 Then Rows("18:18").delete Range("J1").Value = 1 End If End If End If End Sub

  • Excel VBA

    初心者で済みません 少し困っています。よろしくお願いします。 Range("J17") = Range("F17") * Range("H17") If Range("J17").Value = "0" Then Range("J17").Value = "" End If Range("J18") = Range("F18") * Range("H18") If Range("J18").Value = "0" Then Range("J18").Value = "" End If Range("J19") = Range("F19") * Range("H19") If Range("J19").Value = "0" Then Range("J19").Value = "" End If 上記のコードを簡単にしたいのですが、どうすればいいのか、わかりません。どうか教えていただけませんでしょうか?

  • 再質問 長いIF文を短くしたい

    お世話になっております 先日1/24に、条件を示さずに「長いIF文を短くしたい」という質問をしてしまいました こちらの手抜きをお詫びします 前回keithinさんにアドバイスいただいた方法で書き直しましたので これをさらに簡単に書く方法があれば教えてください 以下は、Private Sub Worksheet_Change(ByVal Target As Range)内のマクロです If Target.Row >= 15 And Target.Row <= 100 And Target.Column = 9 Then If Range("I" & Target.Row).Value < Range("J" & Target.Row).Value Then If Range("G" & Target.Row).Value >= 1 Then If Range("I" & Target.Row).Value >= Range("G" & Target.Row).Value Then If Range("I" & Target.Row).Value Mod Range("G" & Target.Row).Value = 0 Then  処理 End If End If End If End If End If

  • エクセル VBAマクロ if文 はどうすれば?

    先ほど質問したのですが、さらにわからなくなったのでお願いします 先ほどの質問 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http://okwave.jp/qa/q7236338.html >変数と式の両立は難しいでしょうからどうすればよいのでしょう?  ⇒関数では出来無いのはエクセルの常識ですのでマクロ(VBA)組込みになります。 一例です。 対象シートタブ上で右クリック→コードの表示→以下のコード貼り付けてA1に枚数を入力して お試しください。 サンプルコード Private Sub Worksheet_Change(ByVal Target As Range) 単価 = 5 If Intersect(Target, Range("A1")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then  Application.EnableEvents = False  Target.Value = Target.Value * 単価  Application.EnableEvents = True End If End Sub ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ↓変更&応用したのですが、、、、 EX:(セル)    セル番号  用紙種類1~3       用紙種類    C12   A3モノクロ1     D12  A3カラー1    C13   A3モノクロ2     D13  A3カラー2    C14   A3モノクロ3     D14  A3カラー3 ※金額の違いは、モノクロとカラーの値段が違うだけ  1~3は金額的な違いはない とあった場合、 ためしに先ほどのを応用して用いたのですが 変更点は、用紙サイズ、カラーの有無による金額        出力先セルの番号 Private Sub Worksheet_Change(ByVal Target As Range) を Private Sub A4_mono_1(ByVal Target As Range) Private Sub A4_mono_2(ByVal Target As Range) ・             ・            ・ と変更したのですがうまく動作しなかったのですが、 どういった点が悪かったのでしょうか? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 最終的な質問↓ 上記のものはVBAマクロ文は基本1つのみなので、if文で作らなくてはいけないということが分かったのですが、そこでさらに疑問が浮かびました、 Private Sub Worksheet_Change(ByVal Target As Range) If or(target.columns = C12:C14) Then 単価1 = 7.6 If Intersect(Target, Range("C12:C14")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then Application.EnableEvents = False Target.Value = Target.Value * 単価1 Application.EnableEvents = True単価1 = 7.6 elseif or(target.columns = D12:D14) Then 単価2 = 30.6 If Intersect(Target, Range("D12:D14")) Is Nothing Then Exit Sub If IsNumeric(Target.Value) And Target.Value > 0 Then Application.EnableEvents = False Target.Value = Target.Value * 単価2 Application.EnableEvents = True End If End Sub としたっ場合全く式になっていません どのようにすればよいのでしょう?

  • Excel、VBAのIF文で

     いつもお世話になります。 エクセルのVBAでセルF4からF65536までを選択していれば印刷して、それ以外を選択していれば「氏名セルを選択してください」と表示させたいのですが、うまくいきません。  全く構文かもしれませんが以下が作成したプロシージャです。VB初心者です。ご指導よろしくお願いします。 Sub 成績個人印刷if() If Range("f5,f65536").Activate = True Then Worksheets("個人カード").Range("a3").Value = ActiveCell.Offset(0, -4) Worksheets("個人カード").PrintOut End If MsgBox "氏名セルを選択してください" End Sub

  • IF文の作り方

    エクセル VBA 超入門のものなんですけど、質問させてください。 A1のセルに 1を入力したら、セルD1に正解を表示させ、 それ以外なら不正解を表示させたいのですが、  以下の文でつくると 実行した最初しか起動してないような気がするのですが、教えてください。どうすればセルA1を入力するたびに、 正解、不正解をD1に表示させれるでしょうか? Sub テスト() If Range("A1") = "1" Then Range("D1").Value = "正解" Else Range("D1").Value = "不正解" End If End Sub

  • マクロが動きません

    以下のようなプログラムでC3の値が変わるたびにA10の値に1を加えていきG3,H3が両方0になったらA10の値も0にする。C5の値が変わるたびにA15の値に1を加えJ3,K3が共に0になったらC5も0にするようにしました。 しかし、動作しません。 このシートの3行目は=シート名!セル番号 という形でほかのシートのセルの値が表示されるようになっています。G3、H3、J3、K3に手動で数値を入力した場合 は動作します。 ほかのシートのセルの値を表示させたセルの値が変化しても動作させる方法はないでしょうか> Private Sub worksheet_change(ByVal target As Range) With target If .Count > 1 Then Exit Sub If IsNumeric(.Value) = False Then Exit Sub If IsEmpty(.Value) = True Then Exit Sub If Not .Row = 3 Then Exit Sub Select Case .Column Case 3 Range("A10").Value = Range("A10").Value + 1 Case 5 Range("A15").Value = Range("A15").Value + 1 End Select End With If Range("g3").Value = 0 And Rang("h3").Value = 0 Then Range("A10").Value = 0 If Range("j3").Value = 0 And Rang("k3").Value = 0 Then Range("A15").Value = 0 End Sub

  • Excel VBA IF文がうまく動作しないわけがわかりません…

    未熟な私ですが… セルC2の文字列の6・7桁目に入っている文字により、8桁目の文字を 置き換えるものをつくりました。 例えば、セルのC2に、IRCD-311234 という値があれば IRCD-31A234 にしなさいというものです しかし、 ElseIf の条件式にあてはまるものがでてきても、 すべて最初のIFの条件式にしてしまい、Elseifに反応してくれません。 ****************************************************** Sub 変換() Dim DAT As Range Dim CAR As String If Mid(Range("C2").Value, 6, 2) = 31 Or 32 Or 33 Then For Each DAT In Range("A1:P40")     CAR = CStr(DAT) If Left(CAR, 5) = "IRCD-" Then    CAR = Left(CAR, 7) & "A" & Right(CAR, Len(CAR) - 8)  DAT.Value = CAR End If Next ElseIf Mid(Range("C2").Value, 6, 2) = 37 Or 38 Or 39 Then For Each DAT In Range("A1:P40") CAR = CStr(DAT) If Left(CAR, 5) = "IRCD-" Then CAR = Left(CAR, 7) & "B" & Right(CAR, Len(CAR) - 8) DAT.Value = CAR End If Next  End If  End Sub ****************************************************** 本やネットを見ているのですが、何が悪いのか私にはわかりません…。 どうかご指導をお願いいたします。

  • エクセル VBAで

    はじめまして。 VBA初心者です。 エクセルVBAで以下のことをしようとしていますが、 「型が一致しません」とエラーが出ます。 何がおかしいのでしょうか。 やろうとしていることは、以下のようなことです。 G2に入っている値を参照し>0なら、H2に”上昇”と表示。 <0なら、”下降”、=0なら”トンボ”と表示させ、G3以降も G列にデータが入っている限りそのように表示したいと思っております。 よろしくお願いいたします。 Sub 陰陽() If Range("G2:G10000").Value > 0 Then Range("H2:H10000").Value = "上昇" ElseIf Range("G2:G10000").Value < 0 Then Range("H2:H10000").Value = "下降" ElseIf Range("G2:G10000").Value = 0 Then Range("H2:H10000").Value = "トンボ" End If End Sub

専門家に質問してみよう