質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Q&A

3回答

2499閲覧

VBScriptのFor文について

piyotaka

総合スコア39

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

0グッド

1クリップ

投稿2015/07/06 02:59

編集2015/07/06 03:55

再投稿です。
このコードの説明をお願いします。
特にiが演算子に来る理由を知りたいです。

B = Inputbox("式を入力してください。")

Y = Len(B)
i = 0

For i = 0 To Y - 1
A(i) = Mid(B,i+1,1)

z = i + 1
For j = 0 To i - 1
x = CStr(x) + CStr(A(j))

Next

Next

For k = z To Y - 1
X2 = CStr(X2) + CStr(A(k))
Next

ans = CDbl(x) + CDbl(X2)
MsgBox"答えは"&CDbl(ans)&"です",,"答え"
End If

例 B=11+11の場合
まず、for文、Len関数、Mid関数でBの文字(数字だけど文字扱い)を一つの文字にして、配列に入れる。

B = Inputbox("式を入力してください。")

Y = Len(B)
i = 0

For i = 0 To Y - 1
A(i) = Mid(B,i+1,1)

次に、切り取った文字で0から演算子(この場合は+)までを計算

z = i + 1
For j = 0 To i - 1 ※よくわからにのはここ。iが演算子にくるから0~i-1で左側 の計算が成立する部分。(そういう風に説明されました)
そもそもなんで、iが演算子の場所に来るかがわからな い。

x = CStr(x) + CStr(A(j)) これで、文字列を統合し11になる
Next
Next Nextをここに二つ持ってくる意味もわからない

次に左側の計算をする。

For k = z To Y - 1 ※zはi+1をして、演算子の一つ右側になる らしい。
X2 = CStr(X2) + CStr(A(k)) Y-1で右側の計算が成立するのもよくわ からない
右側の文字列も統合
Next

出た答えを数字に直し足し算。
ans = CDbl(x) + CDbl(X2)
MsgBox"答えは"&CDbl(ans)&"です",,"答え"

この場合だと、答えは33になる

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takito

2015/07/06 03:37

前回から拝見していますが、今回も謎が多いです・・・ ・課題の内容 ・このプログラムの入力と出力の例 をもう少し書けませんか? 察するに「 12+45 を入力したら 答えは37です と出力される 」ことを期待してるのかなと思いますが、いかがでしょう? このプログラムの目的が見えなければ、変数の意味も、それがどう処理されることが適切かもわからないので、思った通りのアドバイスは得られないと思います
piyotaka

2015/07/06 03:58

現在は電卓を製作中です。こういうやり方でやりたいのでご教授お願いします。
guest

回答3

0

説明の追加ありがとうございました。だいぶ内容が理解できました。

このコードを見た人たちがみな混乱したように、質問者様も混乱されていることがよくわかりました。
質問者様の指摘は至極まっとうで、疑問を持つ点として正しいです。

ひょっとして、全体はこんな感じじゃないですかね。
これなら理解できそうでしょうか?

lang

1 2Dim B As String 3Dim X As String 4Dim X2 As String 5Dim i As Integer 6Dim Y As Integer 7Dim Z As Integer 8Dim ans As Double 9Dim A() As String 10 11B = InputBox("式を入力してください。") 12 13Y = Len(B) 14 15ReDim A(0 To Y - 1) 16 17For i = 0 To Y - 1 18 A(i) = Mid(B, i + 1, 1) 19 If A(i) = "+" Then 20 Z = i + 1 21 For j = 0 To i - 1 22 X = CStr(X) + CStr(A(j)) 23 Next 24 End If 25Next 26 27For i = Z To Y - 1 28 X2 = CStr(X2) + CStr(A(i)) 29Next 30 31ans = CDbl(X) + CDbl(X2) 32MsgBox B & " の答えは " & ans & " です", , "答え" 33

投稿2015/07/06 05:37

takito

総合スコア3111

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

piyotaka

2015/07/06 05:59

ありがとうとうごあいます! こちらのいいたいことは伝わってます。 しかし、i-1とi+1をするということは、iに演算子がきてるってことですよね? ここがやはりわからないです。 詳しくお願いしたいです。
piyotaka

2015/07/06 06:35

目標は1+1+1をすることなので、iについてわからないとできないので、よろしくお願いします。
takito

2015/07/06 07:00

