代数を使った条件分岐の方法

このQ&Aのポイント
  • if文を使った条件分岐をする際に、共通部分のある条件文を代数を使ってまとめる方法について考えています。条件C1において、Note_on_cかつMOD(I1,1)が0の場合は、F1に6を足した値を最大値124で制限します。また、Note_on_cかつMOD(I1,1)が0.25の場合は、F1から5を引いた値を最小値60で制限します。それ以外の場合は、F1の値をそのまま使用します。現在は入れ子のif文で書いていますが、もっとスマートな方法があれば教えてください。
  • 条件分岐で共通部分のある条件文をまとめる方法について悩んでいます。条件C1において、Note_on_cかつMOD(I1,1)が0の場合は、F1に6を足した値を最大値124で制限します。Note_on_cかつMOD(I1,1)が0.25の場合は、F1から5を引いた値を最小値60で制限します。それ以外の場合は、F1の値をそのまま使用します。現在は入れ子のif文で書いていますが、もっと効率的な方法があれば知りたいです。
  • if文の条件分岐で共通部分が多いため、代数を使ってまとめたいと考えています。条件C1において、Note_on_cかつMOD(I1,1)が0の場合は、F1に6を足した値を最大値124で制限します。また、Note_on_cかつMOD(I1,1)が0.25の場合は、F1から5を引いた値を最小値60で制限します。それ以外の場合は、F1の値をそのまま使用します。現在はif文を入れ子にして書いていますが、よりスマートな方法があれば教えてください。
回答を見る
  • ベストアンサー

if文における代数の設定方法

