型変換について

タグの編集
投稿者 リスナー  (学生) 投稿日時 2009/1/6 03:13:33
皆さんこんばんは。

フォームが三枚あって、
それぞれにテキストボックスが一個ずつ、
配置されています。


一個目のテキストボックスには売上を、
二個目のテキストボックスには経費を、
三個目のテキストボックスには差額を、

こういった流れです。



>>'フォームの初期化イベント
        'フォームが開いた時点でテキストボックスに計算結果が表示されているという動作。

        '変数の宣言
        Dim Uriage As Decimal '売上を変数宣言
        Dim Keihi As Decimal '経費を変数宣言

        '変数への代入

        '変数Uriageにフォーム1枚目のテキストボックスを代入します。
        Uriage = CDec(Form1.TextBox1.Text)

        '変数Keihiにフォーム2枚目のテキストボックスを代入します。
        Keihi = CDec(Form2.TextBox1.Text)

                '売上から経費を差し引く計算式
        '「差額」を変数宣言しないで3枚目のテキストボックスに単純に計算結果を入れる。
        Me.Textbox1.Text = CStr(Uriage - Keihi)


こう書いたのですが、
実はこれはやむなくそうしたのであって、
最初は差額についても、Sagakuで変数宣言しました。


ところが変数Sagakuに三枚目のフォーム上の
テキストボックスを代入したことろで、
エラーになってしまいます。


私としては、売上や経費と同じように、
デシマルへと変換したのですが、
ストリングからデシマルへの変換が無効とされました。




Dim Sagaku As Decimal'差額を変数宣言

Sagaku=CDec(Me.Textbox1.Text)'差額にこのフォームのテキストボックスを代入する。


'売上から経費を引いて差額を計算する。

Sagaku=Uriage-Keihi


こうしたいのですが、ストリングからデシマルへの変換が無効にされます。

しかし売上と経費のステップではストリングからデシマルへの変換は有効にされています。
どうして差額を変数宣言した場合だけキャストが無効にされるのでしょう。















投稿者 るしぇ  (社会人) 投稿日時 2009/1/6 03:30:33
>ストリングからデシマルへの変換が無効とされました。
このエラーメッセージを正確に記述すると、
『String "" から型 'Decimal' への変換は無効です。』
では無いでしょうか?
TextBox1.Text に "aaa" を入力しておくと
『String "aaa" から型 'Decimal' への変換は無効です。』
つまり、数字に変換しようがない文字列を変換していると
思われます。

これは Textbox のデータを型変換しているコードに
ブレークポイントを設定して、その時の Text に何が
入っているか確認すれば分かることです。

もし、Textbox に数値に変換できる文字列を指定したと
思っているなら、インスタンスの管理ができていないのかも
しれません。
       Form1.Show()
       Uriage = CDec(Form1.TextBox1.Text)

       Form2.Show()
       Keihi = CDec(Form2.TextBox1.Text)

のように使用しているフォームを直前に Show する
テストコードを入れてみてください。同じフォームが
複数表示されるようなら、どこかで New していると
考えられます。New しないようにしてください。

[参考過去ログ]
http://rucio.groupsite.jp/commu/ThreadDetail.aspx?ThreadId=16
投稿者 リスナー  (学生) 投稿日時 2009/1/6 08:01:05
どうも皆さんこんばんは。


>>このエラーメッセージを正確に記述すると、
『String "" から型 'Decimal' への変換は無効です。』
では無いでしょうか?


はい、ご推察のとおりのエラーメッセージが表示されていました。


>>ブレークポイントを設定して、その時の Text に何が
入っているか確認すれば分かることです。

デバッグについては不勉強で、
正直まだ補助ウィンドウのどの部分を見ればよいのか、
分からないようなレベルです。

自動変数やローカル、ウォッチなど色々あるのですね。
ちょっと追いつくのに時間がかかりそうです。


>>もし、Textbox に数値に変換できる文字列を指定したと
>>思っているなら、

まだなんとも言えない段階なのですが、
同じ要領で他の項目が変換されているのに、
それらと並んでいる1つの項目だけが変換無効という状況に、
どうもピンと来ないといった感じです。


>>もし、Textbox に数値に変換できる文字列を指定したと
思っているなら、インスタンスの管理ができていないのかも
しれません。


Newキーワードは使わず、
自分の習熟度からしても、
インスタンスについても考えに入れていなかったので、

でも、Newキーワードを使っていなくても、
インスタンスとかって問題になって来るのでしょうか。


ちなみにロードイベントに記述しました。
フォームの表示と同時に、
そこに計算結果が出ているの望んでいたので。


インスタンスについては理解していないので、
せっかく提示してくださったコードの本当の意味も
よく分かっていないと思うのですが、
誤解はあるかもしれませんが、
自分なりの理解で試してみます。


とりあえずエラーのコードはコメント化しておきました。
差額を変数化せずに、
テキストボックスに計算結果を
ダイレクトに入れるという応急処置で間に合わせていますが。

前の二つの項目が順当に変換されただけに、
自分でも思いもしなかったエラーでして、
まだ時間を要するかもしれません。









投稿者 かずき  (社会人) 投稿日時 2009/1/6 15:48:40
Dim Sagaku As Decimal'差額を変数宣言 
Sagaku=CDec(Me.Textbox1.Text)'差額にこのフォームのテキストボックスを代入する。 


'売上から経費を引いて差額を計算する。 
Sagaku=Uriage-Keihi

このようなコードを書かれてるようですが
2行目は、コメントで書かれてる意図とは違うものです。

