• ベストアンサー

エクセルマクロについてです

以下のようなマクロで、条件A1~A4のいずれかを満たした場合は、その時点でFor-Nextを抜け(例えばi=1のときにどれかの条件を満たせばi=2,3,4は検討しない)、 さらにNの数字が増えたときに、If以下の検討をするとき、条件A1~A4の中で既に満たされた条件が含まれている行は無視する、 というようにしたいのですが、どのようにすればよいでしょうか。 N=0 Do Until N = 10 For i = 1 To 4    If 条件A1 Then B1        ElseIf 条件A2 Then B2        ElseIf 条件A3 Then B3      ElseIf 条件A4 Then B4      EndIf Next i N = N + 1 Loop

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

  • ベストアンサー
  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.5

かなりベタな書き方ですが、一例です。 80年代に流行した構造化プログラミングでは極力Goto文を使わず、プログラムスイッチを多用して、処理の流れを制御したものでした Dim N, i As Integer Dim sw1, sw2, sw3, sw4 As Boolean N = 0 Do Until N = 10  For i = 1 To 4   If 条件A1 Then    If sw1 = False Then     処理 B1     sw1 = True     Exit For    End If   Else    If 条件A2 Then     If sw2 = False Then      処理 B2      sw2 = True      Exit For     End If    Else     If 条件A3 Then      If sw3 = False Then       処理 B3       sw3 = True       Exit For      End If     Else      If 条件A4 Then       If sw4 = False Then        処理 B4        sw4 = True        Exit For       End If      End If     End If    End If   End If  Next i  N = N + 1 Loop 処理の単位が判別しやすいように「Else If 条件A Then 処理B」の記述は用いていません。その分行数は増えていますが、理解できたら行数を減らすようにコーディングしていただければよいでしょう

blackleon
質問者

お礼

ご回答ありがとうございました。 理解できるように努めます。

blackleon
質問者

補足

うまくできました。 ありがとうございました。

その他の回答 (7)

  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.8

条件が4つなら4個のフラグを用意して、それぞれの条件が満たされたことがあるか記憶する。 N = 0 Flag1 = False Flag2 = False Flag3 = False Flag4 = False Do Until N = 10 For i = 1 To 4    If 条件A1 And (Flag1 = False) Then     B1     Flag1 = True    ElseIf 条件A2 And (Flag2 = False) Then     B2     Flag2 = True    ElseIf 条件A3 And (Flag3 = False) Then     B3     Flag3 = True    ElseIf 条件A4 And (Flag4 = False) Then     B4     Flag4 = True    EndIf Next i N = N + 1 Loop

blackleon
質問者

お礼

ご回答ありがとうございました。 zap35さんのご回答をヒントにして、まさにTrick--o--さんと同じ方法でマクロを書き直していたところでした。 フラグを切り替えるという方法は、私にとって目から鱗の方法であり、質問をしてよかったと思っています。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.7

こんばんは。 #2の回答者です。 私としては、具体例をお願いしたのですが、それが出されないで、同じような文面で書くとなると、どうも、何か特別な問題ですか?もしかしたら、一見、形はVB系のようにはなっていますが、その中身は、言語が違うのでしょうか? 実際、そのコードは、見つけた値の確保のコードが出てきません。 お話のようですと、それは、ダイヤル錠を開けるようなスタイルだと思います。たぶん、Nの数字が、どこかで確保されることは予想されますが、現実のコードでも、言葉でも、そのような内容が出てきません。 例えば、ダイヤル錠だと過程して、4つの数字をひとつずつ、当てるような形になっていくのだろうとは思います。条件A1,条件A2, 条件A3, 条件A4 それぞれをFlg を True していくことと同じことだと思いますし、複雑にならずにすみます。 例 VB系ですと、例えば、このようなスタイルになります。 Dim myKey1 As Variant 'この4つに確保されます。 Dim myKey2 As Variant Dim myKey3 As Variant Dim myKey4 As Variant Sub Test2()   Dim i As Integer   Dim myKeys As Variant   Dim myCondis As Variant   Dim Cond1, Cond2, Cond3, Cond4   'ここに具体的な値を、Cond1~Cond4 の条件を入れる      myKeys = Array(myKey1, myKey2, myKey3, myKey4)   myCondis = Array(Cond1, Cond2, Cond3, Cond4)   For i = 0 To 3     OpenKey myKeys(i), myCondis(i)   Next i   MsgBox Join(myKeys, ",") End Sub Function OpenKey(myKey As Variant, Condi As Variant)   Dim j As Long   For j = 0 To 10     If Condi = j Then       myKey = j       Exit For     End If   Next j   If j > 10 Then myKey = False End Function 値が見つからない場合には、MyKey には、False が確保されます。

