初心者のためのExcelマクロ超入門(絶対できるVBA開発)

マクロがまったくわからない人のためにエクセルマクロやVBAについてできるだけわかりやすく書いています。Twitter:@shuhhohhey

初心者のためのExcel(エクセル)マクロVBA入門-成績表マクロの作成:マクロを再設計する

さて、今回から新たに今までに作った成績表マクロを一度ぶっ壊してみます。完全に0にするわけではありません。必要な処理と仕様を洗い出し、どのような処理をすることが一番スマートなのか?を考えてみましょう。

マクロの仕様を考える前に前提を決める


まず大切なのはこのマクロの前提です。例えば、成績表ならば現在は主要5教科ですが、この科目数は可変が良いのでしょうか?それとも固定でも特に問題ないですか?また、印刷はそもそもに必要だろうか?全体での成績って必要ですか?クラスの人数は10人で固定なのか?可変なのか?全員分の成績表って一気に作れる方が便利?そのための前提って?

というように色々と模索しながら考えていきます。今回は決めていかなければいけないので、仮で決めていますが、自分で自分なりの前提を決めてください。

<前提>

・科目は5教科(算数・国語・理科・社会・英語)とする
・元の成績表フォーマットは科目の順番なども変わらない(固定)
・生徒の人数は可変とする
・成績表は個別にファイルとして保存する
・テストを受けなかった生徒の点数は0点とする
・成績表のテンプレートファイルはマクロファイルと同じ場所にあるものとする
・出力する成績表ファイルの保存先はマクロファイルがある場所に「成績表」フォルダ
 を作成しておき、そこに保存するものとする
・全体成績表は必要だが、今回は作成しない。


こんな感じでしょうか。これがしっかりしているとマクロを作る時にとっても楽なので考えられるだけ考えておきましょう。

マクロの仕様を考える


これでもう一度仕様を考えてみます。先の前提から考えると今まで使っていたファイルのボタンを位置とかちょっとまずいってわかりますでしょうか?生徒の人数は可変という前提なのでフォームやボタンを下に設置するのはちょっと見にくいですよね?ボタンは横につけるようにする。また、成績表用のテンプレートも必要だ。などなど・・・一連の仕様を考えます。

<仕様>
・成績表をマクロのフォーマットにしたがって入力する
・出席番号を入力フォームに入れる
・出席表出力ボタンを押すと確認ウィンドウが出る。
・はいを押すと成績表が「成績表_個人名.xls」として成績表フォルダの中に保存される
・成績表にはコメント欄があり、事前に設定したコメントも表示される。
・印刷チェックがあると印刷もされる。(印刷プレビュー)

こんな感じでしょうか?

想定されるエラーを考えよう!


今までは場当たり的にこのマクロならこういうエラーが発生するとか考えていましたよね?実はこの考え方はダメなやつです。小さなプログラムの種から大きくしていく。という方法を前回まで取っていたので、このようになっていましたが、実はダメです。これを続けてしまうと、非常に無駄が多くかつ、読みにくくて不安定なものが出来上がってしまいます。
通常は、想定した仕様に基づいて考えられるエラーを先に考えるべきです。そしてこれを考える時に前に考えた「前提」が役に立ちます。前提がないとあれもこれもと、想定外が多すぎて、収拾がつかなくなってしまいます。ですので、まず前提があり、その前提を覆すような想定外はいわゆる「運用エラー」として「システムエラー」で処理をしてしまいます。

<想定されるエラー>
  • 出席番号が入力されてない場合
    • 出席番号を入力してください。
  • 出席番号入力に数字以外を入力した場合
    • 出席番号が存在しません。処理を終了します。
  • 成績表の点数に数字以外が入っていた場合
    • 成績表の点数が不正です。処理を終了します。
  • 存在しない出席番号が入力された場合
    • 出席番号が見つかりません。処理を終了します。
  • 成績表テンプレートがない場合
    • テンプレートファイルがありません。処理を終了します。
  • 指定している保存先がない場合
    • 保存先が存在しません。処理を終了します。