差額変数(Decimal型)に、Textbox1に入力されている文字列をDecimal型に変換して代入するです。

エラーを無くすだけなら、Textbox1のTextプロパティにデザイナから0あたりを入れておけば消えると思います。
(動き的に意図したものにはなりませんが)
何故ならないかは、少し考えてみるといいかもしれないです。
投稿者   (社会人) 投稿日時 2009/1/6 17:13:24
こんにちは。

>>このエラーメッセージを正確に記述すると、
>>『String "" から型 'Decimal' への変換は無効です。』
>>では無いでしょうか?
>はい、ご推察のとおりのエラーメッセージが表示されていました。
コードのどの部分でこのエラーが発生するのでしょう?

Sagaku = CDec(Me.Textbox1.Text)

↑の部分ですか?
そうだとしたら恐らくTextBox1に計算結果が
セットされていないのではないでしょうか?

計算結果の数値を一度String型に変換してTextBox1に表示したら
Decimal型に戻せなくなった。というのは考えにくいと思います。

間違いなくTextBox1には計算結果がセットされていますか?
変換するときにTextBox1のTextに何がセットされているか教えてください。

ローカルウインドウ等の見方が分からなければ、
MessageBox.Show(Me.Textbox1.Text)

↑のコードを変換前に実行すれば一応値を知ることはできます。
でも、ローカルウインドウの見方は覚えたほうがいいとは思いますが。
投稿者 るしぇ  (社会人) 投稿日時 2009/1/6 20:22:45
> デバッグについては不勉強で、
ヘルプに書いてありますし、基礎の基礎に限定すれば、30分で覚えられる
程度の内容でしかありません。
[チュートリアル : Windows フォームのデバッグ]
http://msdn.microsoft.com/ja-jp/library/kya29xtx(VS.80).aspx

「ブレークポイント」で止め、コード上にマウスカーソルを持っていくか、
右クリックしてショートカットメニューから「クイックウォッチ」でも
一時的に確認できます。

初心者はメッセージボックスが分かり易いのでしょうが、コード画面から
実行フォーム画面へ切り替えてOKボタンを押さないと次の処理が実行
できません。ウォッチ式の追加をすればウィンドウは自動で表示されますし
こちらを覚えた方がいいでしょう。

タイマーの処理など、プログラムを中断するとイベントのタイミングが
変わってしまう場合があります。このような場合は、
  Console.WriteLine(Me.TextBox1.Text)

  Debug.WriteLine(Me.TextBox1.Text)
といったコードを書けば、出力ウィンドウやイミディエイトウィンドウに
出力されます。※VBのバージョンにより動作が異なります。
出力されたログを後から確認することで、プログラムを中断せずに値を
確認することができます。

# VB中学校ではしか解説が無いんですね。
[Visual Basic 中学校 > VB6 テクニック > 14.デバッグの方法]
http://homepage1.nifty.com/rucio/main/technique/teq_14.htm
# 共通の内容も多いです。イミディエイトウィンドウ・ウォッチ式
# ・ブレークポイント。。。この頃から変わってませんね。
# それだけ重要ということです。
投稿者 リスナー  (学生) 投稿日時 2009/1/6 21:08:07
皆さんおはようございます。
たくさんのレスありがとうございます。


本題ですが、
クイックウォッチ
さっそく試してみました。


>>変換するときにTextBox1のTextに何がセットされているか教えてください。


はい。確認したところ、
このTextには値として、


>>"3:差額の表示"


という文章が示されてありました。

実は私にも見覚えがありまして、
これはフォームのテキストプロパティに記述してある文章なのです。
でも、どうしてこれがテキストボックスの値になっているのでしょう。


もしかしたらクイックウォッチの方法が悪かったのでしょうか。
そう思い、今度は、

>>Me.Textbox1.Text

全体を反転させてクイックウォッチしたところ、

>>""


のみが値として検出されました。
Meを除いて、
TextBox1.Textで反転させ
クイックウォッチしたところ、


>>""


同じく値はこのようになっていました。
Textのみを反転させると上記の文章が
値となっています。




投稿者 るしぇ  (社会人) 投稿日時 2009/1/6 22:06:26
> 実は私にも見覚えがありまして、
> これはフォームのテキストプロパティに記述してある文章なのです。
> でも、どうしてこれがテキストボックスの値になっているのでしょう。
こちらでは Text だけをクイックウォッチしても TextBox1 の内容が
表示されます。(VB2008 Professional Edition)

とりあえず、正常に取得できる方法があれば先には進めますので、
値が設定されてないことが分かったのですから、デバッグ用のコードを埋め込んで
原因を調べればいいだけでしょ?

> でも、Newキーワードを使っていなくても、
> インスタンスとかって問題になって来るのでしょうか。
Newキーワードを使っていないなら、VBが裏で用意するデフォルトインスタンス1つ
のみしか使われて無いです。

> ちなみにロードイベントに記述しました。
じゃあ、単純にロード時はまだ計算結果が設定されていないということでは?

'// Form1 
    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
        Form2.TextBox1.Text = "aaa"
        Debug.WriteLine("Set aaa")
        Form2.Show()
        Form2.TextBox1.SelectionLength = 0
    End Sub
'// Form2 
    Private Sub Form2_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
        Debug.WriteLine("Form2_Load")
        Debug.WriteLine(Me.TextBox1.Text)
    End Sub

[出力]
>Set aaa
>Form2_Load
>aaa


普通にプログラム書いていけば何の苦も無く書き込めるようですが?