B = "12+34" を例にします 最初の for で B から1文字づつ取り出します i = 0 の時 A[0] = "1"(1文字目) i = 1 の時 A[1] = "2"(2文字目) i = 2 の時 A[2] = "+"(3文字目) ここで"+"が登場し、式の前部分の値が確定するので "+"を除いた数値部分のみを結合させます i は 2(3文字目) まで進んでいるので -1 することで1文字目と2文字目だけの結合をします 結果はこうなります X = A[0] + A[1] = "1" + "2" = "12" -1 しないとどうなるか?? X = A[0] + A[1] + A[2] = "1" + "2" + "+" = "12+" となるのでよろしくないですね Z の変数は、式の後ろ部分の値を取り出すための位置保存用です i = 2 のままでは "+" の位置なので、+1 することで4文字目から処理を始めさせる狙いがあります Z = i + 1 = 2 + 1 = 3 さらに処理が進んで i = 3 の時 A[3] = "3"(4文字目) i = 4 の時 A[4] = "4"(5文字目) と最後まで進んだら外側の for 文が終わります そして最後の for 文で後ろの数値の結合をします Z = 3 ですから X2 = A[3] + A[4] = "3" + "4" = "34" となります もしも i = 2 のまま Z = i としていたら? Z = 2 X2 = A[2] + A[3] + A[4] = "+" + "3" + "4" = "+34" となるのでこれもよろしくないですね "+"の文字を避けるために、i-1 と i+1 の手当をしてあげているわけですね 以上で理解できそうでしょうか? コードを眺めて頭のなかで考えるだけでなく、この規模のプログラムなら変数と値の変化を紙に書き出して考えてみれば十分に理解できると思います がんばってください
piyotaka

2015/07/06 07:09

ありがとうございます。説明理解しました。ただ「"+"の文字を避けるために、i-1 と i+1 の手当をしている」部分ですが、なぜ、i=演算子なんでしょうか?
piyotaka

2015/07/06 07:10

iは配列であり、他のところにもなりそうなのに、なぜ、i=演算子で固定できるのでしょうか?
piyotaka

2015/07/06 07:14

言い方を変えますと、なぜiは演算子になれるのでしょうか?
takito

2015/07/06 07:21

i は文字をカウントしてますね i が 0 からはじまって 2 までカウントをすすめたとき、"12+34" の 3文字目を指し示しますね 最初から"+"の位置を知っているわけでなく、"+"を探した結果 i = 2 だとわかった それならば、i-1 までの文字を式の前の値、i+1 からの文字を式の後ろの値と認識しよう、という意図がこのコードから感じられます A[], i, Z の変数の変化を紙に書いてみることをおすすめします
swordone

2015/07/06 07:39

「iが演算子」なのではなく,「式の文字列のi番目の文字が演算子」なのです. どうも質問者さんはそこをごっちゃにして混乱している様に見えます.
takito

2015/07/06 07:47

swordone さん、補足ありがとうございました なるほど・・・それならば噛み合わないし、こちらの言っていることも理解できないですね・・・
piyotaka

2015/07/06 07:55

「式の文字列のi番目なのはわかってるのですが、iに演算子は含まれてますが、切り取った他の数値もあります。それなのに、なぜピンポイントでi=+にできるのでしょうか?
oMIDNIGHTSUNo

2015/07/06 08:20

そもそも、iはIntegerだから整数しか入らないですよね? だから、表現としては文字にあたる演算子は絶対的に入らないのでは? iは配列Aに対しての「何番目=i」なのだから、i+1やi-1をする事によって、 配列Aから、任意の値を取得してると思うのですが・・・
coco_bauer

2015/07/06 08:28 編集

プログラムの「If A(i) = "+" Then」の部分は、i番目の文字[A(i)]が加算演算子["+"]であれば、Thenに続く部分を実行するという意味です。だから、Thenに続くプログラムでは、A(i)は"+"であるということにできるのです。  決して、i="+"ではないです。 A(i)="+"です。  こんな例を思い浮かべてください。piyotakaさんが、教室の前から5番目の席に座っているとします。  座席(前から5番目)に座っている人=piyotakoさん という訳ですね。  でも、これを「5=piyotakoさん」と言うと訳が判らなくなりますよね。 A(i) と i は、全く違うものです。これを混同すると訳が判らなくなりますよ。
piyotaka

2015/07/06 14:40

確かにA(i)とiを混同している部分がありました。 しかし、それでもA(i)の演算子が判別できる理由がわからないです。 例、1111+2222 Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) ここまでは、理解してます。 z = i + 1'後ろのやつ For j = 0 To i - 1 '前のやつ x = CStr(x) + CStr(A(j)) Next この場合、Lenは9なので、iは8、そこから1引いて7になりますが、 これだと、「1111+22」になってしまい、おかしいようなのですが、実際起動すると正しい計算ができてしまいます。 その理由を教えて欲しいです。
ozwk

