複数テキストボックスでの条件分岐??

解決


kenta  2009-03-11 06:03:06  No: 141657

今、三角関数を計算する電卓を作成しています。
テキストボックスを4つとラベルを4つ配置し、
それぞれが、『底辺』『高さ』『斜辺』『角度』としてあります。
テキストボックス側の『底辺』と『高さ』に数値を入力した時に、
ラベル側の(斜辺)と(角度)に答えを表示させ、
または、『高さ』と『斜辺』に入力をした時には、(底辺)と(角度)を
答えさせる、というような物を作りたいのです。
この場合、『底辺』と『高さ』のテキストボックスに入力があったら、
(斜辺)と(角度)に答えを返し、『底辺』と『斜辺』に入力があったら、
(高さ)と(角度)に答えを返し・・の様に条件分岐すればよいような
気がしたのですか、いまいち  if文を使ってもエラーばかり出てしまいます。
こういう場合、どういう構文を作れば良いのでしょうか?

宜しくお願いします。


めけめけ  2009-03-11 07:07:55  No: 141658

どんなコードを書いて、どんなエラーが出たのか
それを教えて。


kenta  2009-03-11 07:34:05  No: 141659

お返事有難う御座います。

Private Sub cmb41_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb41.Click

        Dim teihen, takasa, syahen, kakudo, kakudo2, kakudo3, kakudo4, radian As Double

        teihen = Val(txb41.Text)
        takasa = Val(txb42.Text)
        syahen = Val(txb43.Text)
        kakudo = Val(txb44.Text)

        kakudo2 = Math.Atan(takasa / teihen)
        kakudo3 = Math.Asin(takasa / syahen)
        kakudo4 = Math.Acos(teihen / syahen)
        radian = 180 / Math.PI

        If txb41.Text And txb42.Text = True Then
            lbl47.Text = Math.Sqrt(teihen ^ 2 + takasa ^ 2)
            lbl48.Text = kakudo2 * radian
        ElseIf txb42.Text And txb43.Text = True Then
            lbl45.Text = Math.Sqrt(syahen ^ 2 - takasa ^ 2)
            lbl48.Text = kakudo3 * radian

        Else

        End If

という様なコードを書いています。
Elseifでまだ続けたいのですが、一回目の回答は出るのですが、
二回目でエラーになります。

String""から型'Boolean'への変換は無効です。
というエラーです。

宜しくお願いします。


アクア  URL  2009-03-11 10:19:29  No: 141660

アクアと申します。どうぞ宜しくお願いします。

コードから察するとIf文による条件分岐がエラーの原因ではなくて、型変換に失敗している事がエラーの原因のようですね。

ただ…
お示しになられているコードにあるIf文では何を評価したいのか分かりません。
If txb41.Text And txb42.Text = True Then
において
txb41.Textとtxb42がどの様な状態である場合を評価したいのでしょうか?

If文でTrueである場合に…と、評価したい内容は例えばそれぞれのTextBoxコントロールに何らかの文字が入力されている場合でしょうか?
それとも別の何らかの状態でしょうか?

想像ですが、txb41.Textとtxb42.Textに1文字以上の文字列が入力されれている場合を評価したい場合、
If txb41.TextLength > 0 And txt42.TextLength > 0 = True Then
となります。
また、txb41とtxb42に入力された数値が0以上の値である事を評価したい場合には
If teihen > 0 And takasa > 0 = True Then
という感じで記述します。


kanta  2009-03-11 16:04:07  No: 141661

アクアさん、回答ありがとうございます。

>>If txb41.Text And txb42.Text = True Then
>>において
>>txb41.Textとtxb42がどの様な状態である場合を評価したいのでしょうか?
私もここがおかしい・・って感じていたので、大変参考になりました!
ありがとうございます!

型変換でのエラーについては CBool を何となく書き込んでみたら、
エラーが出なくなったのですが・・イマイチ自分で納得出来ていません。

今日、また会社で少し続きを作ってみて、また書き込みをさせてもらいます。

ご指導のほど、宜しくお願いします。

kenta


アクア  URL  2009-03-11 19:47:02  No: 141662

まず、御存じのこととは思いますが基本となるIf文の記述方法について振り返ります。

If [評価する式1] Then
 [命令文1]
ElseIf [評価する式2] Then
 [命令文2]
Else
 [命令文3]
End If

Ifステートメントでは、[評価する式1]がTrueの場合、[命令文1]が実行されます。
[評価する式1]がFalseならば ElseIf 以降の処理が実行されます。
[評価する式2]がTrueならば[命令文2]が実行され、False(それ以外)の場合[命令文3]が実行されます。

