🎢
AIコードエディタでVBAを書く枠組みを作った話
AIコードエディタでVBAを書く枠組みを作った話
1. はじめに
Excel VBA を使った業務ツールを作る際、AIコードエディタで記述したいが、Excel外でコードを管理し、Excelに反映させるプロセスが煩雑である。
実直に実施するのであれば、
- 新規モジュールを作成する。
- モジュールをbasファイルとしてエクスポートする。
- コードを記述する。
- コードをインポートする。
といった手順を踏む必要がある。
また、コードをインポートするときも、もともと「Module」というモジュールがあった場合は、「Module1」といった名前で取り込まれてしまうため、一度「Module」というモジュールを削除(解放)した後、「Module.bas」をインポートする必要がある。
そのため、
- VBAモジュールの最新版を反映したい(なるべく手順少なく)
- 手作業でのコピペは事故が起きやすい
- 反映前にバックアップを必ず取りたい
といった課題を解決するため、今回は VBS(Windows Script Host)を使って
.bas ファイル群を .xlsm に安全に一括反映する仕組みを作った。
2. やりたかったこと
-
.vbsをダブルクリックするだけで実行 - 指定フォルダの
.basを xlsm に反映 - 既存の同名モジュールは削除して置き換え
- 実行前に必ずバックアップを取得
- 成功/失敗をダイアログで通知
3. 設計方針
採用した考え方
- Excelを裏で起動する
- 人の操作を一切介さない
- 失敗しても元に戻せる構成にする
そのために、
- FileSystemObject によるファイル操作
- Excel COM オブジェクト操作
- backup フォルダによる世代管理
を組み合わせた。
4. フォルダ構成
ProjectRoot
│ Sample.xlsm
│
├─ bas
│ ├─ ModuleA.bas
│ ├─ ModuleB.bas
│
└─ backup
├─ Sample_20260112_003015_backup.xlsm
5.実装のポイント
5.1 VBS から Excel を操作する
Set xlApp = CreateObject("Excel.Application")
Set wb = xlApp.Workbooks.Open(excelFilePath)
VBAプロジェクトを操作するため、
「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」
を有効にする必要がある。



5.2 バックアップを必ず取る
処理前に xlsm をコピーし、日時付きで保存する。
fso.CopyFile excelFilePath, backupPath
これにより、万が一モジュール反映に失敗しても復旧できる。
5.3 モジュールの置き換え方法
- bas ファイル名をモジュール名として扱う
- 同名モジュールがあれば削除
- Import 後に Name を明示的に設定
Set importedComp = wb.VBProject.VBComponents.Import(file.Path)
importedComp.Name = moduleName
これによりModule1問題を回避できる。
6. 完成した VBS スクリプト
Option Explicit
'=========================
' 設定ここから
'=========================
' 対象のExcelマクロ有効ブック
Dim excelFilePath
excelFilePath = "D:\Work\VBA\Sample.xlsm"
Dim basFolderPath
basFolderPath = "D:\Work\VBA\bas"
'=========================
' 設定ここまで
'=========================
Dim xlApp, wb, fso, folder, file
Dim importedCount
importedCount = 0
Set fso = CreateObject("Scripting.FileSystemObject")
'=========================
' バックアップフォルダ準備
'=========================
If Not fso.FileExists(excelFilePath) Then
MsgBox "Excelファイルが存在しません。" & vbCrLf & excelFilePath, vbCritical
WScript.Quit
End If
Dim parentFolder, backupFolder
parentFolder = fso.GetParentFolderName(excelFilePath)
backupFolder = parentFolder & "\backup"
If Not fso.FolderExists(backupFolder) Then
On Error Resume Next
fso.CreateFolder backupFolder
If Err.Number <> 0 Then
MsgBox "backupフォルダを作成できません。" & vbCrLf & Err.Description, vbCritical
WScript.Quit
End If
On Error GoTo 0
End If
'=========================
' バックアップ作成
'=========================
Dim backupPath, baseName, ext, timeStamp
baseName = fso.GetBaseName(excelFilePath)
ext = fso.GetExtensionName(excelFilePath)
timeStamp = Year(Now) & _
Right("0" & Month(Now), 2) & _
Right("0" & Day(Now), 2) & "_" & _
Right("0" & Hour(Now), 2) & _
Right("0" & Minute(Now), 2) & _
Right("0" & Second(Now), 2)
backupPath = backupFolder & "\" & baseName & "_" & timeStamp & "_backup." & ext
On Error Resume Next
fso.CopyFile excelFilePath, backupPath, False
If Err.Number <> 0 Then
MsgBox "バックアップ作成に失敗しました。" & vbCrLf & Err.Description, vbCritical
WScript.Quit
End If
On Error GoTo 0
'=========================
' Excel起動
'=========================
On Error Resume Next
Set xlApp = CreateObject("Excel.Application")
If Err.Number <> 0 Then
MsgBox "Excelを起動できません。" & vbCrLf & Err.Description, vbCritical
WScript.Quit
End If
On Error GoTo 0
xlApp.Visible = False
xlApp.DisplayAlerts = False
' ブックを開く
On Error Resume Next
Set wb = xlApp.Workbooks.Open(excelFilePath)
If Err.Number <> 0 Then
MsgBox "Excelファイルを開けません。" & vbCrLf & Err.Description, vbCritical
xlApp.Quit
WScript.Quit
End If
On Error GoTo 0
'=========================
' .bas フォルダ確認
'=========================
If Not fso.FolderExists(basFolderPath) Then
MsgBox ".basフォルダが存在しません。" & vbCrLf & basFolderPath, vbCritical
wb.Close False
xlApp.Quit
WScript.Quit
End If
Set folder = fso.GetFolder(basFolderPath)
'=========================
' モジュール置き換え
'=========================
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Name)) = "bas" Then
Dim moduleName, comp, importedComp
moduleName = fso.GetBaseName(file.Name)
' 同名モジュール削除
For Each comp In wb.VBProject.VBComponents
If comp.Name = moduleName Then
wb.VBProject.VBComponents.Remove comp
Exit For
End If
Next
' インポート
Set importedComp = wb.VBProject.VBComponents.Import(file.Path)
' ★ モジュール名を bas ファイル名に強制変更
importedComp.Name = moduleName
importedCount = importedCount + 1
End If
Next
'=========================
' 保存・終了
'=========================
wb.Save
wb.Close False
xlApp.Quit
MsgBox "処理が完了しました。" & vbCrLf & _
"バックアップ保存先:" & vbCrLf & backupPath & vbCrLf & vbCrLf & _
"インポートしたモジュール数:" & importedCount, vbInformation
' 後始末
Set folder = Nothing
Set fso = Nothing
Set wb = Nothing
Set xlApp = Nothing
7. ハマりどころ・注意点
- bas ファイルは Shift-JIS で保存する
- UTF-8 だと日本語コメントが文字化けする
- Excel 側のセキュリティ設定が必須
- 実行中に xlsm を開いてはいけない
8.実行確認
空のエクセルを用意。


モジュールが何も登録されていない。
フォルダにbasファイルを配置。


スクリプトを実行。

実行結果をメッセージ表示
⇒反映されたことを確認。

文字化けもなし。
「backup」フォルダも自動作成され、ファイルが退避されています。

9.まとめ
VBS を使うことで、以下を実現しました。
- VBA資産をコードとして管理できる
(変更管理ができる) - 手作業による事故を防げる
- 配布・更新が非常に楽になる
Excel VBA を「属人化させない」、またAIを活用して業務改善を行うための
シンプルかつ強力な仕組みとしておすすめできるものになったかなと思います。
Discussion