2015/07/06 15:05

if文とfor文の意味をしっかり調べたほうがいいと思います。
takito

2015/07/06 17:49

どうも構文そのものをちゃんと理解されてないように感じます 私の書いた方のコードを見てくださいね # この場合、Lenは9なので、iは8、そこから1引いて7になりますが、 # これだと、「1111+22」になってしまい、おかしいようなのですが 違います For j = 0 To i - 1 これを処理するのは文字列から"+"を見つけたときだけですので iが8になったときは文字の結合処理は行われません 1111+2222 であれば + は5文字目です 5文字目を処理するときのiは4になっていますね そのときの配列Aを見てみましょう A(0) ... 1 A(1) ... 1 A(2) ... 1 A(3) ... 1 A(4) ... + <--- iが4まで進んだ A(5) ... A(6) ... A(7) ... A(8) ... となっています ということは A(0) ... 1 A(1) ... 1 A(2) ... 1 A(3) ... 1 だけを結合したいですよね これを処理するFor文を考えてみましょう この配列の長さは4で、添字範囲は0~3です iには4が入っていますからそれを使えばよいですね For j = 0 To i - 1 jが0からはじまってi-1の範囲まで1ずつ増やしながら処理する つまり jが0から3の範囲まで処理する というFor文です その結果Xには"1111"が入ります "+"の文字の判定による処理は1回しか行われませんので、もう2度と X の内容は変わりません そしてこちら Z = i + 1 これもif文の中に入っているので、やはり"+"の文字が見つかった時だけ処理されます つまりiが4の時だけです 全体のFor文処理が終わった時の配列Aを予想してみましょう For i = 0 To Y - 1 A(i) = Mid(B, i + 1, 1) ・・・ Next A(0) ... 1 A(1) ... 1 A(2) ... 1 A(3) ... 1 A(4) ... + A(5) ... 2 A(6) ... 2 A(7) ... 2 A(8) ... 2 こうなるはずです A(5)から後ろの数字の文字"2222"がはじまります iが4まで進んだとき、"+"の登場により前後の数字の区切りがわかりましたので iの値に1を加えた5を"2222"の開始位置としてZに記憶しておきます iが4まで進んだときの配列Aのイメージに戻ると A(0) ... 1 A(1) ... 1 A(2) ... 1 A(3) ... 1 A(4) ... + <--- iが4まで進んだ A(5) ... <--- "2222"が始まる z に記憶しておく位置 A(6) ... A(7) ... A(8) ... こういうことです このようにしてiがY-1を超える9に達したら処理を抜けて、最後のfor文に進みます For i = Z To Y - 1 X2 = CStr(X2) + CStr(A(i)) Next iがZからはじまってY-1の範囲までiを1ずつ増やしながら処理する つまり、iが5から8の範囲まで処理します Zの値を決めたときに予想した配列Aと一緒にイメージすると A(0) ... 1 A(1) ... 1 A(2) ... 1 A(3) ... 1 A(4) ... + A(5) ... 2 <--- z A(6) ... 2 A(7) ... 2 A(8) ... 2 こんな感じですね A(5)~A(8)を結合するので、X2に"2222"が入ります 以上で X="1111" X2="2222" の完成です いかがでしたか?
swordone

2015/07/07 00:40

そもそも質問者さんのコードでEnd Ifはありますが,Ifはどこに行ったんですか?
piyotaka

2015/07/07 00:41

なるほど。よくわかりました。 確認です。 For j = 0 To i - 1 この場合に If A(i) = "+" Then があるからfor文の回転は+の所で終わるってことですよね? 1111+がiであるって考え方ですよね そこから0~i-1をやることにより、演算子の前の数値を出し、 1111になる 次に一番右は+だから、i+をして+の一つ右の数値に行き、 Y-1をしたところまで、最後まで計算される、ってことですよね?
oMIDNIGHTSUNo

2015/07/07 00:43

takitoさんの解法、すごくわかりやすいです!
piyotaka

2015/07/07 00:55

同じくです。ありがとうございます。
takito

2015/07/07 01:14

piyotaka さん、そんな感じです がんばってください!
piyotaka

2015/07/07 02:13

