今、三角関数を計算する電卓を作成しています。
テキストボックスを4つとラベルを4つ配置し、
それぞれが、『底辺』『高さ』『斜辺』『角度』としてあります。
テキストボックス側の『底辺』と『高さ』に数値を入力した時に、
ラベル側の(斜辺)と(角度)に答えを表示させ、
または、『高さ』と『斜辺』に入力をした時には、(底辺)と(角度)を
答えさせる、というような物を作りたいのです。
この場合、『底辺』と『高さ』のテキストボックスに入力があったら、
(斜辺)と(角度)に答えを返し、『底辺』と『斜辺』に入力があったら、
(高さ)と(角度)に答えを返し・・の様に条件分岐すればよいような
気がしたのですか、いまいち if文を使ってもエラーばかり出てしまいます。
こういう場合、どういう構文を作れば良いのでしょうか?
宜しくお願いします。
どんなコードを書いて、どんなエラーが出たのか
それを教えて。
お返事有難う御座います。
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'への変換は無効です。
というエラーです。
宜しくお願いします。
アクアと申します。どうぞ宜しくお願いします。
コードから察すると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
という感じで記述します。
アクアさん、回答ありがとうございます。
>>If txb41.Text And txb42.Text = True Then
>>において
>>txb41.Textとtxb42がどの様な状態である場合を評価したいのでしょうか?
私もここがおかしい・・って感じていたので、大変参考になりました!
ありがとうございます!
型変換でのエラーについては CBool を何となく書き込んでみたら、
エラーが出なくなったのですが・・イマイチ自分で納得出来ていません。
今日、また会社で少し続きを作ってみて、また書き込みをさせてもらいます。
ご指導のほど、宜しくお願いします。
kenta
まず、御存じのこととは思いますが基本となる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だという事になります。
アクアさん、こんにちは。
大変詳しいご説明有難う御座います。
条件分岐について、少し分かった感じがします!
アクアさんのアドバイスを見ながら、コードを書き直してみたら、
出来ました!
(アクアさんの予想している物と僕の作りたい物はきっと同じです)
ちなみにこんなコードなんですが、無駄な部分とか不適当な部分とか
あるでしょうか? お時間があれば、また教えてください。
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
ご自身の構想通りに動作するなら、それは仕様ですので私を含めた誰かが修正すべきことではないと思いますよ。
むしろ、きちんと動くのであれば自信を持って良いと思います。
同様に、あれこれと誰かが改善点や勉強すべき点を指摘するのも変な話だとおもいます。
ただ、ちょっと気になったのですが…
Private Sub cmb41_Click(・・・
にあるcmb41ってもしかしてButtonコントロールですか?
であれば、ComboBoxコントロールならコントロールの名前はどうします?^^;;
私の場合、Buttonコントロールならbtn、ComboBoxコントロールならcmbとプレフィックスを付けて命名します。
ですが、これも個人差で十人十色です。
一般的と思われがちなプレフィックスも他人から見たらよく分からないモノである場合があるので、掲示板などでご質問される場合はButton1とかLabel2とか、配置されたままのコントロール名の方が、回答者側の負担が少なく、より多くの方からの回答が得られると思いますよ。
アクアさん、こんばんわ。
どうも有難うございました。大変勉強になりました。
cmbは確かにボタンの事です。
なるほど、そうですね・・僕もbtnとプレフィックスを付ける癖にします。
一週間前にVBインストールして、初めて完成したソフトなので感激です♪
また何か作ってみようと思います。
分からなかったらまた助けて下さい(^^;
ありがとうございました!
>であれば、ComboBoxコントロールならコントロールの名前はどうします?^^;;
>私の場合、Buttonコントロールならbtn、ComboBoxコントロールならcmbとプレフィックスを付けて命名します。
コマンド ボタンを cmdxxxx とするのはVB6時代のMixroSoft標準ですよ。
ComboBoxについては下記サンプルのとおりです。
チェック ボックス chk chkReadOnly
コンボ ボックス cbo cboEnglish
コマンド ボタン cmd cmdExit
コモン ダイアログ dlg dlgFileOpen
ツイート | ![]() |