VBAで中学数学の問題を扱おう! その1 (単項式)×(単項式)の計算(前半)
こんばんは~。
VBAのことをブログに書いてからちょっとだけブログアクセス数が増えました。
ありがたいことです。
意外と需要があるのかな???
さて。
今回から数回にわたって「中学数学の問題を扱おう!」の記事を書きたいと思います。
ひとくちに中学数学といってもいろいろあると思いますが。。
今回はその中でも根幹に来るであろう「計算」について。
特に(単項式)×(単項式)について書きたいと思います。
今回からの記事ではできるだけコードについて説明を書いていこうと思っています。
とりあえずざっくりと単項式について定義して。
その後にいくつかのケースを解決するコードを書いてみようかなと。
- 単項式って?
単項式は掛け算のみからなる式。
ということにしましょう!
- ケース1 2×3
つまりは(数字)×(数字)ですね。
Sub ケース1()
Dim siki(1) As Integer '扱う式を代入
Dim answer As Integer '答え
siki(0) = 2
siki(1) = 3
answer = siki(0) * siki(1)
End Sub
ま。
この処理ができないのに今回のブログを書こうとは思わないですよねw
これで処理できますが。
とりあえずユーザーフォーム仕様にでもしよう。
。。。
Private Sub CB1_Click()
Dim siki(1) As Integer '扱う式を代入
Dim answer As Integer '答え
siki(0) = Val(TB1)
siki(1) = Val(TB2)
answer = siki(0) * siki(1)
TB3 = answer
End Sub
テキストボックスを左からTB1,TB2,TB3
計算と表記されているコマンドボタンをCB1
と定義しています。
コード自体は最初に書いたものとほとんどおんなじです。
せっかく作ったことですし。
以降はユーザーフォームを使っていきましょうか。。
正直ユーザーフォームは初心者だからうまく使えるか不安。。
- ケース2 2a×3
つまりは(文字式)×(数字)ですね。
文字式が入ってくると少しずつ難しくなってきます。。
まずはsikiとanswerをintegerからstringに変更します。
Dim siki(1) As String '扱う式を代入
Dim answer As String '答え
siki(0) = TB1
siki(1) = TB2
ここからはいろいろな処理方法があると思いますが。
僕が取ろうと思っている処理は。
それぞれの式を数字と文字に分ける。
数字同士を処理する。
文字同士を処理する。
です。
新しくmoji(1)とkazu(1)を定義します。
あとtrgtも定義します。これは処理用の仮箱?
Dim trgt As String
Dim kazu(1) As String
Dim moji(1) As String
次にsiki(0)とsiki(1)をkazuとmojiに分けます。
一気に書くとわかりにくいのでとりあえずsiki(0)だけ処理しましょう。
j = 0
For i = 1 To Len(siki(j))
trgt = Mid(siki(j), i, 1)
If trgt Like "[a-z]" Then
moji(j) = moji(j) & trgt
Else
kazu(j) = kazu(j) & trgt
End If
Next
次の処理を簡単に書くためにj=0として書きました。
中身にチラッと触れると。
trgtにsiki(0)の1文字目を入れる。
それがアルファベットだったらmojiに追加。
それ以外だったらkazuに追加。
です。
じつはこの処理にはめちゃくちゃ問題があるのですが。。。
少なくともケース2は処理できるので良しとします。
というか。
いきなり強すぎるコードを載せちゃうとつまらないですよねw
For j = 0 To 1
For i = 1 To Len(siki(j))
trgt = Mid(siki(j), i, 1)
If trgt Like "[a-z]" Then
moji(j) = moji(j) & trgt
Else
kazu(j) = kazu(j) & trgt
End If
Next
Next
これでsiki(0)とsiki(1)に処理を施しました。
次はmojiとkazuを処理します。
answer = Val(kazu(0)) * Val(kazu(1))
answer = answer & moji(0) & moji(1)
ちょっと横着しちゃいました。
とりあえずこれでケース2をクリア。
Private Sub CB1_Click()
Dim siki(1) As String '扱う式を代入
Dim answer As String '答え
siki(0) = TB1
siki(1) = TB2
Dim trgt As String '処理用の箱
Dim kazu(1) As String '数を割り振る
Dim moji(1) As String '文字を割り振る
For j = 0 To 1
For i = 1 To Len(siki(j))
trgt = Mid(siki(j), i, 1)
If trgt Like "[a-z]" Then
moji(j) = moji(j) & trgt
Else
kazu(j) = kazu(j) & trgt
End If
Next
Next
answer = Val(kazu(0)) * Val(kazu(1))
answer = answer & moji(0) & moji(1)
TB3 = answer
End Sub
- ケース3 2b×ac
これは(文字式)×(文字式)
とりあえずケース2のコードで処理してみました。
ん???
いろいろ突っ込みどころがありますねw
まず本筋と違うところで。
画像が見にくいですねw
次から気をつけますw
次は本筋で。
なぜか数が0になっている。
文字の順番がアルファベット順になっていない。
2b×ac=2abc
でないとだめですよね。
逆に言うと上に書いた二つの問題をクリアすればケース3も合格なのですが。
まずは簡単なほうから修正しますか。
なぜか数が0になっていることから。
これは初期値が原因です。
kazuの初期値は""です。
今回はkazu(1)は""のまま。
そのせいでVal(kazu(0)) * Val(kazu(1))の結果が""になってしまいます。
解決策は初期値を変えること。
For i = 0 To 1
If kazu(i) = "" Then
kazu(i) = 1
End If
Next
。。。
うそついちゃいました。
初期値を変えるのはその後の処理が大きく変わってしまいそうなので。
未定義のkazuを1と定義することにしました。
2b×ac=2bac
修正1は完了。
次は文字をアルファベット順に並べます。
この解決策はわれながら頭いいなーと思っちゃいますw
なんちって
sikiの割り振りかたを大幅に変更。
moji(1)をmoji(1,26)と定義します。
26にピンとくるひともいるかな?
そう。アルファベットの数です。
siki(0)について
一文字ずつ処理。
もしも数字だったら今までどおりkazuに入れる。
もしも文字だったら。
aならmoji(0,1)に、cからmoji(0,3)に、xならmoji(0,24)に入れる。
Dim tmp As Integer
For j = 0 To 1
For i = 1 To Len(siki(j))
trgt = Mid(siki(j), i, 1)
If trgt Like "[a-z]" Then
tmp = Asc(trgt) - 96
moji(j, tmp) = moji(j, tmp) & trgt
Else
kazu(j) = kazu(j) & trgt
End If
Next
Next
ローカルウィンドウを見るとこんな感じになります。
この処理方法は。。
Dim pre As String
For i = 1 To 26
pre = pre & moji(0, i) & moji(1, i)
Next
answer = Val(kazu(0)) * Val(kazu(1))
answer = answer & pre
いえーい。
クリア。
もしかするとめちゃくちゃ効率の悪い定義法なのかもしれませんが。
これなら確実に文字をアルファベット順に処理できます。
あー。
ついでにkazuの処理も変更しますか。
kazuという変数を除去してmoji(0,0)とmoji(1,0)に代用させます。
これは表記の問題なのですが変数は少ないほうが何かと楽かなと思います。
こうするとmojiという変数で数字を処理するのも気持ち悪いので。
moji(1,26)をelement(1,26)に変更しましょう。
ケース3を処理するコード。
Private Sub CB1_Click()
Dim siki(1) As String '扱う式を代入
Dim answer As String '答え
siki(0) = TB1
siki(1) = TB2
Dim trgt As String '処理用の箱
Dim tmp As Integer '処理用の箱
Dim element(1, 26) As String '数と文字を割り振る
For j = 0 To 1
For i = 1 To Len(siki(j))
trgt = Mid(siki(j), i, 1)
If trgt Like "[a-z]" Then
tmp = Asc(trgt) - 96
element(j, tmp) = element(j, tmp) & trgt
Else
element(j, 0) = element(j, 0) & trgt
End If
Next
Next
'未定義のkazuを1と定義
For i = 0 To 1
If element(i, 0) = "" Then
element(i, 0) = 1
End If
Next
Dim pre As String
For i = 1 To 26
pre = pre & element(0, i) & element(1, i)
Next
answer = Val(element(0, 0)) * Val(element(1, 0))
answer = answer & pre
TB3 = answer
End Sub
ちょっと疲れてきたので。
今日はここまで。
一気に書くつもりでしたが。。
後半は後日ということで。。