和風スパゲティのレシピ

日本語でコーディングするExcelVBA

ExcelVBA「こんなのあるなら先に言ってよ」機能大全

このブログの記事数が300に到達しました。

いつもお読みいただいている皆様本当にありがとうございます!


さて300記事を記念して、今回はおすすめ機能の厳選記事を書きたいと思います。


その厳選のテーマはズバリ

「こんな機能があるなら先に言ってよ!!」

な機能たちです。



ExcelVBAの無数の機能の中には、

  • 絶対必要ではない(他の方法でも実装できる)ため知名度が低い
  • でも知っているだけ使えるくらい、実は簡単に使えてしかも便利

という機能がたくさんあります。


今回はそんな機能をまとめてみました。


「便利だけどその分習得難易度も高い」機能は外してありますので、
学習コスパが良い機能」の一覧になっています。


是非一読いただき、知らなかったものがあればお持ち帰りください。

日本語変数・日本語関数

まずははじめに本ブログのテーマから。

VBAの変数名・関数名には日本語を使用することができます。
(というか最近のプログラミング言語で使えない言語はほとんどないです)


日本語変数を用いるメリットとしては、
翻訳が不要というのももちろん大きいのですが、

  • 日本語部分だけ読んでもなんとなく処理の流れがわかる
  • どれが構文でどれが変数かが見ただけで分かる

という点も、あまり語られないですが強力なアドバンテージになります。


例えばSpecialCellsにまだ慣れていない段階では、

myRng.SpecialCells(xlCellTypeVisible).Value = myNum
セル範囲.SpecialCells(xlCellTypeVisible).Value = 入力値

間違いなく下のコードが読むのが楽ですよね?

慣れないうちは「どれが自作でどれがMicrosoft製かわかる」のって大事です。


ということで、これらメリットを最大限に享受するために、

「英訳がわからない変数は日本語にしてもよい」ではなく、
変数はすべて日本語にする」というルールでやってみてください。

冗談抜きに世界が変わりますよ。


まあこの辺は散々他の記事で語ってきた部分ですので、
詳細はこちらの記事に任せて次に行きましょう。

www.limecode.jp

シートオブジェクト名

続いて紹介するのが「シートオブジェクト名」です。

実はワークシートには「プログラム上の名前を付ける機能」があり、

シートオブジェクト名の設定

この部分を編集することができます。

何もしないと「Sheet1」とかになってる場所ですね。


ここに画像のように「WS + 実際のシート名」と名付けておくと、
以下のようにシートを指定できるようになります。

Worksheets("購入データ").Cells(R, 2)
' ↓ シートオブジェクトに書き換え
WS購入データ.Cells(R, 2)

 

加えて「WS」を必ず頭につけるルールで全シートを命名しておけば、
Ctrl+Spaceの「コードの入力補完」機能を起動することで、

WS+Ctrl+Spaceの選択肢

この選択肢から選んで入力することができます。


この時点で既にWorksheets("○○")よりも書きやすそうというのがわかりますが、
さらにWorksheets("○○")と違って

Worksheetからのインテリセンス

この選択肢も表示されるため、以降のコードですらこちらの方が書きやすいです。


他ブックには使えないという弱点はありますが、自ブックのシートを指定する上では、
取り違えも起きづらく、読みやすく、書きやすい最強のシート指定方法です。

まだ使っていなかった方は是非とも採用してみてください。

www.limecode.jp

コードの入力補完(Ctrl+Space)+ハンガリアン記法

先ほど軽く紹介しましたが、コードを途中まで打った後、
Ctrl + Space で残りのコードを自動入力させることができます。


候補が複数ある場合は先ほどのように

Ctrl+Spaceの選択肢

こんな選択肢が出て、選んだあとは「Tab」で入力ができます。


「Workb」まで入力して候補が1つしかなくなっている場合は、
選択肢も出ず残りをそのまま入力してくれます。


これを使えば変数の打ち間違えを極端に減らせますね!


しかも先ほどの「変数の種類を英字で先頭に付ける」技を組み合わせると、
↓こんな風に選択肢入力でサクサクコードが入力できるようになります。

アプリケーションハンガリアン日本語変数の入力アニメ

わざわざコードを手入力する量を相当減らせるだけでなく、
日本語変数を日本語入力OFFのまま入力できるというのも強力ですね。


この「変数の種類を頭に付ける」記法をハンガリアン記法と呼びます。

行番号R_、列番号C_、セルcell、セル範囲rangeなど自分ルールを決めておけば、
ほとんどの変数を選択肢入力にすることができるようになります。

是非とも採用してみてください。

www.limecode.jp


列挙型定数Enum

続いて紹介するのが本記事の真打、「列挙型定数Enum」です。

初めて知ったとき
「こんなのあるなら最初から言ってよ!」
となる機能筆頭はこいつなんじゃないかと思います。


Enumは「Long型の定数を連番で持つ仕組み」なのですが、
主たる用途は「列番号に名前を付ける」ことになります。


例えば、

Cells(R, 4) = Cells(R, 2) * Cells(R, 3)

このよくあるコードを、

' モジュールの上部
Public Enum データの列
    No=1
    単価
    個数
    金額
End Enum

' Subの中身
Cells(R, データの列.単価) = Cells(R, データの列.個数) * Cells(R, データの列.金額)

こんな風に書き替えることができます。


メリットは大きく3つあり、

◇ コードが「読めばわかるコード」になる

