プロが教える店舗&オフィスのセキュリティ対策術

たびたび質問をさせていただいてすみません
以下のプログラムをあげます。

Private Sub cmdsktuisi2_Click()
'定数
Const A = 60 '基準となる点
'変数
Dim sugaku As Integer '数学の点
Dim kokugo As Integer '国語の点
'初期値
sugaku = InputBox("数学の点数を入れなさい")
sugaku = Val(sugaku)
kokugo = InputBox("国語の点数を入れなさい")
kokugo = Val("kokugo")
'IF式 数学のテストは合格か?
If sugaku >= A Then
If kokugo >= A Then
MsgBox "追試になりません"
Else
MsgBox "追試です"
End If
Else
MsgBox "追試"
End If

End Sub

メッセージボックスに何もいれないときは、エラーとしてかえすことにします。
こんかいのプログラムを実行すると、何の数値を入れても”追試です”と返します。数学も国語も基準点以上の場合はちゃんと”追試にはなりません”と返したいのですが・・・。

質問者からの補足コメント

  • ありがとうございます!

    >ユーザーにとっては、キャンセルボタンがそこにあるのに、
    それを押すと「実行時エラー」で何故かMicrosoftに叱られる、というのは、
    感覚的に馴染まないような気がします。

    確かにそうですね。

    Variantはなんでも放り込んでいい関数だと認識です。

    >If IsNumeric(sugaku) = False Then
        MsgBox "数値が入力されなかったのでキャンセル"
        Exit Sub
      End If
    このExit Sub は、もうここでプログラムは終了します。の意味なのでしょうか。

    > IsNumeric(kokugo)

    IsNUmeric関数は、値が何も入ってないとき、0に返さず、Falseを返すことになる
    のでしょうね。

    No.6の回答に寄せられた補足コメントです。 補足日時:2015/04/11 06:59

A 回答 (7件)

kokugo = Val("kokugo")



kokugo = Val(kokugo)
    • good
    • 0
この回答へのお礼

ありがとうございます。

あほなこと私してましたね。
””をとってみます。

お礼日時:2015/04/10 05:45

sugaku = InputBox("数学の点数を入れなさい")


InputBoxは文字列を返す関数ですが、sugakuは整数型なので型変換されて数値として代入されます。
なので、次の行の
sugaku = Val(sugaku)
は無意味です。
Valを使いたいなら、
sugaku = Val(InputBox("数学の点数を入れなさい"))
としてください。

kokugo = Val("kokugo")
これは、"kokugo"という文字列を数値変換しようとしているので、変換できずに0を返しています。(エラーにはならないようです)
この行も不要です。
    • good
    • 0
この回答へのお礼

ありがとうございます。

型変換されるのはVBA特有の暗黙のルールとうやつですね。ほかのPGを勉強するときにも役立つように、
sugaku = Val(InputBox("数学の点数を入れなさい"))
としてみようと思います。

お礼日時:2015/04/10 05:51

sugaku,kokugoの値を表示してみてください。


1)入力値が正しく取り込めているか。
2)IF文が正しく判定されているか。
を切り分けると回答にたどり着くと考えます。
    • good
    • 0
この回答へのお礼

ありがとうございます。

なるほど。実際に数字をプログラムに入れてしまうって、動かなければIF文のほうに間違いがあって、動くのならば数値入力のほうに間違いがあるので、切り分けるとどこにミスがあるのか分かりやすいですね。

お礼日時:2015/04/10 06:16

×


sugaku = InputBox("数学の点数を入れなさい")
sugaku = Val(sugaku)
kokugo = InputBox("国語の点数を入れなさい")
kokugo = Val("kokugo")


sugaku = CInt(InputBox("数学の点数を入れなさい"))
kokugo = CInt(InputBox("国語の点数を入れなさい"))

でしょうね。
入力チェックを考えないならば。
Val()を利用したところで、意図した値で処理するかは別問題になるわけですから、Val()を利用する意味がわかりません。
    • good
    • 0
この回答へのお礼

ありがとうございます。

CInt関数「引数を評価して整数型(Integer)に変換し、その値を返します。 引数は -32,768 ~ 32,767 の範囲の整数を指定し、」

