【5分でVBA学習】避けては通れないSubプロシージャ ～Excelフィルタリングツール コード解説 #2～

# 1. はじめに
ＡＲアドバンストテクノロジ株式会社（ＡＲＩ）の鈴木タクヤです。

今回はExcelフィルタリングツールのソースコード解説第2回です。

（ツールの詳細については以下の記事を、「Excelフィルタリングツール解説シリーズ」タグの記事一覧については以下の記事下部「5. 解説記事のリンク」をご参照ください。）

https://qiita.com/TakuyaSuzuki/items/75789a1cf0b3a7c31c0b

__[解説第1回](https://qiita.com/TakuyaSuzuki/items/158ec6815509fd27de67 "【5分でVBA学習】マクロ処理高速化 ～Excelフィルタリングツール コード解説 #1～")__ は中級者向けのマクロ高速化についての記事でしたが、今回からは初心者向け。第2回のテーマはExcelのマクロで避けては通れない「Subプロシージャ」です。

# 2. Subプロシージャとは
Subプロシージャとは、「Sub」と「End Sub」で挟まれた部分のことです。マクロの処理内容は、この中に記述されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/4ed1ac81-4740-a025-648c-170598d02251.png)
上の画像は「マクロの記録」機能で、①A1セルを選択し、②「a」を入力し、③A1セルを選択し、④コピーし、⑤B2セルを選択し。⑥ペーストする、という操作を記録したものです。

