- ベストアンサー
VB6イルミネーションプログラムその3
いつもお世話になっています。 テキストボックスに1~255までの数字を入力し、コマンドボタンをクリックしたら、入力した数字を2進数に変換してランプを点灯するというプログラムを考えています。 例えば、テキストボックスに170と入力し、コマンドボタンをクリックしたら以下の様にランプが点灯するプログラムです。 ●○●○●○●○ 10101010 170の2進数 色々と調べ目的とする動きはするのですが、別の方法として値を引数にして2進数に変換した値でランプを点灯する処理を手続き(サブルーチン)として分離するという処理はどのようにすればよいのでしょうか? 現コードは以下です。(未熟ですので、コメントが見苦しくすみません…) Private Sub cmd1_Click() '変数の宣言 Dim Kazu As String Dim Binary(7) As Integer Dim Nishin As Integer Dim Value As String Dim Index As Integer 'テキストボックスへ入力した文字列を数値型に変換し、格納 Nishin = Val(txtKazu.Text) '2進数への変換処理 For Index = 0 To 7 Step 1 'Nishinに入力された数値を2で除算し、8ビット分の余りを繰返し求め格納 Binary(Index) = Nishin Mod 2 'Nishinの除算の商を求め、格納 Nishin = Nishin \ 2 Next Index '各余りを下から順に並べる処理 For Index = 7 To 0 Step -1 '変数Binaryを変数Kazuの型である文字列型へ変換し、連結して格納 Kazu = Kazu & CStr(Binary(Index)) Next Index '2進数の結果をランプコントロールへ反映 CWBtn(0).Value = Mid(Kazu, 8, 1) CWBtn(1).Value = Mid(Kazu, 7, 1) CWBtn(2).Value = Mid(Kazu, 6, 1) CWBtn(3).Value = Mid(Kazu, 5, 1) CWBtn(4).Value = Mid(Kazu, 4, 1) CWBtn(5).Value = Mid(Kazu, 3, 1) CWBtn(6).Value = Mid(Kazu, 2, 1) CWBtn(7).Value = Mid(Kazu, 1, 1) End Sub サブルーチンって??と思い、サイトや参考書を色々と見たのですが、サンプルコードなどを見ても理解出来ませんでした。 未熟で理解が浅いのですが、役割として「離れた箇所の文の並びを実行し、元の場所に制御を戻す」という様な感じですよね…元の場所で実行せず、わざわざ離れた箇所で実行するメリットもピンときません… 宜しくお願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
サブルーチンは私の言葉で簡単に表現しますと、特定の動作をする「小さな部品」です。ただ、 百聞は一見にしかず!! ということで、質問に書いてあるプログラムをサブルーチンにくくり出して見ましょう。まず、2進数の文字列に変換することだけをするプログラムの部品です。この部品にDecToBinaryという名前を仮につけてあげましょう。その部品にはこんなソースを書きます。 Private Function DecToBinary(Byval intValue As Integer) As String DecToBinary = "" Do Until intValue < 2 DecToBinary = CStr(intValue Mod 2) & DecToBinary intValue = Int(intValue / 2) Loop DecToBinary = CStr(intValue) & DecToBinary End Function 負の数は考えていませんが、あしからず。 さて、部品が1個できました。この部品を使うにはCallステートメントを使います。使い方はこうです。 Call DecToBinary(170) 本当はCallは省略できて、「DecToBinary 170」という風に書くこともできます。むしろ省略するほうが有名ですよね。 しかし、この部品はFunctionプロシージャーです。Subプロシージャーと違って部品が動いた結果を部品の名前自身が変数となって教えてくれるのです。この例ですと strResult=DecToBinary(170) という風に書きますと、実行されるとstrResultのなかには"10101010"という文字が入ることになります。DecToBinaryという部品はそういう仕事をする専用に今ここに生まれたわけです。 さて、10進数を2進数に変換できただけではまだ目的の動作は完了できませんよね。ですので、もうちょっと大きな目線で見ましょう。 数字を受け取ると、2進数に変換して、その2進数の値にしたがってランプコントロールのValueプロパティーを変更して初めて仕事が完了するわけですので、その動作を行う部品を作りましょう。この部品には「SwitchLamp」とでも名前をつけてみましょう。すると、SwitchLampという部品のソースはこうなります。 Private Sub SwitchLamp(intValue As Integer) Dim I As Integer, strResult As String strResult = DecToBinary(intValue) '(1) '8桁未満の場合は頭に0が足りないので足りない分だけ0を追加する If Len(strResult) < 8 Then strResult = String(8 - Len(strResult), "0") & strResult For I = 1 To 8 'CWBtnのValueプロパティーはTrueかFalseの指定であると '勝手に解釈しています。違う場合はこの部分を修正してください CWBtn(I - 1).Value = (Mid$(Right$(strResult, I), 1) = 1) Next End Sub (1)の部分が先ほど作った10進数から2進数に変換する部品を呼び出しているところです。似たような動作を何度もするところをこのように小さな部品にしてしまうのです。そして、部品にして、部品にした仕事はその部品に代わりに仕事をしてもらうのです。仕事を部下に丸投げする上司みたいですよね。でもそういう捕らえ方で大丈夫です。 小さいところですが、ランプコントロールのValueを変更する部分もFor~Nextでまとめちゃうと、コードが非常にすっきりしてますよね?これがサブルーチン化のメリットの1個です。いろいろな部品を組み合わせて1個の大きな動作をする機械を作り上げるのです。 最後に、これで目的の動作をする機械は完成しました。しかし、1個まだ問題が残っています。機械はできても、この機械はいつ動けばいいのでしょう? その答えが一番頭にあり、かつこの質問の心臓部ですね。コマンドボタンを押したらこの機械を動かしなさい。そうすることによってこの機械は動作を開始して、目的の動作をこの機械が行ってくれるのです。そのためのコードは下のような感じです Private Sub Command1_Click() Call SwitchLamp(Val(txtKazu.Text)) End Sub この1行だけです。とてもシンプルになりましたよね。日常に例えると「機械のスタートボタンをポンと押した」という感じでしょうか。 よって、コマンドボタンがたくさん増えて40個目が押されたとしても Private Sub Command40_Click() Call SwitchLamp(Val(txtKazu.Text)) End Sub 書くのは同じこの1行だけでいいのです。 最後になりましたが、サブルーチン化はコードが見やすくなり、見やすくなることでバグが発生しにくいプログラムを作ることができるようになります。一番初めの2進数に変換する部分でも「(Byval intValue As Integer)」と書きましたよね?これによって変な文字を入力しようとするとこの部品を呼び出そうとした場所でエラーが起こりますので、バグの原因の発見も早くなるといった小さいけれど侮れない大きなメリットもあるのです。 また、余談ですが、サブルーチンを呼び出してそこへ飛ぶということは、呼び出して終わった後、呼び出された元へ飛んで帰らなければいけません。あまり部品を小さく区切りすぎると逆に処理が遅くなるということも起こります。過ぎたるは及ばざるが如し、程々が一番ですね。 以上、長文失礼いたしました。 個人的なことですが、私もVB使いです。昔は私もaries-0323さんと同じようなことで悩み、同じようなコードを記述していました。aries-0323さんが今後より上達できることを応援します。
その他の回答 (2)
- shut0325
- ベストアンサー率40% (490/1207)
今回書かれているコードもサブルーチンです。 では、新規にボタン2を作ったとして、処理としてはボタン1と同じにしたいときはどうしますか? 同じコードをコピー&ペーストしますか? それも間違いではないですが、「ボタン1をクリックしたときと同じ処理でおねがいします。」が楽ではないですか? 更に発展して、ボタン2の処理はボタン1の処理と1部だけ違うパターンはどうでしょう? ということsubやfunctionを使って状況によって変わる処理が実現できます。
お礼
ご回答有り難う御座います。 仰られる通り、新規にボタンを作ったとして同じ処理にしたい時自分ならどうするかと考えると今の自分のレベルでは最初に思いつく考えはコピー&ペーストにしてしまいます… 同じ処理に出来れば楽ですね。 処理の仕方は沢山あるんですね。 う~ん、奥深いです!!
- ShowMeHow
- ベストアンサー率28% (1424/5027)
具体的なコードはともかくとして、 たとえば、このボタンが信号機で、 40個の信号機を出力デバイスを使いながら、同期を取ってコントロールしなくてはいけなくて、、、 歩行者信号延長などの情報などを入力デバイスで取得しなければいけないとしたら、、、 すべての行為をログに書き出さなければいけないとしたら、、、 ・・・・・ と考えていくとサブルーチンはメリットがあります。
お礼
ご回答有り難う御座います。 なるほど、40個一つ一つにその処理を書くよりもその処理を一つの箇所に決めて用意しておいて、そこへ飛ばして処理を実行させてから元の所へ戻すという感じですね。 サブルーチン、メリットありますね。 わかり易い例え感謝です!
お礼
ご回答有難う御座います。 ご丁寧な解説で大変勉強になります! まだまだ完璧には使いこなせませんが、Randomizeさんに教えていただいたコードを元に他の処理の場合にも「小さな部品」として機能出来るように勉強していきたいと思います! 最後に未熟な私ごときに応援をしていただき、恐縮です… ご期待(?)に添えますように、今後も壁に当たっても精進していきます!!