[[20170321142527]] 『IFについて』(はる) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『IFについて』(はる)

お世話になります。
VBAの勉強で書籍を使って問題を解いているのですが
腑に落ちない点があり質問させていただきます。
実務に関する質問ではありませんので、
このような質問をさせてもらうことがルール違反でしたら
申し訳ありません。

会員区分と購入金額によって割引率を求める問題があります。

会員の場合
購入金額が5万以上 30%
購入金額が3万以上 20%
購入金額が1万以上 10%

一般の場合
購入金額が5万以上 15%
購入金額が3万以上 10%
購入金額が1万以上 5%

解答例は次のように書いてあります。

Sub waribiki()

    Dim kingaku As Currency
    kingaku = Range("C33").Value
    If Range("D33").Value = "一般" Then
        If kingaku >= 50000 Then
            MsgBox "15%割引です"
        ElseIf kingaku >= 30000 Then
            MsgBox "10%割引です"
        ElseIf kingaku >= 10000 Then
            MsgBox "5%割引です"
        End If
    ElseIf Range("D33").Value = "会員" Then
        If kingaku >= 50000 Then
            MsgBox "30%割引です"
        ElseIf kingaku >= 30000 Then
            MsgBox "20%割引です"
        ElseIf kingaku >= 10000 Then
            MsgBox "10%割引です"
        End If
    End If
End Sub

これは以下のように記述してはいけないのでしょうか?
会員区分が3通りもしくはこれから3通りになるのかもしれないなら
上記のコードがいいように思うのですが、区分が2通りであれば以下のように書いた方がシンプルな気がします。
上記のように記述するメリットを教えていただけますか?
初歩の初歩でお恥ずかしい限りですがよろしくお願いいたします。

Sub waribiki2()

    Dim kingaku As Currency
    kingaku = Range("C33").Value
    If Range("D33").Value = "一般" Then
        If kingaku >= 50000 Then
            MsgBox "15%割引です"
        ElseIf kingaku >= 30000 Then
            MsgBox "10%割引です"
        ElseIf kingaku >= 10000 Then
            MsgBox "5%割引です"
        End If
    Else
        If kingaku >= 50000 Then
            MsgBox "30%割引です"
        ElseIf kingaku >= 30000 Then
            MsgBox "20%割引です"
        ElseIf kingaku >= 10000 Then
            MsgBox "10%割引です"
        End If
    End If
End Sub

< 使用 Excel:Excel2010、使用 OS:Windows7 >


 VBAに限らず、IF関数でも同じことですけど、 
 「想定外のデータをどこまでケアするか」と言う問題でもあります。

 Range("D33").Value には「一般」と「会員」しか入っていないと決めていいのかどうか。

 なので、問題文にどんな状況なのかが、書いてあるかにもよります。

 実務で、よくあるのは「空白」。
 また、そこに数式が入っていると、時には「エラー」になっていることもあります。

 解答案は、とりあえず、「一般」と「会員」については間違いのないレベルに納めたと言えます。

 あくまで「解答例」なので、はるさんが、ミスなんて起きようもないと確信できれば、
 それに従うこともなく、簡略にすることもできます。

 一般論ですが、ユーザーは結構でたらめな事をやりますよ。
 「一般」とするところを「一班」として気づかなかったとか。

(半平太) 2017/03/21(火) 15:16


半平太さん ありがとうございます。

Range("D33")を空白 と Range("D33")を一班
で、実行してみました。

2つのコードの結果の違いに気が付きました。

===

 VBAに限らず、IF関数でも同じことですけど、 
=== 「想定外のデータをどこまでケアするか」と言う問題でもあります。

教えていただいたことを念頭に置いて勉強します。
本当に有難うございました。
(はる) 2017/03/21(火) 16:34


もう見ないかもですが、私だったらこう書くなぁ、という例なぞ。

 Sub test()
    Dim iw As Long

    Select Case Range("C33").Value
    Case Is >= 50000
        iw = 15
    Case Is >= 30000
        iw = 10
    Case Is >= 10000
        iw = 5
    Case Else
        iw = 0
    End Select

    If Range("D33").Value = "会員" Then
        iw = iw * 2
    End If

    MsgBox iw & "%割引です"
 End Sub
