• ベストアンサー

例外処理の使用方法(VB.NET)

以前、PictureBoxの背景色変更について質問をさせていただいたものです。 (http://okwave.jp/qa3795334.html) その中で、数値を直接テキストボックスに入力し 以下の場合はエラーとして処理をしたいと思っています。 1.テキストボックスが空白の場合 2.0~255の範囲内に無い数字が入力された場合 3.上記2つ以外の全て Try~Catchを利用し、2は Catch ex As ArgumentException とし、3は Catch ex As Exception としたところうまくいきましたが テキストボックスが空白の場合、という処理がどうしてもわかりません。 考えられうる例外クラス名はすべて試したのですが どれもうまくいきませんでした。 上記3つの条件すべてを満たせる例外処理をするには いったいどうすればいいでしょうか?

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

  • ベストアンサー
  • ace456
  • ベストアンサー率36% (37/102)
回答No.3

こんばんは > この部分は、Catchを使わずに、普通に書けばいいのでしょうか。 はい。Catchの中ではありません。 Tryの中でもいいですし、Tryの前に出してやっても構いません。 Tryの中であれば、その2つのコードで「我々もまだ予想してないようなエラー」が起きた時に catchでそれを拾ってメッセージを表示したりすることが出来ます。 > 背景色を変える部分を > PictureBox1.BackColor = Color.FromArgb(TextBox1.Text, TextBox2.Text, TextBox3.Text) > としていますが、Tryを使わずに、上記の文をいれると > Try~Catchにいれてしまうと反応がなくなってしまいます。 > 上記の部分は、どこに書けばいいでしょうか? 上記の文・上記の部分というのは、 「PictureBox1.BackColor = Color.FromArgb(TextBox1.Text, TextBox2.Text, TextBox3.Text)」 のことですよね? 以下は、その前提で書かせて頂きます。 Try~Catchの中で構いません。 反応がなくなったように見えるのは、 > Color.FromArgb(TextBox1.Text, TextBox2.Text, TextBox3.Text) ↑が、構文として誤っているからです。 それが例外として認識され、Catchに飛ばされ、そこで何も処理を行っていない為 (エラーメッセージなどを出していない為)反応がないように見えています。 Try~Catchの外に出すと、それを拾わない為、構文エラーとしてプログラムがずっこけます。 では、根本的な対処はなんでしょう? それは、その構文の誤りを正すことです。 まず第一に、メソッドの引数の型の誤りを修正しましょう。 FromArgbメソッドの引数は、Integer型(整数型)でなければいけません。 なので、文字列型であるTextBox1.TextなどをInteger型に変換してあげましょう。 例えばこうなります ↓ Color.FromArgb(CType(TextBox1.Text, integer), CType(TextBox2.Text, integer), CType(TextBox3.Text, integer)) ※何故、整数型じゃないといけないのかと言われると困るのですが、マイクロソフトがそう作りました。  深く考えないで下さい。一応参考URLをのっけておきます。 ここまで来れば、 > たとえば、「文字列""から型'Integer'へのキャストが有効ではありません」とエラーになってしまいます。 何故こういう風に怒られたか、解るのではないでしょうか。 2段構えで怒られています。 1.Integer型(整数型)で渡さなければならないところを、String型(文字列型)で渡そうとしているから 2. 例え数値に変換されるように作ってあっても、空白("")を数値に変換することができないから だからです。 1.については、 Color.FromArgb(CType(TextBox1.Text, integer), CType(TextBox2.Text, integer), CType(TextBox3.Text)) の記述で解消できます。 2.については、上記の背景色設定処理を実行するより前に、空白のチェックエラー処理を行えば解消できます。 >if textbox.text <> "" then >  --チェックエラー処理 >endif ↑こいつのことです。このチェックエラー処理で「exit sub」などしていれば、 テキストボックスが空白の時は背景色設定のところまでたどりつきませんよね。 チェックエラー処理では、「exit sub」するだけでなく、 なんかメッセージを表示したほうがわかりやすいかも知れません。 いかがでしょうか。 プログラムに慣れてくると、多分私が書いたコードなどは見づらくて 「もっと読みやすく書けないか」「もっと楽できないか」と欲が出てくると思います。 そういう思いが出てきたらしめたもんなので、頑張ってみて下さい。 PS. すいません。前回書いた「例外処理は云々」というのはあまり気にしないで下さい。   ご質問者の方が前回されていた質問の内容を全く見ていなかったので、   練度などを全く考慮していませんでした。   まずは色々作ってみて、あーでもないこーでもない とやってみるくらいの気構えで良いと思います。

参考URL:
http://msdn2.microsoft.com/ja-jp/library/system.drawing.color.fromargb(VS.80).aspx
laybial
質問者

お礼

返信が遅くなって申し訳ないです。 丁寧な解説のおかげでなんとか作成できました。 ありがとうございました。

その他の回答 (2)

  • ace456
  • ベストアンサー率36% (37/102)
回答No.2

こんばんは 1.については if textbox.text <> "" then   --チェックエラー処理 end if 2.については if Ctype(textbox.text, integer) < 0 or Ctype(textbox.text, integer) > 255 then   --チェックエラー処理 end if 3.については そのままでOK です。 ANo.1の方も書かれてる通り、 例外処理(Try Catch~)は、文字通り「想定できないエラー」を拾う為の物です。 仕様書に書かれている入力値チェック処理、プログラマが容易に想像つく入力値チェック処理などは、 全て上記のように明示的にチェック・エラー処理を書くべきです。 3は「それ以外」とありますが、 それ以外の中にあらかじめわかっているようなエラーケースがあるなら それもチェック処理として1,2のように書いといたほうが良いです。 ご参考になれば。

laybial
質問者

補足

ありがとうございます。 例外処理について、思い違いをしていたようです。 >if textbox.text <> "" then >  --チェックエラー処理 >endif >if Ctype(textbox.text, integer) < 0 or Ctype(textbox.text, integer) > 255 then >  --チェックエラー処理 >end if この部分は、Catchを使わずに、普通に書けばいいのでしょうか。 背景色を変える部分を PictureBox1.BackColor = Color.FromArgb(TextBox1.Text, TextBox2.Text, TextBox3.Text) としていますが、Tryを使わずに、上記の文をいれると たとえば、「文字列""から型'Integer'へのキャストが有効ではありません」とエラーになってしまいます。 Try~Catchにいれてしまうと反応がなくなってしまいます。 上記の部分は、どこに書けばいいでしょうか?

  • popesyu
  • ベストアンサー率36% (1782/4883)
回答No.1

想定がつくエラーはTry以外の部分で拾って、予想もつかないエラーをTryで拾うようにすれば? Catchで何も指定しなければよいです。 1は例えば if textbox.value <> "" then exit sub とでもやれば拾えるし。 どんなエラーも何でもかんでもTryで拾わせようとすると、バグの温床になる。後でコードを読み返した時、どんなエラーが発生したらどうなるのかというのがパッと見で理解できない。上に書いたようなコードがあれば、空っぽの時はここで処理を抜けるんだなとすぐに分かる。 あるいはそもそもは当初の質問でも回答されているように、textbox向きな処理じゃない。NumericUpDownやスクロールバーでやる方がむいている。こちらだと最大値と最小値が簡単に設定できるので、1と2のような例外処理を考える必要がないし、3も必要なくなる。textboxで無理やりやろうとするから不自然で歪なコードになる。 包丁で行う方が向いているのにハサミしか使ったことが無いからハサミで無理やりやると。その為包丁でやるよりも高度なことが要求されてしまっていることに気付いていない。

laybial
質問者

補足

ありがとうございます。 1.2の条件の時はIfで拾うことも考えて試してみたのですが そちらでやってもエラーが出ます。 (文字列からInteger型へ変換できない等) >if textbox.value <> "" then exit sub これを書くと、ValueはTextBoxのメンバではありません、とエラーになりました。 最初の質問で提案していただいたNumericUpDownを使うほうが良い と私も思っていますが、こちらの判断では変更することができない状況です。 申し訳ありません。

関連するQ&A