:::note
「マクロの記録」について知らない方もいると思いますが、これだけでも簡単な自動化ツールが作れて、VBAの学習にも使えるので、本記事のおまけとして[最後に](#5-おまけマクロの記録の使い方)紹介します。
:::

Excelフィルタリングツールにおいては、
`exeCommonProc()`
`copyHeader()`
`filter()`
`clearFilter()`
`activateSheet(ByVal sheetName As String, ByVal wb As Workbook)`
`showFormatErrorMessage(ByVal NoFromTheBeginning As Integer)`
`endMacro()`
という7つのSubプロシージャが存在します。厳密には括弧の前までがSubプロシージャ名で、括弧の中はSubプロシージャを呼び出す際の引数[^1]です。
```vb:
Sub プロシージャ名(引数)
    ～何かしらの処理～
End Sub
```
という書き方になります。
引数については __[次回の解説第3回](https://qiita.com/TakuyaSuzuki/items/1fc0a6c9411e585c8f64 "【5分でVBA学習】使えると便利なFunctionプロシージャ ～Excelフィルタリングツール コード解説 #3～")__ にて解説します。

ちなみにSubプロシージャを別のSubプロシージャなどから呼び出す時は、以下のように記述します。
```vb:Subプロシージャの呼び出し方
Call プロシージャ名　　　　　'引数がない場合
Call プロシージャ名(引数)　　'引数がある場合
```
___Call___ は省略可能ですが、その場合は引数を括弧で囲みません。[Excelフィルタリングツール](https://qiita.com/TakuyaSuzuki/items/75789a1cf0b3a7c31c0b "【ツール提供】Excelユーザなら全員使える?! Excelフィルタリングツール")では、以下のような呼び出しの記述が登場します。
```vb:Excelフィルタリングツールより抜粋
（前略）
 '対象シートの存在確認/活性化
    Call activateSheet(targetSheetName, targetBook)
（中略）
 'マクロ終了処理の呼び出し
    Call endMacro
（後略）
```

[^1]: __引数__ ：プログラムの中で処理を呼び出す際に渡す値のこと。

# 3. ExcelフィルタリングツールにおけるSubプロシージャの役割
## 3-1 exeCommonProc
「copyHeader」「clearFilter」から呼ばれる共通処理について記述されたSubプロシージャです。「filter」からも間接的に呼ばれます。（名前はexecute Common Procedure のつもり）

__[第1回](https://qiita.com/TakuyaSuzuki/items/158ec6815509fd27de67 "【5分でVBA学習】マクロ処理高速化 ～Excelフィルタリングツール コード解説 #1～")__ で紹介した「処理高速化のおまじない」の後は、主にフィルタリング対象シートに対する情報をツールに入力されたセルの値から読み取り、 __対象ファイルが開いていなければ開き__、セルの入力内容に誤りがないか、各種フォーマットチェックを実行します。

:::note
そう、実は対象ファイルを開いていなくても、ツールの処理を実行することができます！
ツールの初回実行時は対象シート名や表見出しの両端セルの指定を空白セルのまま「処理中ポインタ解除」以外のマクロ実行ボタン押下で、対象ファイルを開くという裏ワザが使えます。
:::


## 3-2 copyHeader
「表見出しのコピー」ボタンに割当てた、フィルタリング対象の表見出しをツール側にコピーするSubプロシージャです。

「exeCommonProc」を呼び出した後、表見出しのリセットのためにシートの7行目から10行目を削除します。その後指定された情報に基づき、表見出しをコピーします。


## 3-3 filter
「フィルタリング」ボタンに割当てた、このツールの肝である、フィルターを適用するためのSubプロシージャです。

後述の「clearFilter」を呼び出した後、二重の __forループ処理__ で、指定されたフィルター抽出条件を __配列__ に格納し、AutoFilterメソッドに配列を渡す処理を繰り返します。

__ループ処理__ や __配列__ 等についても、この解説記事シリーズで取り上げる予定です。

## 3-4 clearFilter
「フィルタのクリア」ボタンに割当てた、対象の表を含むシートのフィルターを解除するためのSubプロシージャです。「filter」の処理冒頭にも呼び出されます。

対象の表を含むシートがフィルタリング済みの場合はフィルターを解除し、「filter」から間接的に呼び出されている場合には処理を継続、「フィルタのクリア」ボタン押下で呼び出されている場合には処理を終了するために後述の「endMacro」を呼び出します。

## 3-5 endMacro
ソースコードに登場する順番は前後しますが、「処理中ポインタ解除」ボタンに割当てた、事後処理のためのSubプロシージャです。

こちらは __[第1回](https://qiita.com/TakuyaSuzuki/items/158ec6815509fd27de67 "【5分でVBA学習】マクロ処理高速化 ～Excelフィルタリングツール コード解説 #1～")__ の「4. 注意点」で紹介したものです。マクロの処理完了後や、エラーで処理を中止した場合に「処理高速化のおまじない解除」を呼び出します。ボタンの登録は、ソースコード内でキャッチできなかった実行時エラーで処理が中断した場合に「処理高速化のおまじない解除」を実行するためのものです。

## 3-6 activateSheet
ここからはエラー対処用のSubプロシージャです。

「activateSheet」は「exeCommonProc」から呼ばれます。 __指定されたワークブック__ に、 __指定された文字列__ と名前が一致するシートが存在すれば当該シートを活性化し、存在しなければ以下のようなエラーメッセージを表示し、「endMacro」を呼び出します。マクロ名の後の`(ByVal sheetName As String, ByVal wb As Workbook)`の部分が引数で、`sheetName`が __指定された文字列__、`wb`が __指定されたワークブック__ を表します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/3c6a8a11-c32b-19f4-f546-e53d1853f5cb.png">

## 3-7 showFormatErrorMessage
こちらは「checkFormat」というFunctionプロシージャから呼ばれるSubプロシージャです。

:::note warn
checkFormat？何なん？という顔をされたそこのあなた。その反応が正解です。こちらについては解説第3回（Functionプロシージャ編、Comming Soon!）で解説予定です。
:::

指定されたセル番地を表す文字列のフォーマットチェックがNGだった場合、以下のエラーメッセージを表示します。マクロ名の後の`(ByVal NoFromTheBeginning As Integer)`の部分が引数で、`NoFromTheBeginning`はセル番地を表す文字列の __先頭から何文字目__ でエラーとなったかを表します。
（以下のキャプチャでは `NoFromTheBeginning = 3`）
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/4984e396-c682-5286-86e0-24bc4c01b31a.png">

# 5. おわりに
以上、Subプロシージャの解説でした。

マジメにソースコードを見ていただいた方はおわかりかもしれませんが、意図的に解説を飛ばした「 __Function__ 」と「 __End Function__ 」で挟まれた部分については __[次回](https://qiita.com/TakuyaSuzuki/items/1fc0a6c9411e585c8f64 "【5分でVBA学習】使えると便利なFunctionプロシージャ ～Excelフィルタリングツール コード解説 #3～")__ 解説します。

👇次回

https://qiita.com/TakuyaSuzuki/items/1fc0a6c9411e585c8f64

:::note
Subプロシージャについては以上ですが、初心者の方はここから先のおまけが一番有用かもしれません…
:::

# 6. おまけ；「マクロの記録」の使い方
「マクロの記録」を使用したことがない方向けに、手順をご紹介します。

①「開発」タブ-「マクロの記録」を押下します。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/1fb6a3a8-78bd-d988-2d77-d39df10f692e.png">


②マクロ名やマクロの保存先（どのブックに保存するか）を入力します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/85e2f427-a97b-5aac-ebfd-a37760059e41.png">


③保存したい操作（セルに値を入れる、行を追加する、特定の範囲を選択してコピペする等）を実行し、最後に「開発」タブ-「記録終了」を押下します。__…以上！！__
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/a03a35dc-0949-f6ea-f67c-50e94e36b226.png">

:::note warn
マクロを記録したブックを保存する場合、拡張子が「.xlsx」ではなく「__.xlsm__」のマクロ有効ブックとして保存してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/a608a676-7042-fdc5-e4e9-6c788e7d796b.png)
:::

ソースコードの内容を確認したい場合や、記録内容を再現したい場合や削除したい場合には、「開発」タブ-「マクロ」を押下し、操作します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/bb58a626-531a-a47e-f05c-e07a4c3fe8fd.png">

内容確認は「編集」押下で。
VBE[^2]が開き、「標準モジュール」が追加されたことや、②で入力したマクロ名のSubプロシージャが追加されていることが確認できます。
[^2]: ___VBE___ ： ___V___ isual ___B___ asic ___E___ ditorの略で、VBAのコードを入力する際に使用するソフト（Excelでは「開発」タブ「Visual Basic）押下、もしくは「Alt」+「F11」等で開くやつ）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2566746/15c73f6a-8bee-22d6-afe9-0f5b57e78847.png)

:::note
人による判断が不要で何度も繰り返し行うような単純作業は、これで自動化・高速化できます。
また、手動で操作した内容がVBAではどう記述されるのか、勉強になります。
:::

# 7. 参考文献
こちらはMicrosoftの公式ドキュメントです。

https://learn.microsoft.com/ja-jp/office/vba/language/glossary/vbe-glossary#procedure

こちらは私がものすごくお世話になっている「エクセルの神髄」という解説サイト。より深く学習を進めたい方は是非。

https://excel-ubara.com/excelvba1/EXCELVBA306.html