一旦おいといて…

ご提示いただいたプログラミングコードでは
> If txb41.Text And txb42.Text = True Then
とありますが、これは
If (txb41.Text And (txb42.Text = True)) Thenと記述した内容とほぼ等価の内容です。
コードデザイナ画面で、txb42.Textに波線が表示されているのはtxb42.TextがString(文字列)型で、Boolean型ではない事が理由です。
CBool(txb42.Text)とすると波線が消えるのは文字列をBoolean型にキャストした事に由来します。
(CBoolの内容については私の方では触れませんのでMSDN等で調べてみる事をお勧めします。)

CBool(txb42.Text)と修正すると今度は、txb41.Textに波線が表示されたと思います。
これも、txb41.TextがBoolean型で評価できない為に表示されているのですが、txb42.Text = Trueの時とは少し内容が異なります。
txb42.Textの時は明示的にtxb42.Text = True と式が記述されていますが、txb41.Textには式が記述されていません。
という事は、txb41.Textには評価式が存在しない事になり、これだけに焦点をあてると
If txb41.Text Then
という記述であると言えます。
最初の方にご説明したように、Ifステートメントでは、
If [評価する式1] Then の結果が正しいか、正しくないか(True or False)で分岐されますので、内部では[評価する式1]はBoolean型で評価されている事になります。
従って、式として成立していないtxb41.TextではBoolean型での評価ができず、波線が表示されてしまう結果となるのです。

以上を踏まえて…
txb41.Textとtxb42.Textがどの様な場合にTrueなのかは kentaさんにしか分からない事なのですが、
私ならテキストボックスに数字が入力されていて、しかも数値に置き換えた値が0以上でなくてはならない。とした場合、
If (CDbl(txb41.Text) > 0 And CDbl(txb42.Text) > 0) Then
と記述すると思います。
そうなると、kentaさんのコードで
> Dim teihen, takasa, syahen, kakudo, kakudo2, kakudo3, kakudo4, radian As Double

>         teihen = Val(txb41.Text)
>         takasa = Val(txb42.Text)
と、txb41.Textの文字列とtxb42.Textの文字列を値に変換してDouble型の変数に代入しているので、その変数を使って、
If (teihen > 0 And takasa >0) Then
としてもOKだという事になります。


kanta  2009-03-11 23:32:30  No: 141663

アクアさん、こんにちは。
大変詳しいご説明有難う御座います。
条件分岐について、少し分かった感じがします!

アクアさんのアドバイスを見ながら、コードを書き直してみたら、
出来ました!
(アクアさんの予想している物と僕の作りたい物はきっと同じです)

ちなみにこんなコードなんですが、無駄な部分とか不適当な部分とか
あるでしょうか? お時間があれば、また教えてください。