if文を使った条件分岐をさせているんですが、条件の共通部分が多いため、代数か何かを設定してまとめられないかなと考えています。 何度も同じ条件文を書いていると、カッコが多すぎてどこがどこにかかっているのか全くわからなくなります。 代数でなくてもよいのですが、とにかく上手くまとめたいと思っています。 今作っているのは 条件C1=Note_on_c"かつMOD(I1,1)=0) 真なら(MIN(124,F1+6) 偽なら  条件C1=Note_on_c"かつMOD(I1,1)=0.5)  真なら(MAX(60,F1-5))  偽なら   条件C1=Note_on_c"かつMOD(I1,1)=0.25)    真なら(MIN(120,F1+6)    偽なら    条件C1=Note_on_c"かつMOD(I1,1)=0.75)     真なら(MAX(90,F1-5))     偽ならF1 というもので以下のように書いてみたのですが(まだ途中です) =IF((C1=" Note_on_c")*AND(MOD(I1,1)=0),(MIN(124,F1+6)),IF((C1=" Note_on_c")*AND(MOD(I1,1)=0.25),(MAX(60,F1-5)),F1)) とこのように、IF((C1=" Note_on_c")までは全て一緒なのですが、条件文に共通部分があっても入れ子にするしかないのでしょうか。 もっとスマートな方法があったら教えて下さいませ。

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

  • ベストアンサー
回答No.6

補足:論理式とIF文との関係 if a="あ" Then  b=10 elseif a="い" Then  b=20 else  b=0 end if このような if 文はCHOOSE関数と論理式とで書くことで簡略化できます。 =CHOOSE(1+(a="あ")*1 + (a="い")*2, 0,10, 20) 1 + (a="あ")*1 + (a="い")*2 の論理式の値は、 (a="あ")が真ならが、1+1*1=2。偽ならば、1+0*1=1 (a="い")が真ならが、1+1*2=3。偽ならば、1+0*2=1 このことから判るように、上記の論理式の値は、1、2,3のいずれかになります。 if 文のネストを避ける手段として論理式を使うことが可能ですが、先の回答では、論理式の説明を割愛していましたので少し補足しておきます。

tukutukuhosi
質問者

お礼

うーん、これはすごいですね。 Chooseを数式ではなく、真偽値にすることでどんな非常に応用性のある式になってますね。 昨日までif文も知らなかったんですが、皆様のおかげで今日一日で、随分色々なパターンを覚えられました。

その他の回答 (6)

  • MackyNo1
  • ベストアンサー率53% (1521/2850)
回答No.7

>ここがI1ではI5を用いた理由を教えて頂けませんか? 単純に私の入力間違いです。 C1セルが「 Note_on_cで、かつI1セルの値が0.25の倍数なら、CHOOSE関数の値を引っ張ってくるという条件式です。

tukutukuhosi
質問者

お礼

そうですか。ありがとうございます。結局choose式を使わせていただくことになりました。ありがとうございます。

回答No.5

条件&答えを下記記号で書くと a:C1=Note_on_c" b:MOD(I1,1)=0 c:MOD(I1,1)=0.5 d:MOD(I1,1)=0.25 e:MOD(I1,1)=0.75 ア:MIN(124,F1+6) イ:MAX(60,F1-5) ウ:MIN(120,F1+6) エ:MAX(90,F1-5) オ:F1 貴式は IF((a and b),ア,IF((a and c),イ,IF((a and d),ウ,・・・・ これで、a が何回も出るのがスマートじゃないということですね。 これを、IFの位置を変えると下記のようになりスマートになります。 IF(a,IF(b,ア,IF(c,イ,IF(d,ウ,IF(e,エ,オ)))),オ)

tukutukuhosi
質問者

お礼

ああ、こうやって自分で記号化してしまうと楽ですね。 これは盲点でした。ありがとうございます。どこでも使えそうな技ですね。

  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.4

こんばんは! あまり簡潔な式にではないですが・・・ Excel2007以降をお使いだとして =IF(G1="Note_on_c",IFERROR(CHOOSE(MATCH(MOD(I1,1),{0,0.25,0.5,0.75},0),MIN(124,F1+6),MIN(120,F1+6),MAX(60,F1-5),MAX(90,F1-5)),F1),"") こんな感じではどうでしょうか?m(_ _)m

tukutukuhosi
質問者

お礼

IFERRORとchoose関数の合わせ技ですね!シンプルですし、わかりやすいです!ありがとうございます。

  • KURUMITO
  • ベストアンサー率42% (1835/4283)
回答No.3

MOD関数の値によっていろいろと条件が変わりますのでつぎのように作業の列と行を用意して対応するのがよいでしょう。 例えば使用中の表はM列までとして2行目から下方にデータが入力されているとします。 そこで作業のための表ですがN1セルには0、O1セルには0.5、P1セルには0.25、Q1セルには0.75と入力します。 N2セルには =IF(F2="","",MIN(124,F2+6)) O2セルには =IF(F2="","",MAX(60,F2-5)) P2セルには =IF(F2="","",MIN(120,F2+6)) Q2セルには =IF(F2="","",MAX(90,F2-5)) をそれぞれ入力します。 その後にN2セルからQ2セルを選択してそれらの式を下方にドラッグコピーします。 お求めの式は2行目のいずれかのセルに次の式を入力し下方にドラッグコピーすればよいでしょう。 =IF(C2="","",IF(OR(C2<>"Note_on_c",COUNTIF(N$1:Q$1,MOD(I2,1))=0),F2,INDEX(N2:Q2,MATCH(MOD(I2,1),N$1:Q$1,0))))

tukutukuhosi
質問者

お礼

なるほど、これは、一つの列で何とかしようとしないで、作業用の行列を作って、そこから情報をとってくるって感じですんね。参考になります。

回答No.2

<式1> 1+ (C1="Note_on_c" * MOD(I1,1)=0) *2+ (C1="Note_on_c" * MOD(I1,1)=0.25)*3+ (C1="Note_on_c" * MOD(I1,1)=0.5) *4+ (C1="Note_on_c" * MOD(I1,1)=0.75) *5 1--->F1 2--->MIN(124,F1+6) 3--->MIN(120,F1+6) 4--->MAX(60,F1-5) 5--->MAX(90,F1-5) 式1が1ならF1 式1が2ならMIN(124,F1+6) よって、 =CHOOSE(式1,F1,・・・・MAX(90,F1-5)) と書けます。

tukutukuhosi
質問者

お礼

これも直感的で非常にわかりやすいですね。ありがとうございます。

  • MackyNo1
  • ベストアンサー率53% (1521/2850)
回答No.1

例示のように0.25単位で条件分類するなら、CHOOSE関数を使って結果を羅列する、以下のような関数にするのがわかりよいかもしれません。 =IF(AND(C1="Note_on_c",MOD(I5,0.25)=0),CHOOSE(MOD(I1,1)/0.25+1,MIN(124,F1+6),MAX(60,F1-5),MIN(120,F1+6),MAX(90,F1-5)),F1)

tukutukuhosi
質問者

お礼

これは大変、シンプルかつ美しい式ですね!最初は意味がわかなかったんですが、計算してみておおっとなりました笑 追加で質問ですが、 MOD(I5,0.25)=0), ここがI1ではI5を用いた理由を教えて頂けませんか?

