vba裏技、技、論理 - プログラムの組み方
① vbaはある程度以上長くなると書けなくなります。この問題を解決するのが、sub-procedureというテクニックです。
Sub-procedure自身も独立したプログラムですが、元プログラムの中に含ませて書くと、全体のプログラムの長さが短縮されます。
例えば
ファイルを開く
日付
顧客管理
としておけばsub-procedureはそんなに長いものではないので、元プログラムは3行で済みます。
② 但しここで一つの問題が出てきます。それは変数がsub-procedure間を通じて移管されないことです。これを解消するのが「public」というやり方です。元プログラムの一番上に「public」を設定しておけば、変数は全てのsub-procedure間に亘って移管され、有効になります。
③ 変数は宣言しなければなりませんが、難しいことを考えずに全てを「variant」としておいても問題は発生しません。
④ 例えば変数を「ppp」とすれば、「public ppp as variant」で全て解消します。「boolean」とか「long」とか「date」とか一切考える必要はありません。なお変数は後で分からなくなると困るので、できるだけ日本語で書くのをお勧めします。ただ時々反応しない場合があるのですが、その時は違う日本語で試してみて下さい。
長いコマンドや打ちにくい単語などは「IME」で必ず単語登録をするようにしましょう。例えばrange(“A1”)などのうちrange(“”)を「r」としておけば後は””の間に「A1」と入力すれば済みます。Selection.borders(xlinsidehorizontal)などは「bh」とでもしておけば、入力が煩わしくなくなります。
ファイルの管理も面倒です。プログラムを組む人が面倒がってはならないのでしょうが、入力時間を短縮するのも大切です。
ファイルは格納位置を設定しておかないと、格納も開くこともできません。その時のためにも変数を使います。
格納場所=thisworkbook.pathとしておけば「月別売上」というファイルを開く時は「格納場所 & “\” & “月別売上.xlsm”」の入力は簡単になります。「thisworkbook.path」はプログラムを組むファイルおよびそこに組み込んであるファイル全てに共通ですので、これは便利な方法です。
ファイルは開いてあるのにまた開くコマンドを書けばデバッグするので、開いてあるかどうか確かめて開かなければなりません。そんなとき便利な書き方は下のようにします。
On Error Resume Next ①
Windows(“月別売上”).Activate ②
If ActiveWorkbook.Name <>”月別売上” Then ③
Workbooks.Open Filename:=格納場所 & “\” & “月別売上” ④
End If
On Error GoTo 0 ⑤
この方法は”月別売上”のファイルを「activate」即ち選択するのです。しかしそのファイルが開かれていないことも想定して、まず①を書いておきます。①を書いておかないと開かれていなければエラーになりますので、エラーが起こればそのエラーを無視して次の行に進めというコマンドです。
もしその”月別売上”のファイルが開かれていればそれをactivateする。そうするとIf以下は実行時に条件が合わないからEndまで飛ばします。
しかしもし開かれていなければ②を書いても現在使われているファイルがそのまま使われているようになるのです。だからその次には③を書いてファイルの名前を確かめるのです。もしファイルの名前がactivateしたいファイルでない場合は④を書くのです。⑤はon error resume nextを解除するためのコマンドです。
次のように教えている人もいますが、これが普通のやり方でしょうが、覚えるのや考えて書くのが面倒なので、上記の方法を開発しました。
For Each bk In Workbooks
If bk.Name = ブック名 Then
IsBookOpen = True
Exit For
End If
Next
プログラムを書く時は丸暗記は止めて必ず論理的に考えて書いて下さい。その方が後々書き方が上達するし、調べなくても自分で書き方を考案することができます。
追加テクニック
罫線
罫線のコマンドを書くのは面倒です必ず「IME」で単語登録心をしておきましょう。例
「bb」はselection.borders(xledgebottom).weight=xlとしておけば後は「thin」か「hairline」を書き込めば済みます。「thin」も「hairline」も単語登録するのは勿論です。
あるselectionの中が全て「hairline」で外枠が「thin」の場合は次のように書くと一行無駄なコマンドを書かなくて済みます。
Selection.borders.weight=xlhairline
Selection.borderaround weight:=xlthin
と書いておけば
Selection.borderaround weight:=xlthin
Selection.borders(xlinsidehorizontal).weight=xlhairline
Selection.borders(xlinsidevertical).weight=xlhairline
と3行で書くべきところを2行で済みます。
明日に続く
酒巻 修平