Private Sub cmb41_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmb41.Click

        Dim teihen, takasa, syahen, kakudo, kakudo_t, kakudo_s, kakudo_c, radian As Double

        teihen = Val(txb41.Text)
        takasa = Val(txb42.Text)
        syahen = Val(txb43.Text)
        kakudo = Val(txb44.Text)

        kakudo_t = Math.Atan(takasa / teihen)
        kakudo_s = Math.Asin(takasa / syahen)
        kakudo_c = Math.Acos(teihen / syahen)
        radian = 180 / Math.PI

        Try

            If (syahen >= 1 And teihen > syahen) Or (syahen >= 1 And takasa > syahen) Or _
                (syahen >= 1 And teihen = syahen) Or (syahen >= 1 And takasa = syahen) Then

                MsgBox("不正な入力です", 48, "エラー")

            Else

                If teihen > 0 And takasa > 0 Then
                    lbl47.Text = Int(Math.Sqrt(teihen ^ 2 + takasa ^ 2) * 10 + 0.5) / 10
                    lbl47.ForeColor = Color.Crimson
                    lbl48.Text = Int(kakudo_t * radian * 10 + 0.5) / 10 & "°"
                    lbl48.ForeColor = Color.Crimson
                    txb43.Text = lbl47.Text
                    txb44.Text = lbl48.Text

                ElseIf takasa > 0 And syahen > 0 Then
                    lbl45.Text = Int(Math.Sqrt(syahen ^ 2 - takasa ^ 2) * 10 + 0.5) / 10
                    lbl45.ForeColor = Color.Crimson
                    lbl48.Text = Int(kakudo_s * radian * 10 + 0.5) / 10 & "°"
                    lbl48.ForeColor = Color.Crimson
                    txb41.Text = lbl45.Text
                    txb44.Text = lbl48.Text

                ElseIf syahen > 0 And kakudo > 0 Then
                    lbl45.Text = Int(Math.Cos(kakudo / 180 * Math.PI) * syahen * 10 + 0.5) / 10
                    lbl45.ForeColor = Color.Crimson
                    lbl46.Text = Int(Math.Sqrt(syahen ^ 2 - lbl45.Text ^ 2) * 10 + 0.5) / 10
                    lbl46.ForeColor = Color.Crimson
                    txb41.Text = lbl45.Text
                    txb42.Text = lbl46.Text

                ElseIf teihen > 0 And syahen > 0 Then
                    lbl46.Text = Int(Math.Sqrt(syahen ^ 2 - teihen ^ 2) * 10 + 0.5) / 10
                    lbl46.ForeColor = Color.Crimson
                    lbl48.Text = Int(kakudo_c * radian * 10 + 0.5) / 10 & "°"
                    lbl48.ForeColor = Color.Crimson
                    txb42.Text = lbl46.Text
                    txb44.Text = lbl48.Text

                ElseIf teihen > 0 And kakudo > 0 Then
                    lbl46.Text = Int(Math.Tan(kakudo / 180 * Math.PI) * teihen * 10 + 0.5) / 10
                    lbl46.ForeColor = Color.Crimson
                    lbl47.Text = Int(teihen / Math.Cos(kakudo / 180 * Math.PI) * 10 + 0.5) / 10
                    lbl47.ForeColor = Color.Crimson
                    txb42.Text = lbl46.Text
                    txb43.Text = lbl47.Text

                ElseIf takasa > 0 And kakudo > 0 Then
                    lbl45.Text = Int(takasa / Math.Tan(kakudo / 180 * Math.PI) * 10 + 0.5) / 10
                    lbl45.ForeColor = Color.Crimson
                    lbl47.Text = Int(takasa / Math.Sin(kakudo / 180 * Math.PI) * 10 + 0.5) / 10
                    lbl47.ForeColor = Color.Crimson
                    txb41.Text = lbl45.Text
                    txb43.Text = lbl47.Text

                Else
                    MsgBox("値が不足しています", 64, "エラー")

                End If

            End If

        Catch
            MsgBox("予期せぬエラーが発生しました" & Chr(13) & "●●まで連絡を", 48, "エラー")
        End Try

    End Sub


アクア  URL  2009-03-12 02:29:30  No: 141664

ご自身の構想通りに動作するなら、それは仕様ですので私を含めた誰かが修正すべきことではないと思いますよ。
むしろ、きちんと動くのであれば自信を持って良いと思います。
同様に、あれこれと誰かが改善点や勉強すべき点を指摘するのも変な話だとおもいます。

ただ、ちょっと気になったのですが…
Private Sub cmb41_Click(・・・
にあるcmb41ってもしかしてButtonコントロールですか?
であれば、ComboBoxコントロールならコントロールの名前はどうします?^^;;

私の場合、Buttonコントロールならbtn、ComboBoxコントロールならcmbとプレフィックスを付けて命名します。
ですが、これも個人差で十人十色です。
一般的と思われがちなプレフィックスも他人から見たらよく分からないモノである場合があるので、掲示板などでご質問される場合はButton1とかLabel2とか、配置されたままのコントロール名の方が、回答者側の負担が少なく、より多くの方からの回答が得られると思いますよ。


kenta  2009-03-12 06:18:58  No: 141665

アクアさん、こんばんわ。
どうも有難うございました。大変勉強になりました。

cmbは確かにボタンの事です。
なるほど、そうですね・・僕もbtnとプレフィックスを付ける癖にします。

一週間前にVBインストールして、初めて完成したソフトなので感激です♪
また何か作ってみようと思います。
分からなかったらまた助けて下さい(^^;

ありがとうございました!


Sam  2009-03-12 11:19:51  No: 141666

>であれば、ComboBoxコントロールならコントロールの名前はどうします?^^;;

>私の場合、Buttonコントロールならbtn、ComboBoxコントロールならcmbとプレフィックスを付けて命名します。

コマンド ボタンを   cmdxxxx とするのはVB6時代のMixroSoft標準ですよ。
ComboBoxについては下記サンプルのとおりです。

チェック ボックス chk    chkReadOnly
コンボ ボックス   cbo    cboEnglish
コマンド ボタン   cmd    cmdExit
コモン ダイアログ dlg    dlgFileOpen


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加