【Excelプログラミング講座】11 未解決バグに挑戦!(その2)
【Excelプログラミング講座】第11回です。 この講座では、エクセル野球シミュレーション「ダイナミックベースボール」のゲームプログラムを材料として、エクセルVBAでのプログラミングを解説していきます。 ▼ダイナミック・ベースボールのページ 過去記事をまとめたサイト↓ ▼エクセルプログラミング講座 前回から、なかなかやっかいなバグの解決に乗り出しています。簡単に言うと、「サヨナラで途中終了すると、成績反映がされずに終わっちまうときもある」というバグです。原因は、なんと設計段階でサヨナラで途中終了する場合のことを想定していなかった!そういうわけで「今更どうやって入れ込むよ」という状態なのですが、強引になんとか解決を図りたいと思います。道筋としては、「打数と安打数のカウントを最初にして、送りバントの場合のみ、例外的にカウントを戻す、というやり方」をとろうとしています。今回は、そのつづき!果たして今まで放置していたバグが解決できるか?前回は「打数」のカウントのみにまず着目しましたね。そこで、今日は「安打数」のカウントについても、そのタイミングを調べておきましょう。安打数をカウントする命令は Call SeisekiB(Range("H6"), 20)でした。Call SeisekiB(Range("H6")までが、打者成績のカウント命令に共通する部分で、その後の数字が「20」なら安打数なのでした。この「20」は目的のセルの列番号を表しているのでした。たとえばヒットを打ったときなら、=========================== MsgBox "うまく打ちました!ヒット!", , "ヒット!" Call 走者判定HIT HitIn Call SeisekiB(Range("H6"), 20)===========================となっています。検索(Ctrl+”F”)で調べましたが、どこも「HitIn」とセットになっていますね。この「HitIn」、怪しいけど、その中身は?「HitIn」のサブルーチンを見てみると、意外にも、非常に短いプログラム。===========================Sub HitIn() If N Mod 2 = 0 Then '表のとき Range("R2") = Range("R2") + 1 Else '裏のとき Range("R3") = Range("R3") + 1 End IfEnd Sub===========================これは、スコアボードの各チームの「累計ヒット数」のカウントをプラスするプログラムですね。今回の成績処理には関係ありません。なあんだ。「サヨナラの処理」があるのは、「ScoreIn」、つまり得点が入ったときのサブルーチン。ずばり、そうでしょう。「ScoreIn」を見てみると、ありました。次のところです。=========================== 'サヨナラの処理 If Range("O3") <> "" And Range("Q3") > Range("Q2") Then Call SeisekiP(Range("O6"), 22) Y = 3 'Y=3でwinningを処理 MIDIstop Winning End End If===========================サヨナラヒットの場合は打数と安打数のカウントがされないということだったので、「だったら、ここにカウントするプログラムを追加するだけで済むんじゃねえの?」と思われる方もいるでしょうが・・・問題は、「ホームランの時はカウントされる」というところ。ある条件だけで発生するバグへの対応なのに、得点処理ScoreInに書いてしまうと、すべての条件でカウントがされてしまい、別ルートをたどってきた条件では二重処理がされてしまうリスクがあります。そんなわけで、面倒がらずにそれぞれのルートを確認します。ホームランの時のサヨナラ処理がたどるルートは・・・たとえば3塁ランナーがいた場合だと、=========================== MsgBox "3塁ランナーホームイン!!", , "ホームラン!" Call SeisekiB(Range("H6"), 16) Call SeisekiP(Range("O6"), 20) ScoreIn=========================== と書いてあります。うん。ちゃんと打者成績処理(打点)が 「ScoreIn」の前に来ています。ここからさかのぼってランナー条件を見る以前に戻ると、ホームランだと表示させたときにすでに=========================== HitIn Call SeisekiB(Range("H6"), 14) Call SeisekiB(Range("H6"), 16) Call SeisekiB(Range("H6"), 20) Call SeisekiP(Range("O6"), 20)=========================== という打者成績処理もしています。SeisekiB(Range("H6"), 16)の打点処理は、ランナーが帰ってくるたびにプラスしているので、この表記で、合っていますね。では、ホームラン以外の場合はどうか。ホームラン以外の場合は、走者がホームインしたかどうかを読み取らないといけません。この分岐は、「Module Runnner」にあります。おや。この場合もホームランのときと同じですね。打者成績処理は、数字が16。16は打点です。なんと。違いは見いだせず!サブルーチン処理に違いがないので、分岐前の「飛球判定」に戻ってきてからの処理を見てみます。ホームランの場合は「ScoreIn」の前に、「 Call SeisekiB(Range("H6"), 20)」(安打数のカウント)が、ありました。ホームラン以外の場合は、「ScoreIn」は「走者判定」に含まれるので、打者成績処理が「走者判定」の前にないといけないのですが・・・たとえば3塁打の場合、=========================== Call 走者判定3B HitIn Call SeisekiB(Range("H6"), 20)=========================== おっと、思いっきり、逆でした。これは単純に順序の入れ替えでいけそうです。「安打数のカウント」については、以下の対応でクリアできると思います。「 Call 走者判定○○」の前に、「Call SeisekiB(Range("H6"), 20)」を持ってくる。場所は「Module1」の「飛球判定」の中です。該当箇所の「Call SeisekiB(Range("H6"), 20)」を切り取り、「 Call 走者判定○○」の前に挿入し、「 Call 走者判定○○」を切り取って「Call SeisekiB(Range("H6"), 20)」が合った場所に移します。切り取りのキーボードショートカットはOKですか?コピーはCtrl+”C”でしたが、切り取りはCtrl+”X”ですね。念のため。キーボードでサクサク修正作業を進められないとまどろっこしくてしょうがないので、自由自在にできるようになっておきましょう。なにしろ同じような修正箇所が多いですから・・・。ちなみに「HitIn」とは順序が前後しても構いませんよね。すでに見たように、「HitIn」はスコアボードのヒット数表示だけに関わるプログラム。そのため、カットペーストを繰り返すのが面倒なら、「 Call 走者判定○○」のみを切り取って、「Call SeisekiB(Range("H6"), 20)」の後に移し替えるだけでもOKです。これで、安打数のカウントに関してはクリアできました。まだ完全にバグ対応が終わっていませんが・・・またまた長くなったので、続きはまた次回!なお、デバッグにおいては、何をどこまで作業したのかを記録しておくことが重要です。今回の場合、修正したファイルの「情報」タブに、以下のような追記をして、まだ途中だという意味を込めて赤字で目立たせておきました。これは自分用のメモですが、修正版を公開したときにもこういったバグ修正情報は必要なので、体裁を整えて情報を残すようにします。↑自分用のメモ。今はまだ僕の自宅PCのファイルでしか見られない。それではまた来週!次回こそ、修正バージョン完成か!?