すみません。 続けて質問よろしいですか? これで、1+1+1をしようと思うのですが、 型が一致しません:CDblとでます。 どこが間違ってるでしょうか? B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then z = i + 0 For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A(i) = Mid(B,KILL+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then S5 = KILL + 1 For S2 = 0 To KILL - 1 S3 = CStr(S3) + CStr(A(S2)) Next End If Next For S6 = S5 To z - 1 S7 = CStr(S7) + CStr(A(S6)) Next S8 = StrReverse(S3) S9 = StrReverse(S7) If InStr(B,"+") Then CDbl(ans) = CDbl(x) + CDbl(S8) + CDbl(S9) MsgBox"答えは"&CDbl(ans)&"です",,"答え" End If
piyotaka

2015/07/07 02:16

おそらく、演算子が混ざってると思われますがいかがでしょうか?
takito

2015/07/07 03:22

ぱっと見、全体のフローがおかしいですね どういう手順で処理しようとしていますか? まずその設計ができていないように思います 1)計算式の最初の数字を1文字ずつ取り出して結合し、Xに入れる 2)計算式をひっくり返し、最後の数字を先頭にする 3)2)で先頭に来た数字を1文字づつ取り出して結合し、S3に入れる 4)1)と3)の処理で演算子の見つかった位置情報を元に、計算式の中間の数字を1文字づつ取り出して結合し、S7に入れる 5)S3とS7は数字が逆になっているので反転させて元にもどす 6)X、S3、S7を足し算して答えを出す 恐らくこういうことをされたいですよね? 1)を見てみましょう ”1+1+1” の式から、Xに入れたいのは先頭の”1”だけなので、最初の"+"が登場するまでを処理します For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then   z = i + 0   For j = 0 To i - 1    x = CStr(x) + CStr(A(j))   Next   End If Next このコードを見てどうですか? 最初の演算子"+"が見つかってXに"1"が入り、その次の"+"まで進んでまたXの処理に入りますね これでは最初にXに入れた数値を壊してしまいますので、何か工夫がいりそうですね そのあとの流れも同様に、処理がどのように進むか、配列Aにはどのように文字が入っていくか、その他の変数の変化もイメージしてみましょう また最後の CDbl(ans) = CDbl(x) + CDbl(S8) + CDbl(S9) これは記述が間違っています CDbl() は、引数を評価してDouble型で返す関数なので代入はできません ans に値を入れたいなら ans = CDbl(x) + CDbl(S8) + CDbl(S9) でよいですね
takito

2015/07/07 03:32

あと、変数の名前の付け方も工夫された方がよいですよ S1,S2・・・S9までS*が登場しますが、数値だったり文字列だったりで混乱します そういうところをきちっとしておかないと、余計な理解に思考を奪われて、解決したい問題に集中できなくなります 例えば、数値を入れるものは n1, n2・・・、文字列を入れるものは s1, s2・・・、というようにルールを決めて整理しましょう
piyotaka

2015/07/07 04:06

