まだVBAを知らない君たちへ。なんだかんだ我々はVBAを愛している(と思う)


まえおき

今年はほとんどコードを書くことがない1年だったのですが、最近久しぶりにVBAに触れる機会があったので、個人の備忘録として雑多にまとめておこうかと思います。

諸君、VBAはいいぞ

環境構築が簡単であるので個人的には非エンジニア・プログラマの方がプログラミング的なものに触れる最初の入り口としてもちょうどいいのかなと思います。
普段Excelを使う仕事をしているなら、業務を効率化するチャンスがあるかもしれません。
もし複数回、同じことを行う機会があるのであれば、ボタン1つでできるようになったほうが効率的です。
VBAがめちゃくちゃできるとすごい!とかはあんまりないけれど、使えたほうが間違いなくいいです。ちょっとした紳士の嗜みってやつです。

VBA、ここがいい

  • リファレンスや用法・用例が調べればいくらでも出てくる。
  • セルの処理を行う場合に処理結果が目に見えるので動作が確認しやすい。
  • 凝ったものを作ろうと思えばいくらでもこだわれる。

VBAを書くときはここを意識しろ

保守性・汎用性の担保ができているか。
これにつきます。(VBAに限ったことではないけれど)
「昨日の自分が書いたコードは他人のコード」であり、修正や追加の機能に対して伸びやかな柔軟性を持ったコードは未来の誰かを助けてくれます。
とりあえず動けばいいよね!という他人が書いたVBAを修正することは苦痛なものです。

コピペにより実装されたまとまりのないコード、特定のセルを動作させる部分がハードコーディングになっているため少しフォーマットを直すだけでも影響範囲が読めずに大工事が必要となる膨らんだプロシージャ、先祖代々秘伝のソース…

高い可読性を持ち、各処理毎にプロシージャを分けてコードを書くことで再利用可能な部品としてプロシージャを使うことができます。
次に自分が書いたVBAをメンテする人のことを思いながらコードを作成していきましょう。

おそらく人生で役に立つことはないだろう。変態的なVBAたち

過去に話題になってきたけれど、実際に使ったことは残念ながらない変態VBAたち。
VBAでその気になればここまでやれるんだぜ…という人生の肥やし。

Excelでハリケーンの進路を可視化
「Excel上で動くドラムマシン」を作成した猛者が登場する
集中線を作成するしょうもないマクロの作り方【Excel VBA】
数式や関数を打ち間違えるとニコニコ動画風に煽ってくるExcel VBAマクロの作り方

【番外編】
Excelで「ドラゴンクエストIII」をマクロ言語なしで再現した猛者が登場

Tips

ほとんどが個人的なメモレベルですが…何かの足しにでもなれば幸いです。

処理軽量化
'処理している動作の描画を出すと重くなるので、ディスプレイの更新をFalseに
Application.ScreenUpdating = False
'処理が終わったらディスプレイの更新を戻すこともお忘れなく
Application.ScreenUpdating = True
'一時的にオペレーティングシステムに制御を移し、イベントの処理を行わせる
'重めの処理の合間に入れることで応答なし状態を防ぐことができる
DoEvents 
ファイル処理系
'PDFファイル出力
'ブックのあるフォルダ内にPDFフォルダを作成する場合
Dim outputDir As String: outputDir = ThisWorkbook.Path + "\PDF\" '保存先フォルダパス
'出力先が存在しない場合は作成
If Dir(outputDir, vbDirectory) = "" Then
    MkDir outputDir
End If

Dim outputFileName As String 'ファイル名
outputFileName = outputDir + "PDFファイル名.pdf"

'出力
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, outputFileName :=outputFileName 
'CSVファイルを選択して取得する
Dim csvFileName As String '選択されたファイル名用変数
Dim buff As String 'ファイルの中身を文字列として格納する変数
csvFileName = Apprication.GetOpenFilename(FileFilter:="CSVファイル(*.csv).*.csv", _
                                          Title:="CSVファイルの選択")
Open csvFileName For Input As #1
    Line Input #1, buff
Close #1

Dim lineArr As Variant '1行分を一時的に格納するための配列
Dim tmpArr As Variant  'カンマで分割した1行分のデータを一時的に格納するための配列

lineArr = Split(buff, vbLf) '改行コードで分割
For i = 0 To UBound(lineArr) - 1
    tmpArr = Split(lineArr(i), ",") 'カンマで分割
    'セルへ出力するため、カンマで分割されたサイズ分の範囲にリサイズして値を出力
    Cells(i + 1, 1).Resize(1, UBound(tmpArr) + 1).Value = tmpArr
Next i

おわりに

今回まとめた内容は本当にさわりの部分だけになりますが、VBAに興味を持っていただけると嬉しく思います。
今後、より実務的なVBAのコードをまとめたりもできたらいいな、とぼんやり考えているので機会があればまたお会いしましょう。