blackleon
質問者

お礼

いつもご丁寧な回答をありがとうございます。 実際のコードはあまりにごちゃごちゃしていて分かりにくいと思い、簡略化した容で質問させていただきましたが、それが逆にご回答いただく方には分かりにくくなっていたのだと思います。 ご回答の内容は初心者の私には少し難しいのですが、皆さんからいただいたヒントで、自分なりにもう少しやってみます。 駄目な場合は、また新たに具体的な形で質問をさせていただくかもしれませんのでよろしくお願いいたします。

  • Sinogi
  • ベストアンサー率27% (72/260)
回答No.6

補足内容を理解すると N=1 A1~A4 全true → 処理B1 N=2 A1~A4 全true → 処理B2 N=3 A1~A4 全true → 処理B3 N=4 A1~A4 全true → 処理B4 N=5 A1~A4 全true → 処理なし ************************************* N=1 A1 False A2~A4 true → 処理B2 N=2 A1 False A2~A4 true → 処理B3 N=3 A1 False A2~A4 true → 処理B4 N=4 A1~A4 全false→ 処理なし N=5 A1~A4 全true → 処理B1 N=6 A1~A4 全true → 処理なし ですか? 私ではしらみつぶしにパターンを記述するしか思いつきません。 良き回答者が現れるといいですね。

blackleon
質問者

お礼

ありがとうございました。 質問が具体的でなく分かりにくかったことをお詫びします。 ご丁寧にご回答いただいたことに感謝いたします。

  • Sinogi
  • ベストアンサー率27% (72/260)
回答No.4

>私が行いたい処理では、一度A1の条件が成立してB1の処理がされたときには、 >次のNの値からは 「If 条件A1 Then B1」の部分を無視したいのです。 「If 条件A1 Then B1」の部分を無視して 条件A2 以降は評価するのですか? それとも条件文は終了となるのですか? 条件A1 を満たしたか否かの判定子として変数を利用する方法を考えましたが、条件A2 以降の扱いで処理が変わります

blackleon
質問者

補足

条件A2 以降も評価します。 一度成立した条件は無視し、成立していない条件は評価の対象とします。

  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.3

こんな条件のかき方では回答できないように思うが。 Nや条件A1-A4がどこを対象(セルなどか)に何を判断しているのか? 相互関連はないのか? 簡単な具体例でも挙げて、質問すべき問題と思う。 些細なことだがCase文が使える稼動かとか。 Exit Forの回答で質問は済みですか。基本的過ぎて。

blackleon
質問者

補足

分かりにくい質問で申し訳ありません。 Nは行を想定しています。 その行において、ある範囲を設定してその内容を最初のセルから一つづつ調べ、一つの行の処理が終わったら次の行に移るという処理です。 条件はすべてセルの数値を対象としており、処理は条件にあった数値を足したり引いたりという単純なものです。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。 blackleonさんは、プログラミングの経験者でしたね。#1さんのご指摘のように、Exit For を入れますが、具体例があれば、かなり違うコードになるかもしれません。以下では、何か、どこかすっきりしません。通常は、ありえないコードだからです。 Dim N As Integer Dim i As Integer  N = 0   Do Until N >= 10     For i = 1 To 4       If 条件A1 Then         B1         Exit For       ElseIf 条件A2 Then         B2         Exit For       ElseIf 条件A3 Then         B3         Exit For       ElseIf 条件A4 Then         B4         Exit For       End If     Next i     N = N + 1   Loop

blackleon
質問者

補足

ご回答ありがとうございます。 かなり簡略化してしまったので分かりにくいコードになってしまいました。 For-nextから抜けるのはExit Forを使用することは以前こちらで教えていただきました。 その場合、このコードでは、For-nextから抜けても、その次のNの値のときに再び条件A1に合致するとB1という処理がされてしまいます。 例えばN=1のとき、A1が成立してB1という処理がされFor-Nextから抜けたとしても、N=2の時も、N=3の時もA1の条件が成立したときにB1の処理がされます。 私が行いたい処理では、一度A1の条件が成立してB1の処理がされたときには、次のNの値からは 「If 条件A1 Then B1」の部分を無視したいのです。 わかりにくくて申し訳ありませんが、このコードの構成でそのようなことが可能かどうか、ご教示いただければうれしいです。

  • Sinogi
  • ベストアンサー率27% (72/260)
回答No.1

ループ構文の途中で抜けるには Exit~を使用します。 For~Next から抜けるには Exit For Do~Loopから抜けるには Exit Do どこで抜けるのが良いかは自分で判断してください。

blackleon
質問者

補足

ご回答ありがとうございました。 2の方に補足を書かせていただきましたので、ご参照いただければ幸いです。

関連するQ&A

専門家に質問してみよう