Cells(R, 4) = Cells(R, 2) * Cells(R, 3)
' ↓ この処理が「金額 = 単価×個数」なのが見ればわかる
Cells(R, データの列.金額) = Cells(R, データの列.単価) * Cells(R, データの列.個数)

 
◇ 選択肢から入力ができる
列挙型の選択肢


◇ 列を挿入することになったときEnumに挿入するだけで済む

例えば「B列に社名を挿入する」事態になったとしても

Enum 購入歴データの列
    No = 1
    社名        ' ←これを挿入した
    単価    ' ← B列だった単価がC列になるが、連番機能で勝手に3になっている!
    個数    ' 以降の3→4、4→5も同様に自動対応済
    金額
End Enum

こんな風にEnumに列名を追加するだけで改修が終わってしまう。


この3つのメリットを享受することができます。


しかもEnumは最初の定義を作るのもとても簡単で、
セルの見出しを「行列入替」コピーした後で貼り付けると簡単に作れてしまいます。

Enum定義の作成アニメ


学習コストも低く、慣れれば1分程度で書けるくらい準備コストも低いのに、

  • A,B,C,… と列番号を数えて入力する必要がなくなる
  • なんならシートを見に行かずにコード画面だけを見てマクロが書ける
  • 列の挿入や削除があった時に、12を13、13を14、…と延々と列番号を書き替える地獄のような作業から解放される

という素晴らしいパフォーマンスを得られます。

特に最後の地獄を味わったことがある人なら、
これがいかに強力な機能かわかる
のではないでしょうか。


所詮定数であり「これがないと書けない処理はない」ため知名度は低いのですが、
この機能でCellsを指定できるようになると誇張なしで世界が変わります。


まだ導入していない方はぜひ導入してみてください。

www.limecode.jp

Resizeプロパティ(Rangeオブジェクト)

次に紹介するのが、セル範囲を取得する「Resizeプロパティ」です。

こちらは

始点セル.Resize(行数, 列数)

この記述でセル範囲を取得できるものです。


セル範囲の取得は↓の書き方

ws.Range(ws.Cells(R1, C1), ws.Cells(R2, C2))

いわゆるRange(Cells,Cells)をまずは基本形として覚えるため、
Resizeを知らないまま過ごしている人もよく見かけます。


ですがRange(Cells,Cells)法はCellsの指定によっては非常に煩雑になることがあり、
そんな時、Resizeを知っていると相当楽に書けるという場面が出てきます。


例えば「データ1列分のセル範囲を取得したい」ときは

wsデータ.Range(wsデータ.Cells(2, 1), wsデータ.Cells(最終行, 1))
' ↓ 書き替え
データ数 = 最終行 -1+ 1
wsデータ.Range("A2").Resize(データ数)

この記述ができるとコードがかなり読みやすくなるうえ、
他の列にも「データ数」の変数を使いまわせるメリットが得られます。


また、最終行はわからないがセル範囲の大きさが10×4とわかっている場合などは、

ws.Range(ws.Cells(R1, C1), ws.Cells(R1 + 10 , C1 + 4))

ws.Cells(R1, C1).Resize(10, 4)

このようにResizeの方が圧倒的に書きやすく、
しかも読みやすくなっているのがわかると思います。


Resizeを知っておくと小回りが利くようになりますし、
いずれ配列を扱うようになるとさらに強力に使えるプロパティです。

ぜひとも修得してください。

www.limecode.jp

Formula(シート数式の直接入力)を用いた計算

最後にFormulaプロパティを用いたシート数式の活用法を紹介します。


シート関数をVBAで使う場合に真っ先に思い浮かぶのはWorksheetFunctionですが、
もう一つの方法として、セルに直接数式を打ち込む方法もあります。

' このコードでB列をVLOOKUPを使った計算で埋めることができる。
Range("B2:B1000").Formula = "=VLOOKUP(A2,マスタ!A:B,2,FALSE)"
Range("B2:B1000").Value = Range("B2:B1000").Value

 
「セル範囲.Formula = "=数式"」を実行した場合、
セル範囲の第1セルにその数式を入力し、
その後他のセルへコピーしたときと同じように数式が入ります。

あとは同じ範囲に「Value=Value」を実行すればいいだけですね。


変数を使ってキレイに書くと、

Dim 計算エリア As Range: Set 計算エリア = Range("B2:B1000")
計算エリア.Formula = "=VLOOKUP(A2,マスタ!A:B,2,FALSE)"
計算エリア.Value = 計算エリア.Value

こんな感じになります。



この方法のすごいところは、書きやすさもあるのですが、
なにより処理速度が超速です。


詳しくはリンク先で説明していますが、

  • セルへのアクセスが少ないためFor文の数百倍速い
  • さらに検索系関数自体がWorksheetFunctionよりFomulaの方が速い

という効果があり、場合によっては数千倍のスピードになります。


よく「配列を使うと早い」と言われますが、
この方法でも配列と同じかそれ以上の高速効果が得られます。

しかもこっちの方が圧倒的に習得が簡単というおまけつき。


Excelという強力なアプリケーションを使えるVBAならではの技ですので、
こちらもぜひとも修得してください。

www.limecode.jp



以上で「こんなのがあるなら先に言ってくれよ!!」機能の紹介を終わります。


もう一度まとめると、

これらの機能を紹介しました。


ExcelVBAは人のコードを見る機会に乏しいため、
独学でやっていると上級者でも意外と知らない機能があったりします。

たまにこうやって網羅的に機能一覧を漁ると、新たな発見があるかもしれません。


今日の記事で一つでも皆さんに新しい発見がありましたら幸いです。
ということで、また次の100記事もよろしくお願いいたします。