「Gemini CLI」によるExcel自動化フレームワーク:実践ガイド
Gemini CLIは、Googleが開発したAI開発支援ツールであり、2025年6月25日(米国時間)に正式に発表されました。
翌26日には、一般ユーザー向けに無料のプレビュー版の提供が開始され、実際に利用できる環境が整いました。
開発者は自然言語で指示を出すことで、コードの生成や修正、スクリプトの自動作成といった作業を、手軽に実行することが可能です。
プレビュー版では、1日あたり最大1,000リクエストまでという制限付きながらも、試用に適した環境が提供されています。
以下に示すのは、その実験的取り組みの結果です。
なお、本検証はあくまでプレビュー版の段階で提供されている機能を用いたものであり、「どこまで実用に耐えるか?」を探る試験的な検証である点をご理解ください。
1. はじめに:本稿が取り組む課題
2. フレームワークの目的:専門知識からの解放
- ユーザー(あなた)の責任領域:
ビジネスの文脈で「何を」自動化したいかを定義すること。その手段は、PowerShellやVBAのコードではなく、日々の業務で使う自然言語です。
- フレームワークの責任領域:
あなたが定義した「何を」に基づき、「どうやって」それを実現するかを解決すること。AIがあなたの指示を解釈してコードを生成し、実行エンジンがそれを安全に動かします。
- 自動化開発の民主化
プログラミングスキルを持たない業務専門家が、自らのアイデアを直接、自動化という形にできる環境を目指します。現場の課題を最もよく知る人物が、最も効果的な解決策を自ら生み出せるようにします。
- 驚異的なアジリティの実現
新しい自動化タスクの作成や、急な仕様変更への対応が、数日を要するコード開発ではなく、数分で完了する「指示書の修正」で済むようにします。これにより、ビジネスの速度に即応できる開発サイクルを目指します。
- 「読む」ための仕様書
自動化ロジックが、専門家でなくとも誰にでも読める「日本語の文章」として設定ファイル内に記録されるようにします。これにより、設定ファイルそのものが「生きた仕様書」となり、業務の可視性と保守性を劇的に高めることを目指します。
3. アーキテクチャ
3.1. プロセスフロー図

処理ステップ | 詳細 |
設定ファイル読み込み | JSONファイルからExcelファイルパス、タスク指示などを取得し、変数に展開します。 |
VBAモジュールエクスポート | 指定されたVBAモジュールを、元のShift-JIS形式のまま.sjis.basファイルとして一時的にエクスポートします。 |
改行マーカー処理(Pre-process) | エクスポートしたコードを読み込み、全ての改行コードを特殊なマーカー(例: ::)に置換します。 これはAIが改行を失う問題への対策です。 |
プロンプト組み立て | マーカー置換済みのコードと設定ファイルの変更依頼を組み合わせ、「マーカーを維持したまま修正せよ」という指示を含むプロンプトを生成します。 |
Gemini API呼び出し | 組み立てたプロンプトをGemini AIに送信し、修正指示を実行させます。 AIはマーカー付きのコードをテキストとして返却します。 |
改行復元処理(Post-process) | AIから返されたテキスト内のマーカー(::)を、Windowsの改行コード(CRLF)に再置換します。 これにより、正しいフォーマットのコードが復元されます。 |
修正VBAコードの一時保存 | 復元したコードを、後続処理のためにUTF-8形式の最終ファイル(例: .final.utf8.bas)として保存します。 |
インポート用ファイルへ変換 | Excelへのインポートで文字化けが起きないよう、UTF-8形式のファイルをShift-JIS形式のファイル(例: .final.sjis.bas)に変換します。 |
既存モジュール削除 | Excelワークブック内の既存VBAモジュールを削除し、古いコードを完全に除去します。 |
修正モジュール再インポート | 最終的に生成されたShift-JIS形式のファイルをExcelワークブックに再インポートします。 |
Excel終了 | ワークブックを保存してクローズし、COMオブジェクトを解放してプロセスを終了します。 |
3.2. 主要コンポーネントの役割
コンポーネント | 役割 | 説明 |
Gemini AI と gemini-cli | 頭脳 と 通信機 | 「Gemini AI」は、コードを生成するクラウド上の核となる知能です。 「gemini-cli」は、そのAIと通信するためにローカルPCで実行される専用のコマンドラインツールです。 実行エンジンは「gemini-cli」を呼び出して、プロンプトの送信と生成されたスクリプトの受信を行います。 |
config.json | 司令書 / ヒューマン・マシン・インターフェース | 人間とAIをつなぐ唯一の接点です。 このファイルの"description"に記述される自然言語の質と明確さが、生成される自動化の品質を直接決定します。 |
Run-Automation.ps1 | 実行エンジン (The How) | オーケストレーターとして、プロセス全体の制御を担います。 「gemini-cli」の呼び出しを含め、一連の定型的な「作業」をすべて自動で行います。 |
3.3. 文字コード戦略:なぜShift-JISとUTF-8を使い分けるのか
- 担当領域: Microsoft ExcelのVBA環境との入出力
- 理由: ExcelのVBAエディタで作成・保存されたVBAコード(特に日本語を含む場合)は、伝統的にShift-JISでエンコードされています。VBAモジュールを
Export したり、外部から Import したりする際に、文字化けを防ぎ、最も確実に動作する形式がShift-JISです。本フレームワークでは、このExcel
VBAの世界の作法を尊重するために、モジュールのエクスポート時と、最終的なインポート時にはShift-JISを扱います。
- 担当領域: Gemini AIとの通信および、PowerShell内部での処理
- 理由: Gemini AIをはじめとする現代的なWebサービスや開発ツールは、世界標準であるUTF-8を前提として設計されています。Shift-JISのままのコードをAIに渡してしまうと、日本語部分が正しく解釈されず、文字化けや予期せぬエラーの根本原因となります。このAIの世界の作法に対応するため、AIに処理を依頼する前の段階で、一度すべてのデータをUTF-8に変換しています。
4. 環境構築とインストール手順
4.1. Gemini CLI のインストールと設定
Gemini CLIの徹底解説:AIをターミナルから使いこなす
4.2 PowerShell 7 (pwsh.exe) の利用推奨とインストール
旧バージョンの場合は、PowerShellを起動すると以下のメッセージが表示されます。