なるほど、こういうほうほうがあるのですね。べんきょうになります。

お礼日時:2015/04/10 06:29

VB(A)なんで、


Dim sugaku As Integer '数学の点
Dim kokugo As Integer '国語の点
の宣言がしてあれば、
integer型 = string型となっていても、動くには動きます。
ただし、インプットボックスのダイアログに数値に変換できない値を入れた場合にエラーが発生します。

よって、
sugaku = Val(sugaku)
は意味がありません。

ただし、
kokugo = Val("kokugo")
こちらの行は、、、
””がついているので、"kokugo"という文字列になってしまっていますね。
なんで、
kokugo が0になってしまいます。
この行を削除するか、
kokugo = Val(kokugo)
とすれば、インプットボックスの値がkokugoに入ったままになります。

if文については
別々に判定する場合

sugaku >= A Then
MsgBox "数学は追試になりません"
else
MsgBox "数学は追試です"
end if
 
kokugo >= A Then
MsgBox "国語は追試になりません"
else
MsgBox "国語は追試です"
end if

一緒に判定する場合
and 文を使うべきですが、
If sugaku>= A and kokugo >= A then
MsgBox "追試はありません" 
else
msgbox "追試があります"
end if

andを使わない場合は、
If sugaku>= A
If kokugo >= A then
MsgBox "追試はありません"
else
msgbox "追試があります"
end if
else
msgbox "追試があります"
end if

のような判りづらい形になってしまいます。

アドバイスとしてはやはり、ブレークポイント等を使ってのデバッグのやり方を覚える必要があります。
    • good
    • 0
この回答へのお礼

ありがとうございます。

ブレークポイントを調べました。プログラムをストップさせる場所にチェックをつけて、実行させF8キーで一行ずつ判定していくのですね。

いいことを教えて頂きました。今後使ってみようと思います。ぺこり

お礼日時:2015/04/10 06:35

こんにちは。



https://oshiete.goo.ne.jp/qa/8958867
に継続してお応えします。
(別件で優先すると約束した質問があったのでここに来るのが遅れました)

> メッセージボックスに何もいれないときは、エラーとしてかえすことにします。
ユーザーにとっては、キャンセルボタンがそこにあるのに、
それを押すと「実行時エラー」で何故かMicrosoftに叱られる、というのは、
感覚的に馴染まないような気がします。

それと、いきなりInputBoxの戻り値をValで変換するのでは、
未入力での確定、キャンセルボタン、閉じるボタン、などの操作で、
「零点」と判別することになってしまうのでは?

やはり、
InputBox の戻り値の格納はVariant型がお奨めです。
整数であるかどうかについて触らないのであれば、
Val()関数で型変換(Double型だけど)するほうが無難でしょうね。

合否判定は4通り。

' ' ///

Private Sub cmdsktuisi2_Click()
'定数
Const A = 60 '基準となる点
'変数
Dim sugaku As Variant '数学の点
Dim kokugo As Variant '国語の点

  sugaku = InputBox("数学の点数を入れなさい")
  If IsNumeric(sugaku) = False Then
    MsgBox "数値が入力されなかったのでキャンセル"
    Exit Sub
  End If
  sugaku = Val(sugaku)

  kokugo = InputBox("国語の点数を入れなさい")
  If IsNumeric(kokugo) = False Then
    MsgBox "数値が入力されなかったのでキャンセル"
    Exit Sub
  End If
  kokugo = Val(kokugo)

  'IF式 数学と国語のテストは合格か?
  If sugaku >= A Then
    If kokugo >= A Then
      MsgBox "追試になりません"
    Else
      MsgBox "国語 追試です"
    End If
  Else
    If kokugo >= A Then
      MsgBox "数学 追試です"
    Else
      MsgBox "数学 国語 追試です"
    End If
  End If

End Sub
この回答への補足あり
    • good
    • 0

#6です。

補足コメント拝見しました。

InputBox()関数は、文字列型 (String) の値を返します。
例えば何も入力しないで[OK/キャンセル/閉じる]確定した場合は、
""=[長さ0の文字列]です。

Val()関数は、数値として読めない値について、
数値 0 を返します。
 MsgBox Val("")
 MsgBox Val("abc")