(???) 2017/03/22(水) 11:52

select caseを使う方法ですね。
こちらの方がスッキリしていますね。
VLOOKUP関数のイメージですね。
有難うございました。

御礼が遅くなりすみません。

(はる) 2017/03/24(金) 10:12


ご回答いただいた皆様ありがとうございました。

見直していて疑問点がでてきましたので質問させてください。
本当は別件で質問すべきところかもしれませんが・・・

変数kingakuの型をCurrencyではなくintegerにすると
エラーになります。

セルC33に80000と入力してみましたが、なぜintegerではいけないのでしょうか?

それから、
変数はkingakuのみとなっていますが、こういう場合、
変数kubun(セルD33の値を代入)は定義しないものでしょうか?

書籍の解答例についてお尋ねしているのですが、
出版元に尋ねるわけにもいかず、こちらで質問させていただいている次第です。

よろしくお願いします。

(はる) 2017/03/24(金) 10:26


 エラーメッセージで「オーバーフローしました」と出なかったか?
 また、変数の各型の制限はまだ学んでいないだろうか?
 以下はエクセルのヘルプからの引用。

 >整数型 (Integer) の変数は、16 ビット (2 バイト) の変数で、-32,768 〜 32,767 の範囲の値をとります。
 80000は32767を超えているためオーバーフローした。
(ねむねむ) 2017/03/24(金) 10:34

Select文のほうがすっきり見える、というのと、会員は割引が倍なんだ、という事に着目した点がミソですね。
こうすることで、MsgBox を1回しか書かなくて済むので、簡単に見える訳です。
簡単=コーディングが短い=コーディングミスしにくい=バグを作り込みにくい、と、良い事ずくめなのですよ。

あとは、"会員"以外はすべて一般扱いしてます。ミスがあったとしても正しく動作するよう考えておくことを、フェイルセーフと言います。
元のコーディングだと、打ち間違いは割引表示無しになっちゃいますよね。2択にするところまでは気づいたようですが、ミスすると会員扱いにしてしまっては駄目かと。

で、追加の件ですが、Integerというのは16ビット整数なので、32767 が最大値なのですよ。だから80000とかは扱えず、エラーになります。Long型なら32ビット整数なので、もう少し大きくても扱えます。Currency型は、金額用のデータ型であり、更に大きな数でも扱えるのです。
(???) 2017/03/24(金) 10:38


 Integer  -32,768〜32,767
 Long     -2,147,483,648〜2,147,483,647
 Currency -922,337,203,685,477.5808〜922,337,203,685,477.5807

 初めてCurrencyという変数見たけど、通常ならLongで十分そうですね。
(bi) 2017/03/24(金) 10:42

変数にする必要性について追記。

元のコードだと、何度もkingakuを使っていますよね。その度にセルを見る(マクロ内からセルを見るのは、変数を見るより少し時間がかかるのです)より、1回変数に代入しておいて、変数をみるほうが簡単だし速いから。

私の案の場合、金額セルを見るのは1回だけなので、変数代入する意味がないため、省略しました。同じ情報を複数回参照する場合は変数に代入する、というのを基本で考えると良いでしょう。こう考えると、会員区分の情報は元のコードでも1回しか使っていないから変数にしていない、と解釈できます。
(???) 2017/03/24(金) 11:15


ねむねむ 様

・Integer -32,768〜32,767
基本中の基本でした。以前学習しましたが、integerの内容を完全に記憶違いしていました。
よく調べもせずに質問してすみませんでした。ありがとうございました。

bi 様
・Long
確かに!! 国家予算を扱うわけではないのでLongで十分ですね。
ありがとうございました。

??? 様
・変数
いろいろとありがとうございました。
テキストには解答は書いてあっても、その根拠は記載がないので乏しい知識で推察するしかありません。
そのたびに行き詰ってしまいます。

皆様本当にありがとうございました。

(はる) 2017/03/24(金) 12:59


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.