関連するQ&A

  • 上限設定をした場合に条件不一致で0を返さない方法

    昨日 「全ての行のうち、C列にNote_on_cを含んでおり、かつI列が整数の行のみを選択し、それぞれの行のF列の数値を一括で加算/原産する方法はありますか?」 という質問をしたところ =f1+5*(c1="Note_on_c")*(mod(i1,1)=0) という数式を教えて頂きました。 http://okwave.jp/qa/q8214355.html このご解答を踏まえた上で、条件一致の場合の上限を125に設定したいと思い =MIN(125,F1+5)*(C1=" Note_on_c")*(MOD(I1,1)=0)*(I1>0) という数式を入れたところ、条件を満たさない場合にf列の数字がそのまま返らずに、0が返ってきました。 条件一致の場合は、f+5か125の小さい方を、条件不一致の場合は0ではなく、f列の数字をそのまま返させるのはどうすればよいでしょうか? ※マクロではなく数式ですとありがたいです。マクロだと以前の状態に戻せなくなってしまうので。

  • if文について

    最近、C言語プログラムから、離れていて、久しぶりにここを覗いたのですが、 こんな質問を見ました。 質問 C言語初心者だが、学習用に良いサイトはないか? 最初の回答の方は、ある初心者用と思われるサイトを、紹介してらっしゃいました。 それに対して、他の回答者の方々は、そのサイトの一分を引用して、コンパイルできないし、間違っていると指摘されました。それは以下のようなものでした。 if(条件式) 文1; else 文2; その代わりに掲載されているのが次のようなものでした。 if(条件)条件が真のときに実行する1文; else 条件が偽のときに実行する1文; 私には、最初の回答がなぜ間違っているのか、何故コンパイルできないのか、判りません。何方か詳しく教えていただければ、嬉しいです。よろしくお願いします。

  • C言語のif文について(初歩の初歩の初歩)

    if(num % 2) とするときnumが2で割り切れ「ない」とき つまり()内が「偽」であるときputsの文が表示されます。 if(num == 0) とするときnumが0のとき つまり()内が「真」であるときputsの文が表示されます。 ()内が非0になるか0になるかというのはわかるのですが 「真」か「偽」かでみると逆になってしまってわかりにくいので 常に if(num != 0) として0じゃ「ない」とき つまり()内が「偽」であるときputsの文を表示させれば 常に()内が「偽」のとき表示されるのでわかりやすいと思ったのですが この先これでやっていくとうまく行かないことが出てきますでしょうか。 簡単なうちに慣れていますべきでしょうか。 それともこのようにやっても問題ないのでしょうか。 皆様はどのようにしているのか教えてください。 よろしくおねがいします。

  • while文と無限ループの違い

    はじめまして。大学でC++を習い始めたばかりの初心者です。 最近while文とwhile文と使った無限ループを知ったのですが、 両者の違いがイマイチわかりません。 私のイメージですと、while文は条件が真である限り何度でも判定し 条件が偽になればループを抜ける。 一方無限ループもif文を使った条件が真にならない限りbreakしない。 while文の偽と判定する部分がif文で真と判定するだけで、同じような気がするのですが… ド素人の考えで恥ずかしいのですが、違いをわかりやすく教えてください。

  • if文の中のif文・・・について

    質問させていただきます。 if文の中のif文の記述の仕方について質問があります。 例えば if ( x > 0 ){ a = b+c; if ( a > 1) d = e+f; ・・・1 if ( a < 1) d = e-f; ・・・2 if ( a = 1 ) d = 1-g; ・・・3 } h = d + i; aが1より大きい場合は、1の処理を、aが1より小さい場合は2の処理を、aが1と同じであった場合、3の処理をして最終的に、h = d + i;の式の d に代入して h を求めたいと思っているのですが、うまくゆきません。 if文の中のif文の記述はどのようにすればよいのでしょうか? よろしければご教示よろしくお願いします。

  •  IF文 教えて下さい。

    例 if (($in{'pre'} ne "0") && ($in{'pre'} ne "-1")) { 不要なoptin valueを 0と-1。必要が1-47。 value="1" から value="47" までを真にしたいのですが 例を簡単にするには [1-47] 1< とかどう書けば良いのでしょう?・・・ -------------------------------------------- if ($in{'nam'} && $in{'tel'} && ($in{'pre'} ne "0") && ($in{'pre'} ne "-1") && $in{'add'}) { 今はこんな感じでやってるのです・・・ 全部揃ったら真って感じです。条件文が毎回長くなってw(≧m≦)w

    • ベストアンサー
    • Perl
  • VC2005においてif文が正しく評価されない

    環境: WindowsXP SP2 VC2005 下記ソースをデバッグしています(F10によるステップ実行)。 if文の直前で変数aの値を-1など、0未満へ変更し、 そのままステップ実行しても、なぜかif文の中に入りません。 本来であれば、-1は0未満であるため、if文の判定は真と判定 されるべきであると思います。 個人的に「a = b - c」の式が悪さをしているのではないかなと 考えています。 なぜこのような現象が起こるのでしょうか? int main(void) { long a = 0; long b = 2; long c = 1; a = b - c; if( a < 0 ){ return 0; } }

  • IF関数の計算式について教えてください

    以下の式の場合、「真の場合」として扱われません。 [条件] セルA1=0.9 セルA2=0.9(=0.6+0.3で入力) [計算式] =IF(A1-A2>=0,"真","偽") 通常の計算であれば「0」となるため、「真」が返るはずなのですが 「偽」が返ってしまいます。 「真」が返る方法ありますか?

  • SUMIFとIFの組み合わせ方

    実際の関数のため、シート参照があり分かりにくくてすみません。 SUMIF関数で合計する「条件と範囲」を変えたい場合の質問です。 最初はSUMIFの中で条件を入力してみたのですが、そもそも以下にあるように真と偽だけでは、偽(それ以外の場合)はすべて計算されてしまうため、IFを用いて先に判断してからとおもったのですが、値が0のままです。 IFとSUMIFの使い方が解るかた教えていただけたら幸いです。 IFとSUMIF以外でも回答あればよろしくおねがいします。 【IFの元、B6もしくはC6に値が入っているなら処理をする、両方に値が入っているか値が入っていないなら空欄】 =IF(AND($B6<>0,$C6=0),"勘定",IF(AND($B6=0,$C6<>0),"項目","")) 【上記IFに対してSUMIFで必要な範囲から合計金額を集計】 =IF(AND($B6<>0,$C6=0),SUMIFS(入力【契約書】!$D:$D,入力【契約書】!$E:$E,$C6,入力【契約書】!$I:$I,D$3,入力【契約書】!$J:$J,D$4),IF(AND($B6=0,$C6<>0),SUMIFS(入力【契約書】!$D:$D,入力【契約書】!$C:$C,$B6,入力【契約書】!$I:$I,D$3,入力【契約書】!$J:$J,D$4),""))

  • while文とif文

    #include <stdio.h> void main() { char str[2][6] = {"hello","lop"}; int i = 0; while(i < 2){ printf("%s\n", str[i++]); } } 上のプログラムの条件判定の部分にif文を つかうとhelloという文字列しか出力されず while文を使うとhelloとlop 二つ出力され ます。上の条件判定のif文にした時ととwhile 文にした時の違いはどこなのでしょうか?? どなたかご教授よろしくお願いしますm(_ _)m

専門家に質問してみよう