標準モジュールなどの一括インポート
このページでは標準モジュールの一括インポートについて紹介しています。
エクスポートについては「標準モジュール等の一括エクスポート」をご参照ください。
作成したマクロを他のブックでも使う方法
VBAを利用していると標準モジュールやフォームやクラスを作成していくことになりますが、作成したマクロを他のブックでも使いたいことがあります。
汎用的に使うのであれば個人用マクロブック(personal.xlsb)に書くことも一つの方法ですが、そこまでではない、という場合もあります。
そういう場合はVBA画面を開き、コピー元のブックから標準モジュール等をエクスポートして、利用するブックでインポートすることでマクロの転用が可能です。
インポートは1度に1ファイルしか出来ない
マクロを転用する際に面倒なことがあります。それはエクスポートとインポートがそれぞれ1ファイルずつしか行えないことです。
コピー元のブックが持つマクロが標準モジュール1ファイルだけ、などであればいいのですが、その他にも別の標準モジュールやフォームやクラスなどが複数あった場合は全てをエクスポートやインポートするのはかなり面倒です。
ここがVBAがプログラミング言語として弱い部分の1つです。
一般的なプログラミング言語であればソースコードはテキストファイルとして扱うことが出来るため他のプログラムへの転用はファイルをコピーするだけで行えます。ところがVBAのソースコードはブックに紐づいているためテキストファイルをコピーするようには他のブックへ転用できません。
その問題を解消するために、VBAの標準モジュールやクラスやフォームを一括してインポートするマクロで対応します。
事前設定
VBAで一括インポートを行う前に、事前にExcelの設定を変更する必要があります。
エクスポートとインポートを可能にする
開発タブ→コード→マクロのセキュリティを開きます。または、ファイルタブ→オプション→セキュリティセンター→セキュリティセンターの設定ボタン→マクロの設定、でもいいです。
そこで「VBAプロジェクトオブジェクトモデルへのアクセスを信頼する(V)」にチェックを付けます。このチェックを付けることで、VBAでの標準モジュールなどのエクスポートやインポートが可能になります。
あとは各ダイアログのOKボタンを押していきます。
これでエクスポートとインポートが可能になります。
VBComponentの参照設定
VBA画面のツールメニュー→参照設定で、「Microsoft Visual Basic for Application Extensibilly 5.3」にチェックをつけてOKを押します。
これによりVBComponentクラスとVBComponentsクラスの利用が可能になります。
VBComponentクラスはVBAProjectの標準モジュールやフォームやクラスの各ファイルの操作を行うことができるクラスです。
VBComponentsコレクションクラスは、そのブックに含まれる標準モジュールやフォームやクラスの全ファイルの管理を行うクラスです。
FileSystemObjectの参照設定
ファイル操作をFileSystemObjectにて行っているため、VBA画面のツールメニュー→参照設定で「Microsoft Scripting Runtime」にチェックをつけてOKを押します。
これによりFileSystemObjectクラスの利用が可能になります。
一括インポートのソースコード
以下のマクロは、対象フォルダ配下に含まれる標準モジュール、クラス、フォームを全てインポートするマクロです。
インポートの際に、既に同じ名前のモジュールが存在している場合は上書きします。
1番目の引数にインポートするブックのWorkbookオブジェクトを指定し、2番目の引数にインポートするモジュールが格納されているフォルダを指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
'// 指定ワークブックに指定フォルダ配下のモジュールをインポートする '// 引数1:ワークブック '// 引数2:モジュール格納フォルダパス Sub ImportAll(a_TargetBook As Workbook, a_sModulePath As String) On Error Resume Next Dim oFso As New FileSystemObject '// FileSystemObjectオブジェクト Dim sArModule() As String '// モジュールファイル配列 Dim sModule '// モジュールファイル Dim sExt As String '// 拡張子 Dim iMsg '// MsgBox関数戻り値 iMsg = MsgBox("同名のモジュールは上書きします。よろしいですか?", vbOKCancel, "上書き確認") If (iMsg <> vbOK) Then Exit Sub End If ReDim sArModule(0) '// 全モジュールのファイルパスを取得 Call searchAllFile(a_sModulePath, sArModule) '// 全モジュールをループ For Each sModule In sArModule '// 拡張子を小文字で取得 sExt = LCase(oFso.GetExtensionName(sModule)) '// 拡張子がcls、frm、basのいずれかの場合 If (sExt = "cls" Or sExt = "frm" Or sExt = "bas") Then '// 同名モジュールを削除 Call a_TargetBook.VBProject.VBComponents.Remove(a_TargetBook.VBProject.VBComponents(oFso.GetBaseName(sModule))) '// モジュールを追加 Call a_TargetBook.VBProject.VBComponents.Import(sModule) '// Import確認用ログ出力 Debug.Print sModule End If Next End Sub '// 指定フォルダ配下のファイルパスを取得 '// 引数1:フォルダパス '// 引数2:ファイルパス配列 Sub searchAllFile(a_sFolder As String, s_ArFile() As String) Dim oFso As New FileSystemObject Dim oFolder As Folder Dim oSubFolder As Folder Dim oFile As File Dim i '// フォルダがない場合 If (oFso.FolderExists(a_sFolder) = False) Then Exit Sub End If Set oFolder = oFso.GetFolder(a_sFolder) '// サブフォルダを再帰(サブフォルダを探す必要がない場合はこのFor文を削除してください) For Each oSubFolder In oFolder.SubFolders Call searchAllFile(oSubFolder.Path, s_ArFile) Next i = UBound(s_ArFile) '// カレントフォルダ内のファイルを取得 For Each oFile In oFolder.Files If (i <> 0 Or s_ArFile(i) <> "") Then i = i + 1 ReDim Preserve s_ArFile(i) End If '// ファイルパスを配列に格納 s_ArFile(i) = oFile.Path Next End Sub |
ソースコードの説明
上のコードにはImportAll関数とsearchAllFile関数の2つがあります。メインの処理はImportAll関数です。
ImportAll関数
インポートの本処理はImportAll関数で行います。
searchAllFile関数を使って指定フォルダ配下のファイルパスの配列を取得します。
配列をループし、ファイルパスの拡張子がcls、frm、basであるか(インポート対象か)を判定し、インポート対象の場合は同名モジュールを削除してからインポートを行います。
同名モジュールが無い場合にRemoveメソッドを行うとエラーになるため、それを回避する目的で2行目に「On Error Resume Next」を入れています。
削除時に存在チェックを入れてもよかったのですが、面倒だったのでこのようにしています。
searchAllFile関数
searchAllFile関数は指定フォルダ配下にある各ファイルのパスを配列に格納します。
ここではモジュールのパスが格納されることになりますが、関係ないファイルが格納されていればそれも配列に格納されます。
関係ないファイルの除外はここではなくImportAll関数で行います。
この関数についての詳細は「VBAで指定フォルダのファイル一覧を取得」で紹介しています。
使用例
アクティブブックに指定フォルダのモジュールをインポートするサンプルです。
1 2 3 4 5 6 7 |
Sub ImportAllTest() Dim s As String s = "C:\web\test\test\a\" Call ImportAll(ActiveWorkbook, s) End Sub |
実行結果
1. モジュールを格納します。サブフォルダがあってもいいのですが、ここでは単純な1フォルダです。
2. 使用例のImportAllTest関数を実行します。実行後は以下のようにインポートされます。
Personal.xlsbにインポートする場合
Personal.xlsbにインポートしたい場合は、Personal.xlsbに標準モジュールを追加して、そこに上のコードのImportAll関数とsearchAllFile関数と使用例のImportAllTest関数をコピペします。
その後、使用例のコードのActiveWorkbookの個所をThisWorkbookに変えて、その標準モジュール上で動かしてください。
上書きで元のコードが削除されるのが怖い場合は28行目のRemoveの行をコメントアウトしてください。
同名モジュールがあった場合は別名で登録されます。たとえばModule1が既にある場合に同じ名前のMoudule1.basを追加すると、Module11.basという1が追加された名前で登録されます。