流れは上記のフローであっています。 1+1はできるのですが、1+1+1をすると型が合いませんとでます。 最後の+1がおかしいようなのですが、なぜだかわかりますか? B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then z = i + 1 For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next End If Next S1 = StrReverse(B) S10 = StrReverse(Z) For KILL = 0 To Y - 1 A(i) = Mid(S1,KILL+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then S5 = KILL + 1 For S2 = 0 To KILL - 1 S3 = CStr(S3) + CStr(A(S2)) Next End If Next 'ここまで大丈夫 For S6 = S5 To z - 0 S7 = CStr(S7) + CStr(A(S6)) Next S8 = StrReverse(S3) S9 = StrReverse(S7) If InStr(B,"+") Then ans = CDbl(x) + CDbl(S8) + CDbl(S9) MsgBox"答えは"&ans&"です",,"答え" End If
takito

2015/07/07 04:50

>1+1はできるのですが、1+1+1をすると型が合いませんとでます。 > 最後の+1がおかしいようなのですが、なぜだかわかりますか? わかります +が1個ならうまくいくけど、+が2個だとだめなんですよね? フローがおかしい、というのは、+が2個あるときの考慮がないことを言っています もう一度書きます For i = 0 To Y - 1  A(i) = Mid(B,i+1,1)  If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then   z = i + 1   For j = 0 To i - 1    x = CStr(x) + CStr(A(j))   Next  End If Next このfor文の中で、Bの式に+が2個あるとxの中身がどうなるか考えてみてください 最初の+が見つかるところはうまくいきますが、そのまま処理を続けるとまた+が判定されてどうなりますか? 問題はそこにあります また、上の書いていただいたコードをそっくりそのまま実行したところ ”1+1”で答えが3と出ました ”2+2”では答えが6と出ました そちらでは本当にうまくいっていますか?
piyotaka

2015/07/07 05:04

いえこちらも、1+1=3 2+2=6です。 原因がわかりません。
takito

2015/07/07 06:18

原因はわかります +の演算子が1個しか無いのに、2個あるかのように処理してしまうため、本来は入れるべきではないS7の変数に数字が入ってしまっているからです +の演算子が1個のとき +の演算子が2個のとき それらの条件に見合ったプログラムになっていないからです つまり、フローがちゃんと設計できていません どうやってデバッグしていますか? 途中で変数の中身がどうなっているか確認するために MsgBox を使うなどしてみてはいかがですか? たとえば、最後の3つの数字を計算する手前に If InStr(B,"+") Then MsgBox "x=" & x & ", S8=" & S8 & ", S9=" & S9 ' 計算値の表示 ans = CDbl(x) + CDbl(S8) + CDbl(S9) MsgBox"答えは"&ans&"です",,"答え" End If こんな感じで MsgBox を使ったら、どんな値で計算しようとしているかわかると思いますよ
piyotaka

2015/07/07 07:00

演算子が二つだから、計算ができないことは理解しました。for文のところで一つ目の演算子で終わらせられるような命令ってありますか?
takito

2015/07/07 08:53

For を抜けたいなら Exit For と書きます
piyotaka

2015/07/08 02:39

これだと、for文を抜けられて、計算できると思ったんですが、上手くいきません。 なぜでしょうか? B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then z = i + 1 For j = 0 To i - 0 '演算子を一つ目で止める方法 If J = "+" Then Exit For j = j - 1 End If Next x = CStr(x) + CStr(A(j)) End If Next
piyotaka

2015/07/08 02:45

exit forの際に一つ目の演算子をしてする方法ってのはありますか?
piyotaka

2015/07/08 03:20

すみません。指定する方法です。
takito

2015/07/08 03:33

一点、認識のおかしいところがあります > If J = "+" Then j という変数に"+"の文字が入るようなことはありません j はfor文を何回処理するかのカウント用に使われています で、 一回目の+を見つけて、配列Aから先頭数字の結合が終わってから処理を抜けたいのであれば、単にその場所に Exit For を入れてみては? For i = 0 To Y - 1  A(i) = Mid(B,i+1,1)  If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then (1)   z = i + 1 (2)   For j = 0 To i - 1 (3)    x = CStr(x) + CStr(A(j)) (4)   Next (5)  End If (6) Next この中の(1)~(6)でどこですかね? 処理の流れをよく考えましょう どのタイミングに、どの変数にどんな値が入るのか、イメージしてください
piyotaka

2015/07/08 04:04

答えはNextですね。 なんとなくわかったんですが、確信がほしいので説明して頂けるのであれば、お願いします。
piyotaka

2015/07/08 04:10

すみません。5番です。答えは
piyotaka

2015/07/08 05:46

すみません。ご迷惑おかけしてます。 もう一度、質問です。 例えば、1+2+3の場合 答え 一番目 1 二番目 1 三番目 空欄 となり、一番と二番が同じになること、三番の空欄について、ご教授お願いします。 B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next Exit For End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A(i) = Mid(S1,KILL+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For S2 = 0 To KILL - 1 AN1 = CStr(AN1) + CStr(A(S2)) Next Exit For End If Next z = i + 1 S5 = KILL - 1 KO2 = StrReverse(S1) For K1 = 0 To Y - 1 A(i) = Mid(KO2,K1+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For KO = z To S5 + 0 KO1 = CStr(KO1) + CStr(A(KO)) Next End If Next If InStr(B,"+") Then MsgBox "x=" &x& ", AN1=" &AN1& ", KO1=" &KO1 ' 計算値の表示 ans = CDbl(x) + CDbl(AN1) + CDbl(KO1) MsgBox"答えは"&ans&"です",,"答え" End If
takito

2015/07/08 09:12

問題点1 For KILL = 0 To Y - 1 A(i) = Mid(S1,KILL+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then 計算式をリバースして最後の数字を処理する部分 > For KILL = 0 To Y - 1 KILL という変数を使っているのに > A(i) = Mid(S1,KILL+1,1) > If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then A(i) 配列の添字に i を使ってしまってます 問題点2 z = i + 1 S5 = KILL - 1 z は「1個目の演算子の位置の次」ですね ----- 0: 1 1: + 2: 2 <--- z 3: + 4: 3 ----- では、S5 はなんでしょうか? KILL の変数には「式をひっくり返して1個目の演算子の位置」が入っています ----- 0: 3 1: + <--- KILL 2: 2 3: + 4: 1 ----- ということは -1 しまったら "3" の位置に戻ってしまいますので ここは +1 して "2" の位置にしないと意味ある値として使えなさそうですね ----- 0: 3 <--- KILL - 1 1: + <--- KILL 2: 2 <--- KILL + 1 3: + 4: 1 ----- 問題3 z ・・・ 先頭から1個目の+を見つけた次の文字の位置 S5 ・・・ 末尾から1個目の+を見つけた次の文字の位置 という違いに注意が必要です もしも入力した式が "1+222+3" だとしたら ----- 0: 1 1: + 2: 2 <--- z 3: 2 4: 2 <--- S5 5: + 6: 3 ----- となります といことはどうでしょう? 文字列 B について Z から S5 までを取り出せば、中間数字が抜き取れそうではないでしょうか? ループ処理をしてもいいですが、 Mid 関数を使ったら簡単に済みそうです いかがでしょうか
piyotaka

2015/07/09 04:03

ありがとうございます! おかげでほとんど完成に近づきました。 一点だけ、F1の答えに+が付いてしまうのがよくわかりません。 何故だかわかりますか? B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next Exit For End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A(KILL) = Mid(S1,KILL+1,1) If InStr(A(KILL),"+") Or InStr(A(KILL),"-") Or InStr(A(KILL),"*") Or InStr(A(KILL),"/") Then For S2 = 0 To KILL - 1 AN1 = CStr(AN1) + CStr(A(S2)) Next Exit For End If Next z = i + 1 S5 = KILL + 1 KO2 = StrReverse(S1) AN2 = StrReverse(AN1) F1 = Mid(KO2,z,S5) If InStr(A(i),"+") And InStr(A(KILL),"+") Then ans = CDbl(x) + CDbl(F1) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "++" End If If InStr(B,"+") Then MsgBox "x=" &x& ", AN2=" &AN2& ", F1=" &F1 ' 計算値の表示 ans = CDbl(x) + CDbl(AN2) + CDbl(F1) MsgBox"答えは"&ans&"です",,"答え" End If
takito

2015/07/09 04:19

2点あります 1点目 Mid関数の使い方を見直しましょう 指定文字列、先頭から何番目の位置、何文字分 2点目 S5 ・・・ 末尾から1個目の+を見つけた次の文字の位置 ということは、先頭からは何文字目でしょう? 全体の文字数、最初の+の文字の次の位置、2番めの+の文字の手前の位置 3つの数を使ったら、中間の数字が何文字になるか求められそうですね
piyotaka

2015/07/09 05:01

すみません。ギブアップです。 試行錯誤しましたが、+は取れませんでした。 できるのであれば、答えを教えてください。
takito

2015/07/09 07:55

F1 = Mid(KO2, Z + 1, Y - Z - S5) Zに + 1 している理由は、MID関数では文字の数え方が 1 からであり、Z には 0 から数えた中間数字の先頭位置が入っていることから、その差を調整しています MID関数の最後の引数は 文字数 なので、YとZとS5を使って中間数字の字数を求めて与えます 理解できそうでしょうか?
piyotaka

2015/07/10 01:26

なるほど! りかいできました! こういうやり方はありなんですね! さて、申し訳ないのですが、また次の質問です。 下記にあるIfだと、例えば1-1-1が1+1-1として処理される理由がわかりません。 できれば、説明の程、宜しくお願いします B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next Exit For End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A(KILL) = Mid(S1,KILL+1,1) If InStr(A(KILL),"+") Or InStr(A(KILL),"-") Or InStr(A(KILL),"*") Or InStr(A(KILL),"/") Then For S2 = 0 To KILL - 1 AN1 = CStr(AN1) + CStr(A(S2)) Next Exit For End If Next z = i + 1 S5 = KILL + 1 KO2 = StrReverse(S1) AN2 = StrReverse(AN1) F1 = Mid(KO2,z+1,Y-Z-S5) If InStr(A(i),"+") And InStr(A(KILL),"+") Then ans = CDbl(x) + CDbl(F1) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "++" End If If InStr(A(i),"+") And InStr(A(KILL),"-") Then ans = CDbl(x) + CDbl(F1) - CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "+-" End If If InStr(A(i),"+") And InStr(A(KILL),"*") Then ans = CDbl(x) + CDbl(F1) * CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "+*" End If If InStr(A(i),"+") And InStr(A(KILL),"/") Then ans = CDbl(x) + CDbl(F1) / CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "+/" End If If InStr(A(i),"-") And InStr(A(KILL),"-") Then ans = CDbl(x) - CDbl(F1) - CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "--" End If If InStr(A(i),"-") And InStr(A(KILL),"+") Then ans = CDbl(x) - CDbl(F1) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "-+" End If If InStr(A(i),"-") And InStr(A(KILL),"*") Then ans = CDbl(x) - CDbl(F1) * CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "-*" End If If InStr(A(i),"-") And InStr(A(KILL),"/") Then ans = CDbl(x) - CDbl(F1) / CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "-/" End If If InStr(A(i),"*") And InStr(A(KILL),"*") Then ans = CDbl(x) * CDbl(F1) * CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "**" End If If InStr(A(i),"*") And InStr(A(KILL),"+") Then ans = CDbl(x) * CDbl(F1) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "*+" End If If InStr(A(i),"*") And InStr(A(KILL),"-") Then ans = CDbl(x) * CDbl(F1) - CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "*-" End If If InStr(A(i),"*") And InStr(A(KILL),"/") Then ans = CDbl(x) * CDbl(F1) / CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "*/" End If If InStr(A(i),"/") And InStr(A(KILL),"/") Then ans = CDbl(x) / CDbl(F1) / CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "//" End If If InStr(A(i),"/") And InStr(A(KILL),"+") Then ans = CDbl(x) / CDbl(F1) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "/+" End If If InStr(A(i),"/") And InStr(A(KILL),"-") Then ans = CDbl(x) / CDbl(F1) - CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "/-" End If If InStr(A(i),"/") And InStr(A(KILL),"*") Then ans = CDbl(x) / CDbl(F1) * CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "/*" End If If InStr(B,"+") Then MsgBox "x=" &x& ", AN2=" &AN2& ", F1=" &F1 ' 計算値の表示 ans = CDbl(x) + CDbl(AN2) + CDbl(F1) MsgBox"答えは"&ans&"です",,"答え" End If
piyotaka

2015/07/10 02:15

もう一つ質問です。 元々入力された数値を引いて、変数に入れてから処理をする方法を考えたんですが、 これも上手くいきません。何故でしょうか? B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next Exit For End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A(KILL) = Mid(S1,KILL+1,1) If InStr(A(KILL),"+") Or InStr(A(KILL),"-") Or InStr(A(KILL),"*") Or InStr(A(KILL),"/") Then For S2 = 0 To KILL - 1 AN1 = CStr(AN1) + CStr(A(S2)) Next Exit For End If Next z = i + 1 S5 = KILL + 1 KO2 = StrReverse(S1) AN2 = StrReverse(AN1) 'KO2 = B F1 = CDbl(KO2) - CDbl(x) F2 = CDbl(F1) - CDbl(AN2) For F3 = 0 To Y - 1 A(F3) = Mid(F2,F3+1,1) If InStr(A(F3),"+") Then F6 = F3 + 1 For F4 = 0 To F3 - 1 F5 = CStr(F5) + CStr(F4) Next Exit For End If Next For F7 = F6 To Y - 1 F8 = CStr(F8) + CStr(A(F7)) Next If InStr(B,"+") Then MsgBox "x=" &x& "AN2=" &AN2& "F5=" &F5& "F8=" &F8 ' 計算値の表示 ans = CDbl(x) + CDbl(AN2) + CDbl(F5) + CDbl(F8) MsgBox"答えは"&ans&"です",,"答え" End If
takito

2015/07/10 04:52

>1-1-1が1+1-1として処理される理由 そのパターンならうまくいきそうですけど 問題ある箇所といえば For KILL = 0 To Y - 1 A(KILL) = Mid(S1,KILL+1,1) この部分ですね 最初の処理で配列Aを使っていますが、この処理によって Bの文字列を逆順 で Aの先頭から 代入しています それなのに、最後のIF文で式のパターン振り分けをするときは配列Aには 入力した通りの式の文字が入っている ことを期待してしまっています 案としては、Bの末尾から処理する時はA2など別の配列を準備してはいかがでしょう? > 元々入力された数値を引いて、変数に入れてから処理をする方法 F1 = CDbl(KO2) - CDbl(x) F2 = CDbl(F1) - CDbl(AN2) この2つの式は、F1 と F2 がどんな中身になることを期待していますか? コメントに書かれているように 'KO2 = B ですから つまり CDbl(B) と同じということは、動かなそうですよね・・・ 用意した変数の型、用途、今入っている値が何を意味しているか、もっとよく意識しましょう
piyotaka

2015/07/12 12:19

度々、申し訳ないです。お力添えを頂けると助かります 下記のUKEに上手く代入されない理由を知りたいです。 IF文の中のCUTが上手く行ってないのはわかるんですが、理由がよくわからないです…。 B = Inputbox("式を入力してください。"&vbCr&_ vbCr&_ "※『=』は必要ありません。"&vbCr&_ "掛け算は『*』、割り算は『/』を使用してください。","数式の入力") Y = Len(B) i = 0 For i = 0 To Y - 1 A(i) = Mid(B,i+1,1) If InStr(A(i),"+") Or InStr(A(i),"-") Or InStr(A(i),"*") Or InStr(A(i),"/") Then For j = 0 To i - 1 x = CStr(x) + CStr(A(j)) Next Exit For End If Next S1 = StrReverse(B) For KILL = 0 To Y - 1 A2(KILL) = Mid(S1,KILL+1,1) If InStr(A2(KILL),"+") Or InStr(A2(KILL),"-") Or InStr(A2(KILL),"*") Or InStr(A2(KILL),"/") Then For S2 = 0 To KILL - 1 AN1 = CStr(AN1) + CStr(A2(S2)) Next Exit For End If Next z = i + 1 S5 = KILL + 1 KO2 = StrReverse(S1) AN2 = StrReverse(AN1) 'F1 = Mid(KO2,z+1,Y-Z-S5) CUT = 0 For CUT = z To Y-Z-S5 A3(CUT) = Mid(KO2,z+1,Y-Z-S5) If InStr(A3(CUT),"+") Or InStr(A3(CUT),"-") Or InStr(A3(CUT),"*") Or InStr(A3(CUT),"/") Then CUT2 = CUT + 1 For T1 = z To CUT - 1 UKE = CStr(UKE) + CStr(A3(T1)) Next Exit For End If Next Y2 = Len(A3(CUT)) For T2 = CUT2 To Y2 - 1 UKE2 = CStr(UKE2) + CStr(A4(T2)) Next If (A(i)) = "+" And (A2(KILL)) = "+" And (A3(CUT)) = "+" And (A4(T2)) = "+" Then ans = CDbl(x) + CDbl(UKE) + CDbl(UKE2) + CDbl(AN2) MsgBox "答えは"&ans&"です",,"答え" MsgBox "++" WScript.Quit End If MsgBox "x="&x MsgBox "UKE="&UKE MsgBox "UKE2="&UKE2 MsgBox "AN2="&AN2 MsgBox "F1="&F1 MsgBox "Y2="&Y2 MsgBox "A3(CUT)="&A3(CUT) MsgBox "A3(T1)="&A3(T1) MsgBox "CUT="&CUT MsgBox "KILL="&KILL MsgBox "i="&i MsgBox "T1="&T1
guest

0

コメントの流れから
最終的に演算子2つ以上、加減乗除混合の計算をしたいのだと思います。
その場合、演算子の優先順位も考慮しなくてはならず(1 + 2*3 = 7のような)、
ちゃんとした計算結果を返すアルゴリズムを考えるのは常人にはつらいです。

で、世の中には電卓ソフトがあるので、
わざわざ自分で考えなくても当然そういうアルゴリズムがあります。
たいてい普通の数式(中置記法)を「逆ポーランド記法」に変換して計算しているはずです。
中置記法から逆ポーランド記法への変換は「操車場アルゴリズム」というものが有ります。

というわけで、最終的には
1.入力を受け取り、
2.処理しやすいように逆ポーランド記法に変換し、
3.変換結果を元に計算し、
4.計算結果を表示する。
となると思います。

これの実現には、
1.逆ポーランド記法に変換するプログラムを作る
2.逆ポーランド記法を受け取って計算するプログラムを作る
3.2つを合わせる
という段階を踏むといいと思います。

(まあ自分で組まなくてもvbsならEval関数で計算したい文字列を突っ込めば計算結果を返してくれますが)

投稿2015/07/07 03:07

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

動かない(文法エラーの)コードを載せて、意味を説明して欲しいと言われても無理です。
動くコードを、入力データ例と伴に載せてください。

あと、

特にiが演算子に来る

といいうのは何のことを指していますか?iは演算子じゃないのですが。

投稿2015/07/06 03:35

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問