このふたつの例では、どちらも、数値 0 が返ります。
問題は、
 MsgBox Val("0")
本当の意味で"0"を入力した場合と、
上のふたつの文字列値だった場合との
区別を付けるには、
「いきなりInputBoxの戻り値をValで変換するのでは」
無理、ということです。

次に、
文字列値を返すInputBox()関数の戻り値を受ける変数は、
本来は、関数に合わせて文字列型 (String)です。
「InputBox の戻り値の格納はVariant型がお奨めです。」というのは、
第一に●文字列値を格納することが出来る
次に ●格納済の文字列値を数値型に変換して格納し直すことができる。
という理由からです。
(前スレの2番目のマクロでは、
 もう一点●戻り値のデータ型を判別に使える
 という利点も活用しています)

> Variantはなんでも放り込んでいい関数だと認識です。
厳密には"なんでも"ではないのですが、さておき、
様々なデータ型を格納できる、ということは確かです。
ただ、漫然と何でもかんでもVariant型、という使い方は避けるべき、
というより、様々なデータ型を理解した上でVariant型を使うように、
教則本などでは初級での教え方として「Variant型を使うな」という
やり方もあるのです。
Variant型を使った方が好い場面というのは、上記●で示した3点を理由に
Variant型の本質的なメリットを発揮できる場合、です。

何故、InputBox()関数の戻り値を受ける変数が数値型でない方が良いのか、
については、
入力された文字列が、数値として読める文字列値であれば、
VBAが勝手にデータ型を型変換(キャスト)してくれて
無事に格納されるのですが、
Dim sugaku As Integer '数学の点
sugaku = InputBox("数学の点数を入れなさい")
のように書いた時、
何も入力しないで[OK/キャンセル/閉じる]確定した場合、""=[長さ0の文字列]
その他の文字列を入力した場合、例えば、"abc"
これらの数値として読めない文字列値ではキャストが働きませんから、
  実行時エラー '13' :
  型が一致しません。
というエラーに帰結します。
エラートラップを掛ければ、解決できますが、それよりはまだ、
Variant型を使う方が扱い易いのではないでしょうか。

InputBox()関数の戻り値をVariant型で受けた場合は、
IsNumeric()関数で、「数値として読めるかどうか」を判別することができます。
(この部分↑だけなら、String型でも良いのです)
"0"なら、「数値として読める」
""や"abc"なら、「数値として読めない」
という風に篩に掛けることができます。

> >If IsNumeric(sugaku) = False Then
>     MsgBox "数値が入力されなかったのでキャンセル"
>     Exit Sub
>   End If
> このExit Sub は、もうここでプログラムは終了します。の意味なのでしょうか。
はい、""や"abc"なら、数値として読めないから、
Exit Sub して(プロシージャを抜けて)、
Sub cmdsktuisi2_Click の処理を終了します。

> > IsNumeric(kokugo)
> IsNUmeric関数は、値が何も入ってないとき、0に返さず、Falseを返すことになる
> のでしょうね。
はい。まさにその通りです。

余談ですが、
前スレで紹介した、Excelの
InputBox メソッド(Variant型)の場合は、
入力するべきデータ型を予め指定しておくことが出来るので、
コード側で面倒な判別をする必要がありません。
数値を入力するように指定してあるとして、
 未入力では確定[OK]できません。
 [キャンセル/閉じる]の場合は、論理値のFalseを返します。
 それ以外の場合は必ず数値、です。
慣れてきたら、数値入力などにはInputBox()関数より扱い易いので、
いずれ余裕が出てきた頃にでも試してみると役に立つと思います。

補足への返信、以上です。
    • good
    • 0
この回答へのお礼

>「InputBox の戻り値の格納はVariant型がお奨めです。」というのは、
第一に●文字列値を格納することが出来る
次に ●格納済の文字列値を数値型に変換して格納し直すことができる。
という理由からです。
(前スレの2番目のマクロでは、
 もう一点●戻り値のデータ型を判別に使える
 という利点も活用しています)

Variant型を選択した意味がようやくわかりました。ありがとうございました。

お礼日時:2015/04/12 19:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!