こんな感じでしょうか?

これで大体のこのマクロの仕様は決定しました。いまさらですがこんなの「マクロの記録」では、おそらく実現することはできないでしょうし、ましてやプログラミングの基礎もわからない人がこれを見てもはい?という感じです。まずはプログラミングの基礎をしっかりと勉強しましょう。当ブログのエクセルVBAのカテゴリを最初から読むときっとわかります(笑)

さぁ、後は作るだけなんですが、それを作る前に必要な処理をある程度洗い出しておきます。するとそれだけでもうモジュールを分けてしまう指標ができます。

必要な処理を考えよう!


ここではこのマクロに必要な処理を考えます。大きく分けてあとは細かく分けましょう。

  • ボタンが押されたらメインの処理を呼び出す
  • 想定されるエラーについて調べる
  • 成績表を読み込む
  • 成績表を出力する

これくらいでしょうか?基本的にはインプット(成績表一覧)があって、アウトプット(個人の成績表)というう感じですね。ここからさらに細かく考えます。

  • ボタンが押された。
    • 確認メッセージを表示する
    • 「いいえ」なら何もしない
    • 「はい」メインの処理を呼び出す
  • 事前の処理をする
    • 画面の更新をストップする
    • ボタンや入力フォームを非活性にする
  • エラーのチェックをする
    • 各種想定したエラーのチェック
    • エラーならマクロを終了する
  • 成績表を読み込む
    • 出席番号の成績表を読み込む
  • 成績表を出力する
    • 成績表テンプレートファイルを開く
    • 成績表とコメントを出力する
    • 個人名_成績表.xlsという名前で保存する
    • 印刷チェックがあれば印刷プレビューを表示する
    • テンプレートファイルを閉じる
    • 出力が完了したメッセージを表示する
  • 事後の処理をする
    • 画面の更新を元に戻す
    • ボタンや入力フォームを非活性にする
  • マクロ終了する

こんな感じしょうか?最初はここまで詳細に考えることが難しい場合は、ここまでじゃなくてもいいです。前述した大きな枠のみの状態で作り始めて、作りながら色々と細かいところを考えていけばよいと思います。
私はこうすべきと考えていますが、他にもやり方は千差万別たくさんあると思います。自分なりのベストなやり方を是非考えてみると良いと思います。

必要な処理からメソッドやモジュールを考えよう!


ここまでできるとなんとなく、イメージがはっきりしてきます。例えば「ボタンが押された。」はイベント処理メソッドですし、事前の処理をする。というのもそのままメソッドにできそうです。こうやってどんどん処理を分けていき、メインではそれを管理、つまり呼び出してあげるだけにすると、何となくかっこいい感じになると思いませんか?

  1. ボタン押下時のイベント処理
  2. メイン処理(mdlMain)
    1. 事前の処理(mdlStartEnd.PreStart)
    2. エラーのチェック(mdlErrorCheck.InputCheck)
    3. 成績表の読み込み(mdlInputScore.InputScore)
    4. 成績表の出力(mdlOutputScore.OutputScore)
      1. 印刷プレビュー(mdlOutputScore.PrintScore)
    5. 事後の処理(mdlStartEnd.PreEnd)

はい、こんな感じでしょうか?あとはこれを元にして、前述した細かい部分はコメントとして記載しながら、各処理を書いていくだけです。

以上で簡単ですが、マクロの再設計は完了です。いかがでしょうか?ここまでやれば何となく作れそうな気になりませんか?設計とは作れるような気がする!という所まで落とし込むことが重要です。今までに作ったものも十分に使えます。ある程度は再利用しながらまた、少しずつ作っていきましょう。

次回から、またコードまみれにしていきます。(笑)


今日はここまで!

かしこ