- ベストアンサー
エクセルマクロについてです
以下のようなマクロで、条件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
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
かなりベタな書き方ですが、一例です。 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」の記述は用いていません。その分行数は増えていますが、理解できたら行数を減らすようにコーディングしていただければよいでしょう
その他の回答 (7)
- Trick--o--
- ベストアンサー率20% (413/2034)
条件が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
お礼
ご回答ありがとうございました。 zap35さんのご回答をヒントにして、まさにTrick--o--さんと同じ方法でマクロを書き直していたところでした。 フラグを切り替えるという方法は、私にとって目から鱗の方法であり、質問をしてよかったと思っています。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 #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 が確保されます。
お礼
いつもご丁寧な回答をありがとうございます。 実際のコードはあまりにごちゃごちゃしていて分かりにくいと思い、簡略化した容で質問させていただきましたが、それが逆にご回答いただく方には分かりにくくなっていたのだと思います。 ご回答の内容は初心者の私には少し難しいのですが、皆さんからいただいたヒントで、自分なりにもう少しやってみます。 駄目な場合は、また新たに具体的な形で質問をさせていただくかもしれませんのでよろしくお願いいたします。
- Sinogi
- ベストアンサー率27% (72/260)
補足内容を理解すると 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 → 処理なし ですか? 私ではしらみつぶしにパターンを記述するしか思いつきません。 良き回答者が現れるといいですね。
お礼
ありがとうございました。 質問が具体的でなく分かりにくかったことをお詫びします。 ご丁寧にご回答いただいたことに感謝いたします。
- Sinogi
- ベストアンサー率27% (72/260)
>私が行いたい処理では、一度A1の条件が成立してB1の処理がされたときには、 >次のNの値からは 「If 条件A1 Then B1」の部分を無視したいのです。 「If 条件A1 Then B1」の部分を無視して 条件A2 以降は評価するのですか? それとも条件文は終了となるのですか? 条件A1 を満たしたか否かの判定子として変数を利用する方法を考えましたが、条件A2 以降の扱いで処理が変わります
補足
条件A2 以降も評価します。 一度成立した条件は無視し、成立していない条件は評価の対象とします。
- imogasi
- ベストアンサー率27% (4737/17069)
こんな条件のかき方では回答できないように思うが。 Nや条件A1-A4がどこを対象(セルなどか)に何を判断しているのか? 相互関連はないのか? 簡単な具体例でも挙げて、質問すべき問題と思う。 些細なことだがCase文が使える稼動かとか。 Exit Forの回答で質問は済みですか。基本的過ぎて。
補足
分かりにくい質問で申し訳ありません。 Nは行を想定しています。 その行において、ある範囲を設定してその内容を最初のセルから一つづつ調べ、一つの行の処理が終わったら次の行に移るという処理です。 条件はすべてセルの数値を対象としており、処理は条件にあった数値を足したり引いたりという単純なものです。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 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
補足
ご回答ありがとうございます。 かなり簡略化してしまったので分かりにくいコードになってしまいました。 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)
ループ構文の途中で抜けるには Exit~を使用します。 For~Next から抜けるには Exit For Do~Loopから抜けるには Exit Do どこで抜けるのが良いかは自分で判断してください。
補足
ご回答ありがとうございました。 2の方に補足を書かせていただきましたので、ご参照いただければ幸いです。
お礼
ご回答ありがとうございました。 理解できるように努めます。
補足
うまくできました。 ありがとうございました。