PowerShell 7のインストール手順:
- Microsoft Storeからのインストール(推奨):
Microsoft Storeを開き、「PowerShell」と検索します。「PowerShell」アプリを見つけ、「入手」または「インストール」をクリックします。Store版は自動更新され、Pathも適切に設定されるため、最も簡単な方法です。 - Winget (Windows パッケージマネージャー) を利用したインストール:
管理者権限でPowerShell (Windows PowerShellまたはPowerShell 7) を起動し、以下のコマンドを実行します。
winget install --id Microsoft.PowerShell --source winget
- GitHubからの直接ダウンロード:
PowerShellの公式GitHubリリースぺージ (https://github.com/PowerShell/PowerShell/releases) にアクセスし、最新の安定版(LTS版が推奨されます)の `.msi` インストーラーをダウンロードし、実行します。
- PowerShell 7が起動している場合:
または
pwsh -v
Get-Host | Select-Object Version
- Windows PowerShell (5.1) が起動している場合:
または
powershell -v
Get-Host | Select-Object Version
- コマンドプロンプトからの直接起動:
またはフルパス (例:
pwsh.exe
)。C:\Program Files\PowerShell\7\pwsh.exe
- バッチファイルからの起動: 詳細は後述の「5.3. スクリプトの実行」セクションを参照してください。
4.3 Excelのセキュリティ設定(トラストセンター)の確認
- Excelを開き、「ファイル」タブから「オプション」をクリックします。
- 「Excelのオプション」ダイアログで「トラストセンター」を選択し、「トラストセンターの設定」をクリックします。
- 「トラストセンター」ダイアログで「マクロの設定」を選択します。
- 「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」という項目にチェックが入っていることを確認してください。
このチェックがないと、PowerShellからのVBA操作がブロックされ、スクリプトがエラーになる場合があります。 - また、「警告を表示してすべてのマクロを無効にする」など、マクロの実行に関する設定も組織のポリシーに合わせて適切に設定してください。
5. フレームワークの実行手順
5.1. 推奨されるフォルダとファイルの配置
│
├─ Run-Automation.ps1 (汎用実行エンジン)
│
└── Tasks\
│
└── VbaRefactor\ (「VBAリファクタリング」タスク用のフォルダ)
│
├─ config.json (このタスクの具体的な指示書)
│
└─ SampleBook.xlsm (このタスクの操作対象ファイル)
│
└── Tasks\
│
└── VbaRefactor\
│
└─ Output\ (VbaRefactorタスクの出力先フォルダ)
│
├─ gemini_prompt.txt (AIへの送信プロンプトを記録したファイル)
│
├─ gemini_raw_response.txt (AIからの生の応答を記録したファイル)
│
├─ Module1.sjis.bas (Excelからエクスポートされた元のSJISファイル)
│
├─ Module1.final.utf8.bas (AIの応答を復元した中間UTF-8ファイル)
│
├─ Module1.final.sjis.bas (Excelインポート用の最終SJISファイル)
│
└─ vba_refactor_log.txt (実行ログ)
- BATファイル (.bat):
バッチファイルは通常、OSのデフォルトエンコーディング(日本では`ANSI`または`Shift-JIS`)で保存する必要があります。`UTF-8`で保存すると、コマンドが正しく認識されないエラーが発生する場合があります。
- PowerShellスクリプト (.ps1), JSONファイル (.json), テキストファイル (.txt):
これらのファイルは、`UTF-8(BOM 付き)`で保存することを強く推奨します。当初は`UTF-8(BOMなし)`を推奨していましたが、実際の検証過程でPowerShell環境(特にWindows PowerShell)では、`BOM付き`の方が文字化けや構文解析エラーを未然に防ぎ、安定して動作することが確認されました。
5.2. config.json の編集
※日本語を使う場合は文字コードに注意。UTF-8(BOM 付き)で保存すること。
5.3. スクリプトの実行
以下の内容をテキストエディタに貼り付け、`RunAutomation.bat` という名前で**文字コードを`ANSI`または`Shift-JIS`に設定して保存**します。保存場所は、デスクトップなど、ダブルクリックしやすい場所で構いません。
@echo off
REM PowerShellスクリプトのルートディレクトリに移動
cd /d "C:\AutomationFramework"
REM PowerShell 7 (pwsh.exe) スクリプトを実行
REM -NoProfile: プロファイルスクリプトを実行しない(起動を速くする)
REM -ExecutionPolicy Bypass: スクリプトの実行ポリシーを一時的にバイパスする(スクリプト実行を許可)
REM -File: 実行するスクリプトファイルを指定
REM -ConfigFile: Run-Automation.ps1のパラメータにconfig.jsonのパスを渡す
REM PowerShellのコマンド全体を二重引用符で囲むことで、BATファイルがPowerShellの引数を誤って解釈するのを防ぎます。
REM PowerShell Core (pwsh.exe) を呼び出し、PowerShellスクリプトを実行
pwsh.exe -Command "& {.\Run-Automation.ps1 -ConfigFile '.\Tasks\VbaRefactor\config.json'}"
REM 実行終了後、ウィンドウを閉じる前に一時停止する場合(オプション)
rem pause
BATファイルの解説:
- `@echo off`: バッチファイルのコマンド表示を抑制します。
- `cd /d "C:\AutomationFramework"`: スクリプトの実行ディレクトリをフレームワークのルートフォルダに移動します。`/d` オプションはドライブ変更も同時に行います。
- `pwsh.exe -Command "& { ... }"`: ここでPowerShell 7 (`pwsh.exe`)
を呼び出し、その後ろに続く文字列をPowerShellのコマンドとして実行させます。
- `-Command`: PowerShellに対して、引数として渡された文字列をコマンドとして実行するよう指示します。
- `"& { ... }"`: PowerShellのスクリプトブロックです。この中に実行したいPowerShellコマンドを記述します。`&` (呼び出し演算子) を使うことで、スクリプトブロック内のコマンドを実行できます。
- `-ConfigFile '.\Tasks\VbaRefactor\config.json'`: `Run-Automation.ps1` に渡すパラメータです。シングルクォートで囲むことで、PowerShellスクリプトブロック内での文字列として扱われます。
- `rem pause`: コメントアウトされており、デフォルトでは実行後すぐにウィンドウが閉じます。もし実行結果を確認したい場合は `rem` を削除して有効にしてください。
PowerShellコンソールからの直接実行(参考):
# フレームワークのルートフォルダに移動
cd C:\AutomationFramework
# 実行コマンド
.\Run-Automation.ps1 -ConfigFile ".\Tasks\VbaRefactor\config.json"
6. 実践サンプルケース:VBAの自動リファクタリング
6.1. 準備するExcelファイル (SampleBook.xlsm) の内容
- ファイル名: SampleBook.xlsm
- シート: Sheet1 という名前のシートを1枚用意します。(中身は空で構いません)
- VBA: 以下のコードを含む Module1 という名前の標準モジュールを1つ作成します。
このファイルが、自動化の「材料」となります。Option Explicit Sub SayHello_Old() Dim msg As String msg = "Hello from AI-modified VBA!" Sheet1.Range("A1").Value = msg Range("A2") = "できるかな?" End Sub Sub test_sample() Dim i As Long With ActiveSheet For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row .Cells(i, 2).Value = i & "行目" Next End With End Sub
- 保存フォルダは、指示書ファイル (config.json) に記載する場所。
"C:\\AutomationFramework\\Tasks\\VbaRefactor\\SampleBook.xlsm"
6.2. 指示書ファイル (config.json) の内容
- excelFilePath: 上記で用意したSampleBook.xlsmへのフルパスを指定します。
- description: AIに実行させたいタスクを、日本語でステップバイステップで記述します。
{
"environment": {
"geminiApiKeyEnvName": "GEMINI_API_KEY",
"excelFilePath": "C:\\AutomationFramework\\Tasks\\VbaRefactor\\SampleBook.xlsm",
"exportFolderPath": "C:\\AutomationFramework\\Tasks\\VbaRefactor\\Output\\",
"logFileName": "vba_refactor_log.txt"
},
"task": {
"moduleName": "Module1",
"description": "以下のVBAコードを修正してください。注意点として、あなたは元のコードの改行をすべて失い、1行の文字列として認識してしまいます。そこで、修正処理が完了した後、VBAの文法として正しくなるように、各ステートメントの末尾に適切な改行を挿入し、完全なフォーマットのコードとして出力してください。\n1. プロシージャ名「Sub SayHello_Old()」を「Sub SayHello_New()」に変更\n2. メッセージ文字列「Hello from original VBA.」を「Hello from AI-modified VBA!」に変更"
},
"mockMode": false
}
6.3. サンプルケースの実行手順
- 前提:フレームワークの環境構築
- レポートの4章に従い、gemini-cliのインストールとAPIキーの環境変数への設定が完了していることを確認します。
- PowerShell 7 (pwsh.exe) のインストールと起動設定が完了していることを確認します。
- Excelのトラストセンター設定で「VBA プロジェクト オブジェクト モデルへのアクセスを信頼する」にチェックが入っていることを確認します。
- フォルダとファイルの準備
- レポートの5.1章で推奨されている構成に従い、C:\AutomationFramework\Tasks\VbaRefactor\ のようなフォルダを作成します。
- その中に、6.1章で定義した内容で SampleBook.xlsm を、6.2章で定義した内容で config.json をそれぞれ作成・保存します。
- 各ファイルの文字コードが、「5.1. 推奨されるフォルダとファイルの配置」の指示に従っていることを必ず確認してください。 (例: BATファイルはANSI/Shift-JIS、PS1/JSON/TXTはUTF-8
BOM付き)
- config.jsonのパス確認
- 作成した config.json ファイルを開き、excelFilePath の値が、ステップ2で保存した SampleBook.xlsm の実際のフルパスと一致していることを必ず確認してください。
- 作成した config.json ファイルを開き、excelFilePath の値が、ステップ2で保存した SampleBook.xlsm の実際のフルパスと一致していることを必ず確認してください。
- 自動化の実行
- 作成した `RunAutomation.bat` ファイルをダブルクリックして実行します。
- 作成した `RunAutomation.bat` ファイルをダブルクリックして実行します。
6.4. 実行後の結果
実行エンジンは、config.jsonの指示と元のVBAコードを元にプロンプトを組み立て、AIに送信します。AIから返却された修正済みコードのテキストを、実行エンジンが責任を持って前後のエンコーディング変換や改行コードの整形を行い、最終的にExcelに適用します。
最終的に、SampleBook.xlsmは以下のように変更されます。
- VBA: Module1のコードが、指示通りに書き換えられます。
Module1 のVBAコード(修正後)
Option Explicit Sub SayHello_New() Dim msg As String msg = "Hello from AI-modified VBA!" Sheet1.Range("A1").Value = msg Range("A2") = "できるかな?" End Sub Sub test_sample() Dim i As Long With ActiveSheet For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row .Cells(i, 2).Value = i & "行目" Next End With End Sub
- 実行後の結果としては、SampleBook.xlsmを開くと、Module1のVBAコードが指示通りに書き換えられていることが確認できます。
この一連のプロセスが、ユーザーの操作なしに、config.jsonの指示だけで完結します。これが本フレームワークが提供する自動化の力です。

6.5 exportFolderに作成されるファイル
実践サンプルで実際に作成された内容。
以下のVBAコードを、指示通りに修正してください。
注意点として、コード内の「::」という文字列は改行を意味する特殊なマーカーです。
このマーカー「::」を絶対に削除したり変更したりせず、そのまま維持して、修正後のコード全文のみを出力してください。
修正指示:
1. プロシージャ名「Sub SayHello_Old()」を「Sub SayHello_New()」に変更してください。
2. メッセージ文字列「Hello from original VBA.」を「Hello from AI-modified VBA!」に変更してください。
修正対象のコード:
Attribute VB_Name = "Module1"::Option Explicit::::Sub SayHello_Old():: Dim msg As String:: msg = "Hello from AI-modified VBA!":: Sheet1.Range("A1").Value = msg:: Range("A2") = "できるかな?"::End Sub::::Sub test_sample():: Dim i As Long:: With ActiveSheet:: For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row:: .Cells(i, 2).Value = i & "行目":: Next:: End With::End Sub::
[INFO] Your configured model (gemini-2.5-pro) was temporarily unavailable. Switched to gemini-2.5-flash for this session.
Attribute VB_Name = "Module1"::Option Explicit::::Sub SayHello_New():: Dim msg As String:: msg = "Hello from AI-modified VBA!":: Sheet1.Range("A1").Value = msg:: Range("A2") = "できるかな?"::End Sub::::Sub test_sample():: Dim i As Long:: With ActiveSheet:: For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row:: .Cells(i, 2).Value = i & "行目":: Next:: End With::End Sub::
[INFO] Your configured model (gemini-2.5-pro) was temporarily unavailable. Switched to gemini-2.5-flash for this session
これは、設定していたAIモデル(gemini-2.5-pro)が、リクエストを送信したタイミングで一時的に利用できなかった(例: サーバーが混雑していた、など)ため、代わりに別の利用可能なモデル(gemini-2.5-flash)に自動的に切り替えて処理を続行した、ということを意味します。
ーで停止するのではなく、代替モデルで処理を成功させてくれる機能です。
Attribute VB_Name = "Module1"
Option Explicit
Sub SayHello_Old()
Dim msg As String
msg = "Hello from AI-modified VBA!"
Sheet1.Range("A1").Value = msg
Range("A2") = "できるかな?"
End Sub
Sub test_sample()
Dim i As Long
With ActiveSheet
For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row
.Cells(i, 2).Value = i & "行目"
Next
End With
End Sub
Module1.final.sjis.bas (Excelインポート用の最終SJISファイル)
Attribute VB_Name = "Module1"
Option Explicit
Sub SayHello_New()
Dim msg As String
msg = "Hello from AI-modified VBA!"
Sheet1.Range("A1").Value = msg
Range("A2") = "できるかな?"
End Sub
Sub test_sample()
Dim i As Long
With ActiveSheet
For i = 1 To .Cells(.Rows.Count, 1).End(xlUp).Row
.Cells(i, 2).Value = i & "行目"
Next
End With
End Sub
[2025-07-01 15:39:25] [INFO] 自動化プロセスを開始します
[2025-07-01 15:39:25] [INFO] Excelを起動し、モジュールをエクスポートします...
[2025-07-01 15:39:29] [SUCCESS] モジュール 'Module1' のエクスポートが完了しました: C:\AutomationFramework\Tasks\VbaRefactor\Output\Module1.sjis.bas
[2025-07-01 15:39:29] [INFO] ファイルを読み込み、改行をマーカー'::'に置換します...
[2025-07-01 15:39:29] [SUCCESS] 改行のマーカーへの置換が完了しました。
[2025-07-01 15:39:29] [INFO] AIへのプロンプト(マーカー使用)を組み立てます...
[2025-07-01 15:39:29] [INFO] AIへのプロンプトをファイルに出力します: C:\AutomationFramework\Tasks\VbaRefactor\Output\gemini_prompt.txt
[2025-07-01 15:39:29] [SUCCESS] プロンプトのファイル出力が完了しました。
[2025-07-01 15:39:29] [INFO] Gemini APIを呼び出し、修正後のコードの返却を依頼します...
[2025-07-01 15:39:45] [INFO] Geminiからの生の応答をファイルに出力します: C:\AutomationFramework\Tasks\VbaRefactor\Output\gemini_raw_response.txt
[2025-07-01 15:39:45] [SUCCESS] 生の応答のファイル出力が完了しました。
[2025-07-01 15:39:45] [INFO] AIからの応答を検証しています...
[2025-07-01 15:39:45] [SUCCESS] AIからの応答の基本検証に成功しました。
[2025-07-01 15:39:45] [SUCCESS] Geminiからマーカー付きの修正コードを正常に受信しました。
[2025-07-01 15:39:45] [INFO] 受信した応答を整形して、ファイルに保存します...
[2025-07-01 15:39:45] [INFO] 後処理のため、VBAコードを一時ファイルに保存します...
[2025-07-01 15:39:45] [SUCCESS] 一時ファイルとして保存が完了しました: C:\AutomationFramework\Tasks\VbaRefactor\Output\Module1.final.utf8.bas
[2025-07-01 15:39:46] [INFO] Excelへのインポート用に、ファイルをShift-JISに変換します...
[2025-07-01 15:39:46] [SUCCESS] インポート用Shift-JISファイルの準備が完了しました: C:\AutomationFramework\Tasks\VbaRefactor\Output\Module1.final.sjis.bas
[2025-07-01 15:39:46] [INFO] 修正されたモジュール(Shift-JIS)をExcelに再インポートします...
[2025-07-01 15:39:46] [SUCCESS] モジュールの再インポートとリネームが完了しました。
[2025-07-01 15:39:46] [INFO] クリーンアップ処理を実行します...
[2025-07-01 15:39:49] [INFO] すべての自動化プロセスが完了しました。
7. 主要コンポーネントの全コード
7.1. 設定ファイル (config.json)
{
"environment": {
"geminiApiKeyEnvName": "GEMINI_API_KEY",
"excelFilePath": "C:\\AutomationFramework\\Tasks\\VbaRefactor\\SampleBook.xlsm",
"exportFolderPath": "C:\\AutomationFramework\\Tasks\\VbaRefactor\\Output\\",
"logFileName": "vba_refactor_log.txt"
},
"task": {
"moduleName": "Module1",
"description": "以下のVBAコードを修正してください。注意点として、あなたは元のコードの改行をすべて失い、1行の文字列として認識してしまいます。そこで、修正処理が完了した後、VBAの文法として正しくなるように、各ステートメントの末尾に適切な改行を挿入し、完全なフォーマットのコードとして出力してください。\n1. プロシージャ名「Sub SayHello_Old()」を「Sub SayHello_New()」に変更\n2. メッセージ文字列「Hello from original VBA.」を「Hello from AI-modified VBA!」に変更"
},
"mockMode": false
}
使用する場合は内容を書き換えて使用してください。
7.2. 汎用実行エンジン (Run-Automation.ps1)
# ===================================================================
# Gemini x PowerShell 汎用自動化実行エンジン
# バージョン: 16.0 (最終完成版)
# ===================================================================
param (
[Parameter(Mandatory=$true)]
[string]$ConfigFile
)
# --- 1. 設定ファイルの読み込み ---
Write-Host "INFO: 設定ファイルを読み込んでいます: $ConfigFile"
if (-not (Test-Path $ConfigFile)) {
Write-Host "ERROR: 設定ファイルが見つかりません。";
exit 1
}
$Config = Get-Content -Path $ConfigFile -Raw -Encoding UTF8 | ConvertFrom-Json
# 設定値の取得
$excelFilePath = $Config.environment.excelFilePath
$exportFolderPath = $Config.environment.exportFolderPath
$moduleName = $Config.task.moduleName
$taskDescription = $Config.task.description
# パスの構築
$logFilePath = Join-Path $exportFolderPath "vba_refactor_log.txt"
$exportedSjisFilePath = Join-Path $exportFolderPath "$($moduleName).sjis.bas"
$finalUtf8FilePath = Join-Path $exportFolderPath "$($moduleName).final.utf8.bas" # AIが生成したコードの一時保存場所
$finalSjisFilePath = Join-Path $exportFolderPath "$($moduleName).final.sjis.bas" # Excelインポート用SJISファイル
# --- 2. ログ出力の準備 ---
if (-not (Test-Path $exportFolderPath)) {
New-Item -ItemType Directory -Path $exportFolderPath -Force | Out-Null
}
function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] [$Level] $Message"
Write-Host $logEntry
Add-Content -Path $logFilePath -Value $logEntry -Encoding UTF8
}
# --- 3. メイン処理 ---
Write-Log "自動化プロセスを開始します" "INFO"
$excel = $null; $workbook = $null;
try {
# --- ステップ1: ExcelからSJIS形式の.basファイルをエクスポート ---
Write-Log "Excelを起動し、モジュールをエクスポートします..." "INFO"
$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false
$workbook = $excel.Workbooks.Open($excelFilePath)
$vbProject = $workbook.VBProject
$vbModule = $vbProject.VBComponents.Item($moduleName)
$vbModule.Export($exportedSjisFilePath)
Write-Log "モジュール '$moduleName' のエクスポートが完了しました: $exportedSjisFilePath" "SUCCESS"
# --- ステップ2: .basファイルを読み込み、改行をマーカー"::"に置換 ---
Write-Log "ファイルを読み込み、改行をマーカー'::'に置換します..." "INFO"
$sjisEncoding = [System.Text.Encoding]::GetEncoding("Shift_JIS")
$originalContent = [System.IO.File]::ReadAllText($exportedSjisFilePath, $sjisEncoding)
$markedContent = ($originalContent -replace "`r`n", "::") -replace "`n", "::"
Write-Log "改行のマーカーへの置換が完了しました。" "SUCCESS"
# --- ステップ3: AIへのプロンプトを組み立て、マーカーの維持を指示 ---
Write-Log "AIへのプロンプト(マーカー使用)を組み立てます..." "INFO"
$geminiPrompt = @"
以下のVBAコードを、指示通りに修正してください。
注意点として、コード内の「::」という文字列は改行を意味する特殊なマーカーです。
このマーカー「::」を絶対に削除したり変更したりせず、そのまま維持して、修正後のコード全文のみを出力してください。
修正指示:
$taskDescription
修正対象のコード:
$markedContent
"@
# --- AIへのプロンプトをファイルに出力 ---
$promptFilePath = Join-Path $exportFolderPath "gemini_prompt.txt"
Write-Log "AIへのプロンプトをファイルに出力します: $promptFilePath" "INFO"
try {
# プロンプトをUTF-8でファイルに書き込む
[System.IO.File]::WriteAllText($promptFilePath, $geminiPrompt, [System.Text.Encoding]::UTF8)
Write-Log "プロンプトのファイル出力が完了しました。" "SUCCESS"
} catch {
Write-Log "プロンプトのファイル出力中にエラーが発生しました: $($_.Exception.Message)" "ERROR"
}
Write-Log "Gemini APIを呼び出し、修正後のコードの返却を依頼します..." "INFO"
# --- エンコーディングを正しく扱うためのラッパー ---
$originalConsoleEncoding = [Console]::OutputEncoding
$originalOutputEncoding = $OutputEncoding
try {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8
$rawResponse = $geminiPrompt | gemini
# --- デバッグ情報出力 ---
Write-Host "DEBUG: rawResponseの型: $($rawResponse.GetType().FullName)"
Write-Host "DEBUG: rawResponseの要素数: $($rawResponse.Count)" # 配列かどうかチェック用
# --- 配列の場合は改行付きで結合 ---
if ($rawResponse -is [System.Array]) {
$rawResponse = $rawResponse -join "`n"
}
# --- Geminiからの生の応答をファイルに出力 ---
$rawResponseFilePath = Join-Path $exportFolderPath "gemini_raw_response.txt"
Write-Log "Geminiからの生の応答をファイルに出力します: $rawResponseFilePath" "INFO"
try {
# 生の応答をUTF-8でファイルに書き込む
[System.IO.File]::WriteAllText($rawResponseFilePath, $rawResponse, [System.Text.Encoding]::UTF8)
Write-Log "生の応答のファイル出力が完了しました。" "SUCCESS"
} catch {
Write-Log "生の応答のファイル出力中にエラーが発生しました: $($_.Exception.Message)" "ERROR"
}
# --- 応答内容のログ(安全にSubstring) ---
if ($rawResponse.Length -ge 150) {
$logDetailResponse = "AIからの実際の応答(先頭150文字): $($rawResponse.Substring(0, 150))"
} else {
$logDetailResponse = "AIからの実際の応答(全文): $rawResponse"
}
# --- ここからが新しい検証ブロック ---
Write-Log "AIからの応答を検証しています..." "INFO"
# AI応答のログ出力をより堅牢にする
$logDetailResponse = ""
if ([string]::IsNullOrWhiteSpace($rawResponse)) {
$logDetailResponse = "AIからの応答が空またはNullです。"
} else {
$logDetailResponse = "AIからの実際の応答(先頭150文字): $($rawResponse.Substring(0, [System.Math]::Min(150, $rawResponse.Length)))"
}
# チェック1: 応答にMarkdownブロックマーカーが含まれていないか?これはステップ4で対応
# チェック2: 応答に改行マーカー'::'が含まれているか?
$validationMarker = "::"
if (-not ($rawResponse -like "*$validationMarker*")) {
Write-Host 'ERROR: 改行マーカーが含まれていません。処理を終了します。' -ForegroundColor Red
Write-Log '改行マーカーが含まれていません。処理を終了します。' "ERROR"
Write-Log $logDetailResponse "DETAIL"
exit 1
}
Write-Log "AIからの応答の基本検証に成功しました。" "SUCCESS"
# --- ここまでが新しい検証ブロック ---
if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($rawResponse)) {
throw "Geminiコマンドの実行に失敗、または応答が空です。"
}
Write-Log "Geminiからマーカー付きの修正コードを正常に受信しました。" "SUCCESS"
} finally {
[Console]::OutputEncoding = $originalConsoleEncoding
$OutputEncoding = $originalOutputEncoding
}
# --- ラッパー終了 ---
# ===================================================================
# --- ステップ4: 受信したコードを整形し、UTF-8ファイルとして一時保存 ---
# ===================================================================
Write-Log "受信した応答を整形して、ファイルに保存します..." "INFO"
# --- 1. すべての改行をマーカー'::'に統一 ---
# 応答に含まれる通常の改行(CRLF/LF)も'::'に置換し、区切り文字を一本化します。
$unifiedResponse = $rawResponse -replace "`r?`n", '::'
# --- 2. 整形処理 ---
# 統一されたマーカー'::'で応答を分割
$lines = $unifiedResponse -split '::'
# 不要な行(空行、INFO行、Markdownマーカー)をまとめて除去します。
$contentLines = $lines | Where-Object {
$line = $_.Trim()
(-not $line.StartsWith('[INFO]')) -and `
($line -ne '```vba') -and `
($line -ne '```')
}
# --- 3. 最終的なコンテンツの作成 ---
# 整形後の行配列を通常の改行コードで結合します。
$finalContent = ($contentLines -join "`r`n").Trim()
Write-Log "後処理のため、VBAコードを一時ファイルに保存します..." "INFO"
$utf8Encoding = [System.Text.Encoding]::UTF8
[System.IO.File]::WriteAllText($finalUtf8FilePath, $finalContent, $utf8Encoding)
Write-Log "一時ファイルとして保存が完了しました: $finalUtf8FilePath" "SUCCESS"
# ===================================================================
# --- ステップ5: インポート用にUTF-8ファイルをShift-JISに変換 ---
Write-Log "Excelへのインポート用に、ファイルをShift-JISに変換します..." "INFO"
$fileContent = [System.IO.File]::ReadAllText($finalUtf8FilePath, $utf8Encoding)
[System.IO.File]::WriteAllText($finalSjisFilePath, $fileContent, $sjisEncoding)
Write-Log "インポート用Shift-JISファイルの準備が完了しました: $finalSjisFilePath" "SUCCESS"
# --- ステップ6: 生成した最終Shift-JISファイルをExcelにインポート ---
Write-Log "修正されたモジュール(Shift-JIS)をExcelに再インポートします..." "INFO"
$vbProject.VBComponents.Remove($vbModule)
$newModule = $vbProject.VBComponents.Import($finalSjisFilePath)
$newModule.Name = $moduleName
Write-Log "モジュールの再インポートとリネームが完了しました。" "SUCCESS"
} catch {
Write-Log "処理中にエラーが発生しました: $($_.Exception.Message)" "ERROR"
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
} finally {
# --- ステップ7: 後片付け ---
Write-Log "クリーンアップ処理を実行します..." "INFO"
if ($excel -ne $null) {
if ($workbook -ne $null) {
$workbook.Close($true)
}
$excel.Quit()
}
if ($vbModule -ne $null) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($vbModule) | Out-Null }
if ($vbProject -ne $null) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($vbProject) | Out-Null }
if ($workbook -ne $null) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($workbook) | Out-Null }
if ($excel -ne $null) { [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null }
[System.GC]::Collect(); [System.GC]::WaitForPendingFinalizers()
}
# 最終的な完了メッセージをtry/finallyブロックの外に移動
Write-Log "すべての自動化プロセスが完了しました。" "INFO"
※日本語を使う場合は文字コードに注意。UTF-8(BOM 付き)で保存すること。
- 設定ファイルの読み込み:
起動時に-ConfigFileで指定されたconfig.jsonを読み込み、対象のExcelファイルパス、VBAモジュール名、AIへの修正指示などの設定を取得します。 - VBAモジュールのエクスポート:
指定されたExcelファイルをバックグラウンドで開き、対象のVBAモジュールをテキストファイル(.bas)としてPC上に書き出します。 - プロンプトの組み立て:
エクスポートしたVBAコードの改行を、AIが誤認しないように特殊なマーカー(::)に全て置換します。このマーカー付きコードとconfig.jsonからの修正指示を組み合わせ、最終的なプロンプトを生成します。 - AIによるコード修正:
組み立てたプロンプトをgemini-cliコマンドに渡し、AIによって修正されたVBAコード(マーカー付き)を受け取ります。 - 応答データの整形・保存:
AIからの応答に含まれる不要な情報([INFO]ヘッダーやMarkdownのコード囲み```など)を削除し、純粋なVBAコードのみを抽出します。この際、デバッグ用にAIへのプロンプトとAIからの生の応答も、それぞれテキストファイルに保存します。 - 修正コードのExcelへの再インポート:
- 整形したコードのマーカー(::)を通常の改行に戻します。
- 元のVBAモジュールをExcelから削除します。
- AIが生成した新しいコードをExcelにインポートし、元のモジュール名に戻して保存します。
- クリーンアップ:
Excelアプリケーションを安全に終了し、すべての処理を完了させます。
8. 対話モードとパイプライン:自動化における「見えざる壁」
- 問題の可視化: ファイルを読み込んで文字化けが発生した際、AIはその結果を画面に表示します。人間はそれを目で見て「文字化けしている」と即座に認識できます。
- 柔軟な軌道修正: 人間は「それはShift-JISだよ」と追加の情報を与えたり、「一度UTF-8に変換したファイルを渡す」といった回避策をその場で実行したりできます。
- 暗黙知の補完: AIの応答が不完全だったり、意図と違ったりした場合でも、人間がその文脈を判断し、「では、こうして」と次の指示を微調整できます。
- 問題の不可視性: AIが内部で改行をすべて削除してしまっても、スクリプトにはその「沈黙のエラー」を検知する手段がありません。返ってきたのが「改行のない一行の文字列」という事実だけを頼りに、原因を推測するしかないのです。
- あらゆる失敗の想定: 文字コードの不一致、改行の欠落、APIの一時的なエラー、AIの応答形式の揺れなど、起こりうる全ての失敗パターンを事前に予測し、それらに対処するロジックをスクリプト内に実装しておく必要があります。一つでも想定外の事態が起きれば、プロセスは即座に破綻します。
- 厳格なルールのみが頼り: 人間のような柔軟な判断は存在しません。スクリプトは、AIが常に100%完璧な、規定通りのデータを返すことを前提として後続の処理を行います。AIがその前提を一つでも破れば(例えば改行を消すなど)、全体のロジックが崩壊します。
対話モード (Interactive Mode) | パイプライン (Pipeline Mode) | |
目的 | 人間との会話 | プログラムによる自動処理 |
使い方 | geminiコマンドを直接実行し、AIとチャット形式でやり取りを続ける。 | (入力データ) | gemini のように、|(パイプ)を使ってデータを一度に渡し、一度に結果を受け取る。 |
特徴 | 試行錯誤や、次に何をするか考えながら進める作業に向いている。文脈をある程度記憶する。 | スクリプトに組み込み、一連の処理を完全に自動化するのに不可欠。入力と出力が明確。 |
今回の例 | 手動でgeminiを起動し、ファイルパスを渡したり、文字化けを指摘したりした操作。 | Run-Automation.ps1が、AIへの指示を|でgeminiコマンドに渡して、修正済みコードを受け取っていた処理。 |
9. セキュリティに関する考慮事項
9.1. 基本的な考慮事項
- APIキーの厳重な管理
config.jsonにAPIキーそのものを書き込むことは絶対に避けてください。APIキーは、意図しない第三者に渡ると不正利用される可能性があります。本レポートで示した通り、環境変数として設定し、その変数名をconfig.jsonで指定する方法を遵守してください。 - プロンプトに含まれる情報
config.jsonのdescriptionに記述された内容は、分析のためにGoogleのサーバーへ送信されます。会社の内部情報、個人情報、パスワードといった機密情報を含めないように徹底してください。 - PowerShell実行ポリシー
開発時には-ExecutionPolicy Bypassが便利ですが、これはスクリプトの実行制限を無効にするため、リスクを伴います。本番環境では、組織のセキュリティポリシーに従い、より安全なRemoteSignedポリシーと、スクリプトへのコード署名を検討してください。
9.2. 追加の重要な考慮事項:AIによるコード生成のリスク
- リスク: 悪意のある、あるいは欠陥のある自然言語指示(プロンプト)により、AIが意図せず危険なVBAコード(例: Kill "C:\*.*" や、FileSystemObjectを使ってファイルを削除するコード)を生成してしまう可能性はゼロではありません。
- 対策:
- 【推奨】人間のレビュー: 重要な業務で利用する場合、生成されたVBAコードのファイル(例: Module1.final.sjis.bas)をExcelにインポートする前に、一度人間の専門家がその内容をレビュー(監査)するステップをプロセスに挟むことを強く推奨します。
- 【推奨】サンドボックス環境: 本番環境とは隔離されたサンドボックス環境を用意し、まずはそこでフレームワークを実行します。その後、生成されたExcelファイルを開き、変更後のマクロを実行して、その挙動(ファイルの書き込み、ネットワークアクセス等)が想定通りであるかを確認するプロセスを設けるべきです。
- リスク: 実行エンジン(Run-Automation.ps1)は、それを実行したユーザーと同じ権限を持ちます。万が一、意図しないコードが生成・実行された場合、そのユーザーがアクセスできる全てのファイルやシステムに影響が及ぶ可能性があります。
- 対策: 可能であれば、このフレームワークを専用のサービスアカウントで実行することを検討してください。そのアカウントには、操作対象のExcelファイルやフォルダへのアクセス権限など、タスク実行に必要な最小限の権限(Principle of Least Privilege)のみを付与します。これにより、万が一の際の被害範囲を限定できます。
- リスク: 「特定のファイル(例: C:\secrets\passwords.txt)の内容を読み取り、外部のWebサイト(例: https://evil-site.com/upload)に送信するコード」を生成するように指示された場合、AIは忠実にそのコードを生成してしまう可能性があります。
- 対策: このフレームワークを実行するサーバーやPCには、ネットワークの出口制御(Egress Filtering)を適用し、組織のポリシーで許可された宛先(例:
社内サーバー群)以外へのHTTP/HTTPS通信をOSやファイアウォールレベルで禁止することが有効です。
10. まとめと展望
- フレームワーク自体の知能化
- 自己修復機能: 生成したスクリプトがエラーで失敗した際、そのエラー内容をAI自身が分析し、コードを自動修正して再試行する、より自律的なエラーハンドリング機構の実現。
- 自動テスト機能: 生成したコードを、本番ファイルに適用する前に、安全なサンドボックス環境で自動的にテスト・検証する仕組みの導入。
- 対話的な自動化構築
- GUIの提供: config.jsonをテキストエディタで書く代わりに、Webフォームやデスクトップアプリ上でAIと対話しながら要件を固め、実行ボタンを押すだけで済むような、よりユーザーフレンドリーなインターフェースの構築。
- GUIの提供: config.jsonをテキストエディタで書く代わりに、Webフォームやデスクトップアプリ上でAIと対話しながら要件を固め、実行ボタンを押すだけで済むような、よりユーザーフレンドリーなインターフェースの構築。
- アプリケーション連携の拡大
- Excelの枠を超えた業務プロセス自動化: 「Outlookの特定メールをトリガーに添付ファイルを読み取り、Excelでデータを集計・加工し、その結果のグラフをPowerPointに貼り付け、要約をTeamsに投稿する」といった、複数のMicrosoft
365アプリケーションを横断する、より高度なシナリオへの挑戦。
- Excelの枠を超えた業務プロセス自動化: 「Outlookの特定メールをトリガーに添付ファイルを読み取り、Excelでデータを集計・加工し、その結果のグラフをPowerPointに貼り付け、要約をTeamsに投稿する」といった、複数のMicrosoft
365アプリケーションを横断する、より高度なシナリオへの挑戦。
- 組織的な展開とガバナンス
- 市民開発者(Citizen Developer)の育成: このフレームワークを組織的に展開し、現場の業務担当者がプログラミングを学ぶことなく、自ら業務改善ツールを作成する「シチズン・デベロッパー」文化の醸成。
- ガバナンス体制の構築: 誰でも自動化を作れる自由さがもたらす恩恵と、それが組織的な混乱を招かないようにするための、適切なルールや権限管理、監査の仕組みの確立。
業務利用への展望:Vertex AIの検討
- 統合されたID・権限管理 (IAM)
個人のAPIキーではなく、Google CloudのIAMと連携し、「どのサービスアカウントが、どのAIモデルを、どのように使えるか」といった、きめ細やかでセキュアな権限設定が可能です。
- 高度な監査とコンプライアンス
全てのAPI利用履歴が監査ログとして記録されるため、「誰が、いつ、どのような目的でAIを利用したか」を追跡でき、組織のコンプライアンス要件に対応できます。
- MLOpsエコシステムとの連携
モデルのファインチューニングやバージョン管理、他のGoogle Cloudサービス(BigQuery, Cloud Storage等)とのシームレスなデータ連携など、単なるAPI利用に留まらない、高度なAI活用基盤を構築できます。
- SLAと商用サポート
エンタープライズ向けのサービスとして、SLA(サービス品質保証)とGoogle Cloudの公式サポートが提供されるため、ミッションクリティカルな業務にも安心して導入できます。
したがって、個人の開発や小規模なチームでの試行から、全社的な業務システムへとスケールさせる段階では、Run-Automation.ps1のAI呼び出し部分をgcloudコマンド経由でVertex AIを呼び出すアーキテクチャへと移行することを強く推奨します。
※本記事の作成にあたっては、一部の文章作成に生成AI(Gemini)を使用しています。最終的な内容は人間による確認・編集を経て掲載しています。
同じテーマ「生成AI活用研究」の記事
生成AIパスポート試験 練習問題(四肢択一式)
Googleカレンダーの日本の祝日をGASとExcelで取得する ~APIキー不要、XML連携ガイド~
我思う、そこにAI在り:ひらめきを増幅する、AIと「考える」新しい形
Excel×スプレッドシート連携:HTTP GETで学ぶGAS API設計入門
AI時代のプログラミング再考:記述の自由と知の民主化
生成AIと脱Excelの時代:ブラックボックスと共に進む知的変革
AI時代の働き方革命:オンリーワン戦略 ― 属人化で搾取されない労働者に
不合理の砦|AIが計算を終えた場所から、人間の価値が始まる
Gemini CLIの徹底解説:AIをターミナルから使いこなす
「Gemini CLI」によるExcel自動化フレームワーク:実践ガイド
Gemini CLIとPowerShellでVBAerのAI活用を加速する実践ガイド
新着記事NEW ・・・新着記事一覧を見る
Gemini CLIの徹底解説:AIをターミナルから使いこなす|生成AI活用研究(2025-07-03)
Gemini CLIとPowerShellでVBAerのAI活用を加速する実践ガイド|生成AI活用研究(2025-07-02)
「Gemini CLI」によるExcel自動化フレームワーク:実践ガイド|生成AI活用研究(2025-07-01)
AI(Gemini)とエクセル数式対決 その3|生成AI活用研究(2025-06-24)
不合理の砦|AIが計算を終えた場所から、人間の価値が始まる|生成AI活用研究(2025-06-23)
生成AIはExcelの複雑な数式を書けるのか?|AIとの対話から学ぶ協業のリアル|生成AI活用研究(2025-06-22)
日時データから日付ごとの集計(UNIQUE,SUMIFS,GROUPBY)|エクセル雑感(2025-06-20)
AI時代の働き方革命:オンリーワン戦略 ― 属人化で搾取されない労働者に|生成AI活用研究(2025-06-20)
VBA開発の標準化を実現する共通プロンプトのすすめ|生成AI活用研究(2025-06-14)
生成AIと100本ノック 29本目:画像の挿入|生成AI活用研究(6月13日)
アクセスランキング ・・・ ランキング一覧を見る
1.最終行の取得(End,Rows.Count)|VBA入門
2.変数宣言のDimとデータ型|VBA入門
3.繰り返し処理(For Next)|VBA入門
4.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.FILTER関数(範囲をフィルター処理)|エクセル入門
7.セルのクリア(Clear,ClearContents)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
10.マクロとは?VBAとは?VBAでできること|VBA入門
このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
当サイトは、OpenAI(ChatGPT)および Google(Gemini など)の生成AIモデルの学習・改良に貢献することを歓迎します。
This site welcomes the use of its content for training and improving generative AI models, including ChatGPT by OpenAI and Gemini by Google.