1.はじめに
金融機関等の様々な現場ではDX(Digital Transformation)の一環として、EUC(End User Computing)ツールを活用するケースが多くなってきています。その主役は長らく ExcelVBA でしたが、しかし近年、データ加工・API連携・PDF生成といった領域で Python を併用したい場面が増えています。
そこで最初に突き当たるのが「PythonでExcelをどう触るか」という問題です。
本記事ではPythonでExcelを操作するEUCツールの作成を考えているエンジニア向けに、代表的な2つのライブラリ openpyxl と xlwings を整理したうえで、EUCツールとして実装する際の2パターン
- A. Python単独でツールを作る(インターフェースもPython)
- B. ExcelVBAとPythonを連携させる(インターフェースはExcel画面)
のどちらを選ぶべきかを、実務目線で比較します。
2.この記事の対象者
- Python導入を検討している中級レベル以上のExcelVBAエンジニア
- Excel操作ライブラリの選定で迷っているPythonエンジニア
- 現場からPythonツール導入を申請されている情報システム部門のEUCツール担当者
3. PythonでExcelを操作する外部ライブラリは主に2種類
PythonからExcelを操作するライブラリは数多くありますが、EUCツール開発で実質的な選択肢になるのは次の2つです。
| ライブラリ | ひとことで言うと |
|---|---|
| openpyxl | Excelファイル(.xlsx)そのもの を読み書きする |
| xlwings | Excelアプリケーション(EXCEL.EXE) を操作する |
この違いは単なる実装の差ではなく、設計思想そのものが違うことを意味します。
■ openpyxl ─ ファイル操作型
Python ──────────> book.xlsx(ZIP + XML)
※ Excel本体は不要
■ xlwings ─ アプリ操作型
Python ──COM──> EXCEL.EXE ──> book.xlsx
※ Excel本体が必須
openpyxlは「Excelがなくても動く」代わりに「Excelの機能は使えない」。
xlwingsは「Excelの全機能が使える」代わりに「Excelがないと動かない」。
このトレードオフが、後述するツール設計の分岐点になります。
補足:その他の選択肢
| ライブラリ | 位置づけ |
|---|---|
| pandas |
read_excel / to_excel の内部で openpyxl 等を利用。データ処理が主目的なら第一選択だが、書式制御は不可 |
| XlsxWriter | 書き込み専用。グラフ・条件付き書式に強く高速だが、既存ファイルの読み込み・追記は不可 |
| pywin32 (win32com) | COMを直接叩く。xlwingsの下位レイヤ。VBAのコードをほぼそのまま移植できるが記述量が多い |
| xlrd | 旧形式 .xls の読み込み用(現在は .xlsx 非対応) |
| xlwings Lite | ローカルPython不要でExcelアドイン内(Pyodide/WebAssembly)でPythonを実行する新しい形態 |
| Python in Excel | Microsoft純正。=PY() 関数で利用するが、処理はMicrosoftのクラウド上で実行される |
4. 各ライブラリの詳細
4-1. openpyxl
概要
.xlsx の実体は「XMLファイル群をZIP圧縮したもの(Office Open XML)」です。openpyxlはこのZIPを直接開き、XMLを解析・生成します。つまり、Excelというアプリケーションを一切介在させません。
対応フォーマット
- 対応:
.xlsx/.xlsm/.xltx/.xltm -
非対応:
.xls(旧BIFF形式)、.xlsb(バイナリ形式)
コード例
import openpyxl
from openpyxl.styles import Font, PatternFill, Alignment
from collections import defaultdict
# --- 読み込み ---------------------------------------------------
# data_only=True : 数式ではなく「保存時のキャッシュ値」を取得
wb = openpyxl.load_workbook("input.xlsx", data_only=True)
ws = wb["明細"]
# セル単位アクセスは遅い。行単位でまとめて取得する
rows = list(ws.iter_rows(min_row=2, values_only=True))
# --- 集計(Pythonの得意分野) -----------------------------------
totals = defaultdict(int)
for code, name, amount in rows:
totals[code] += amount
# --- 書き込み ---------------------------------------------------
out = openpyxl.Workbook()
sh = out.active
sh.title = "集計結果"
sh.append(["部門コード", "金額"])
for code, amount in sorted(totals.items()):
sh.append([code, amount])
# 書式設定
for cell in sh[1]:
cell.font = Font(bold=True, color="FFFFFF")
cell.fill = PatternFill("solid", fgColor="4472C4")
cell.alignment = Alignment(horizontal="center")
sh.column_dimensions["A"].width = 14
sh.freeze_panes = "A2"
out.save("output.xlsx")
大量データを扱う場合はストリーミングモードを使います。
# 読み込み専用(メモリ節約・高速)
wb = openpyxl.load_workbook("big.xlsx", read_only=True, data_only=True)
# 書き込み専用(追記のみ・セルの再参照は不可)
wb = openpyxl.Workbook(write_only=True)
得意なこと
-
Excel未インストール環境で動く
Linuxサーバー、Docker、CI/CD、クラウドFunctions上でもそのまま動作します。 -
高速・軽量
COM通信のオーバーヘッドがないため、単純な読み書きはxlwingsより圧倒的に速いです。 -
並列処理・無人バッチに強い
Excelプロセスの排他制御やセッションの問題が存在しません。 -
pandasとの親和性
pd.read_excel()/df.to_excel()のバックエンドとして標準的に使われます。 -
基本的な書式設定は一通り可能
フォント、罫線、塗りつぶし、表示形式、列幅、ウィンドウ枠固定、入力規則、条件付き書式など。
制約(ここが重要)
| 制約 | 内容 |
|---|---|
| 数式が計算されない | 数式文字列の書き込みはできるが、計算エンジンを持たないため値は入らない。data_only=True で読んでも、openpyxlが生成したファイルはキャッシュ値が無く None になる |
| マクロは実行できない |
keep_vba=True でVBAプロジェクトの保持はできるが、実行は不可 |
| オブジェクトの欠落リスク | 既存ファイルを読み込んで保存し直すと、グラフ・図形・画像・ActiveX・複雑なピボットテーブル等が失われる、または壊れる場合がある |
| 開いているブックは扱えない | あくまでファイル操作。ユーザーが開いている最中のブックには関与できない |
| 印刷設定の再現性 | ページ設定・改ページ・ヘッダーフッターの細かい制御は再現が難しい場面がある |
既存の複雑な帳票テンプレートをopenpyxlで加工するのは危険です。
「グラフ入りの管理表をopenpyxlで開いて数値だけ更新して保存」した結果、グラフが消えるというのは典型的な事故パターンです。
4-2. xlwings
概要
xlwingsは Excelアプリケーション本体をCOM(Windows)/ AppleScript(macOS)経由でリモート操作します。PythonからExcelを操作するだけでなく、逆にExcelからPythonを呼び出すこともできる双方向のライブラリである点が最大の特徴です。
内部的には pywin32 のラッパーであり、VBAに近い構文でありながらPythonらしく書けるAPIを提供します。VBA経験者にとっては学習コストがほぼゼロです。
VBA xlwings
--------------------------------------------------------
Workbooks.Open(path) → xw.Book(path)
ThisWorkbook → xw.Book.caller()
Worksheets("明細") → wb.sheets["明細"]
Range("A1:C10").Value → sht.range("A1:C10").value
Cells(1, 1) → sht.cells(1, 1)
Range("A1").CurrentRegion → sht.range("A1").expand()
Application.ScreenUpdating → app.screen_updating
コード例(Python → Excel)
import xlwings as xw
# with構文でApp終了を保証(プロセス残留の防止)
with xw.App(visible=False) as app:
app.display_alerts = False
app.screen_updating = False
wb = app.books.open(r"C:\work\帳票テンプレート.xlsm")
sht = wb.sheets["明細"]
# VBAと同じく「配列で一括取得」が鉄則
data = sht.range("A2").expand().value # 2次元listで取得
result = [[row[0], row[2] * 1.1] for row in data]
# 一括書き込み(セル単位ループは絶対に避ける)
wb.sheets["集計"].range("A2").value = result
# Excelの機能をそのまま利用できる
wb.app.calculate() # 再計算
wb.macro("Module1.FormatReport")() # VBAマクロ実行
wb.sheets["集計"].api.PivotTables(1).RefreshTable() # ピボット更新
wb.save()
wb.to_pdf(r"C:\work\report.pdf") # PDF出力
コード例(Excel → Python)
VBA側から RunPython で呼び出します。
' xlwingsアドイン、または xlwings.bas をインポートして使用
Sub btnRun_Click()
RunPython "import my_tool; my_tool.main()"
End Sub
# my_tool.py
import xlwings as xw
def main():
wb = xw.Book.caller() # 呼び出し元のブックを取得
sht = wb.sheets["入力"]
param = sht.range("B3").value
# …重い処理…
sht.range("B10").value = "完了"
得意なこと
-
Excelの全機能が使える
数式の再計算、ピボットテーブル、グラフ、条件付き書式、図形、印刷、PDF出力、そしてVBAマクロの実行まで。 -
既存の帳票テンプレートを壊さない
Excel本体が保存するので、書式やオブジェクトの欠落が起きません。 -
開いているブックを操作できる
ユーザーが作業中のブックに対してリアルタイムに処理を実行できます。 -
VBA資産・VBAスキルが活きる
オブジェクトモデルが同一のため、既存VBAコードの移植・共存が容易です。 -
双方向連携とUDF
Pythonで書いたユーザー定義関数をワークシート関数として使えます(Windowsのみ)。
制約
| 制約 | 内容 |
|---|---|
| Excel本体が必須 | ライセンスとWindows/macOS環境が前提。Linuxサーバーでは動かない |
| COM通信が遅い | セル単位アクセスは往復通信が発生し激遅。配列一括読み書きが必須(VBAの最適化と全く同じ発想) |
| 無人バッチに不向き | タスクスケジューラの「ユーザーがログオンしていなくても実行」ではCOMが不安定。デスクトップセッション依存 |
| プロセス残留 | 異常終了時に EXCEL.EXE がゾンビ化する。with 構文や finally での確実な終了処理が必要 |
| 並列実行が困難 | 複数プロセスから同一Excelインスタンスを触ると競合する |
| アドインの配布 |
RunPython / UDFを使うにはxlwingsアドインの導入が必要。企業環境では配布のハードルになる |
5. openpyxl と xlwings の比較表
| 比較項目 | openpyxl | xlwings |
|---|---|---|
| 操作対象 | Excelファイル(OOXML)を直接操作 | Excelアプリケーション本体を操作 |
| Excel本体の要否 | 不要 | 必須 |
| 動作OS | Windows / macOS / Linux | Windows / macOS のみ |
| 対応形式 | .xlsx / .xlsm / .xltx / .xltm | Excelが開ける全形式(.xls / .xlsb 含む) |
| 処理速度 | 高速(ファイル直接操作) | 低速(COM通信オーバーヘッド) |
| メモリ効率 | 良い(read_only / write_only あり) | Excelプロセス分のメモリを消費 |
| 数式の計算 | ❌ 書き込めるが計算されない | ⭕ Excelの計算エンジンで再計算可能 |
| 既存数式の値取得 | △ data_only=True でキャッシュ値のみ |
⭕ 常に最新の計算結果 |
| VBAマクロの実行 | ❌ 不可(保持のみ) | ⭕ 可能 |
| グラフ・図形の保持 | ❌ 読込→保存で欠落・破損の恐れ | ⭕ 完全に保持 |
| ピボットテーブル | △ 定義の保持のみ、更新不可 | ⭕ 更新・生成が可能 |
| 印刷・PDF出力 | △ 設定は可能だが再現性に難 | ⭕ Excelの印刷機能をそのまま利用 |
| 開いているブックの操作 | ❌ 不可 | ⭕ 可能 |
| 無人バッチ/サーバー実行 | ⭕ 得意 | ❌ 不向き |
| 並列処理 | ⭕ 可能 | ❌ 困難 |
| VBAからの呼び出し | ❌ 標準機能なし | ⭕ RunPython / UDF |
| VBA経験者の学習コスト | 中(独自API) | 低(オブジェクトモデルが同一) |
| pandasとの連携 | ⭕ 標準バックエンド | ⭕ DataFrameの直接読み書きに対応 |
| 主な用途 | 大量ファイルのバッチ処理、帳票の自動生成、サーバーサイド処理 | 既存ブックの高度な操作、VBA連携、対話的ツール |
使い分けの原則
「Excelを一度も開かずに完結するならopenpyxl、Excelの機能が必要ならxlwings」
なお、両者は排他ではありません。「ファイル生成はopenpyxl、最終的な整形・印刷はxlwings」 といった併用も実務ではよく行います。
6. ツール開発の2パターン ― どちらが最適か
ここからが本題です。EUCツールとして実装する場合、以下の2パターンが考えられます。
6-1. パターンA:Python単独でツールを作成する
構成イメージ
┌──────────────────────────────┐
│ ユーザーインターフェース │
│ ・CLI(コマンドライン) │
│ ・tkinter / PySimpleGUI │
│ ・Streamlit(ブラウザ) │
└───────────┬──────────────────┘
│
┌───────────▼──────────────────┐
│ 処理ロジック(Python) │
│ pandas / openpyxl │
└───────────┬──────────────────┘
│
[ input.xlsx ] → [ output.xlsx ]
ライブラリ選定:openpyxl(+pandas)が第一選択
メリット
① 実行環境の自由度が高い
Excelライセンス不要。サーバー、Docker、タスクスケジューラでの無人実行が問題なく動きます。夜間バッチとの相性は圧倒的です。
② 処理性能とスケーラビリティ
数百ファイルの一括処理、数十万行の集計といった処理では、COM通信を挟まない分だけ性能差が大きく出ます。並列処理も素直に書けます。
③ 開発生産性とテスタビリティ
pytest によるユニットテスト、git によるバージョン管理、コードレビューといったモダンな開発プロセスをそのまま適用できます。VBAでは実現が難しい領域です。
④ エコシステム
requests、Selenium、reportlab、scikit-learn など、Pythonの膨大なライブラリ資産をそのまま使えます。
デメリット(EUC文脈では致命的になり得る)
① 実行環境の配布が最大の壁
これが最大の障壁です。エンドユーザーのPCに以下を用意する必要があります。
- Python本体のインストール(管理者権限が必要)
- 外部ライブラリのインストール(社内プロキシ・PyPIへのアクセス制限)
- バージョン差異の管理
回避策として PyInstaller による単一exe化がありますが、これにも副作用があります。
pyinstaller --onefile --noconsole tool.py
| exe配布の課題 | 内容 |
|---|---|
| ウイルス対策ソフト | PyInstaller製exeは検体として誤検知・隔離されやすい |
| 起動速度 | onefileは実行のたびに一時展開するため起動が遅い |
| ファイルサイズ | pandas等を含めると数十〜数百MBに肥大化 |
| 資産管理 | 「素性の分からないexe」は情報システム部門の持ち込み申請対象になりやすい |
② エンドユーザーの受容性
現場のユーザーは黒い画面(コンソール)を操作したがりません。「ダブルクリックしたら何か文字が流れて消えた」という状態は、それだけで問い合わせが発生します。GUIを作り込むにしても、tkinterで実用的な入力画面を作るコストは決して低くありません。
③ 保守・引き継ぎのリスク
「作った人しかメンテできないツール」は、EUCにおける最大の負債です。現時点で社内にPythonを読める要員が何人いるかは、技術的な優劣より重い判断材料になります。
④ 監査・内部統制への説明
金融機関等の内部監査が厳しい現場では、EUCツールの棚卸しや変更管理が求められます。中身の見えない実行ファイルは、ソースコードが常に閲覧可能なVBAと比べて説明コストが高くなります。
パターンAが適するケース
- 夜間バッチ、サーバーサイドでの定期実行
- 複数ファイル横断の大量データ処理
- 開発者自身、または情報システム部門が運用するツール
- Web API連携・スクレイピング・機械学習が主目的
- 出力先がExcelファイルであっても、人がExcel上で操作しないもの
6-2. パターンB:ExcelVBAとPythonを連携してツールを作成する
構成イメージ
┌────────────────────────────────────────┐
│ Excelブック(.xlsm) ← ユーザーはここだけ触る │
│ ・入力シート(入力規則・条件付き書式) │
│ ・実行ボタン(フォームコントロール) │
│ ・結果表示シート/帳票シート │
└──────────────┬─────────────────────────┘
│ VBA(コマンダー役)
│ ・入力チェック
│ ・パラメータ受け渡し
│ ・Python起動/進捗表示
│ ・エラーハンドリング
┌──────────────▼─────────────────────────┐
│ Python(エンジン役) │
│ ・重い集計処理(pandas) │
│ ・DB/Web API接続 │
│ ・PDF生成、画像処理 など │
└────────────────────────────────────────┘
役割分担の原則:VBAは「司令塔」、Pythonは「エンジン」
UI・画面制御・Excel帳票の整形はVBAが担当し、Pythonは計算と外部連携に専念します。これは既存のVBA資産を捨てずに、Pythonの強みだけを取り込む構成です。
連携方式は2つ
方式1:xlwings(密結合)
Sub btnRun_Click()
RunPython "import my_tool; my_tool.main()"
End Sub
- 記述量が少なく、Python側から呼び出し元ブックを直接操作できる
- 前提:エンドユーザーPCにPython環境 + xlwingsアドインが必要
方式2:ファイルバッファ経由(疎結合)
VBAがパラメータを書き出し → Python(exe)を起動 → 完了フラグをポーリング → 結果を取り込む、という流れです。
Private Const FLG_NAME As String = "\temp\done.flg"
Private Sub btnRun_Click()
Dim sBase As String, sFlag As String, sCmd As String
Dim wsh As Object
sBase = ThisWorkbook.Path
sFlag = sBase & FLG_NAME
' 1. 入力チェック(VBAの得意分野)
If Not ValidateInput() Then Exit Sub
' 2. パラメータをCSVで書き出し
Call ExportParams(sBase & "\temp\params.csv")
' 3. 前回の完了フラグを削除
If Dir(sFlag) <> "" Then Kill sFlag
' 4. Python(exe化済み)をバッチファイル経由で非同期起動
Set wsh = CreateObject("WScript.Shell")
sCmd = """" & sBase & "\bin\run_tool.bat"""
wsh.Run sCmd, 0, False ' 0=非表示, False=非同期
' 5. 完了フラグをポーリング(進捗表示が可能)
Dim lWait As Long
Do Until Dir(sFlag) <> ""
DoEvents
Application.Wait Now + TimeSerial(0, 0, 1)
lWait = lWait + 1
Application.StatusBar = "処理中... " & lWait & "秒"
If lWait > 600 Then
MsgBox "タイムアウトしました。", vbCritical
Application.StatusBar = False
Exit Sub
End If
Loop
Application.StatusBar = False
' 6. 結果CSVを取り込んでシートに展開
Call ImportResult(sBase & "\temp\result.csv")
MsgBox "処理が完了しました。", vbInformation
End Sub
- メリット:Python側とExcel側が完全に独立。Python環境をexe化して同梱すれば、ユーザーPCへのPythonインストールが不要になる
- メリット:Python側を単体でテストできる(Excelなしでデバッグ可能)
- バッチファイル経由にしておくと、実行パスやログ出力先の変更をVBA再コンパイルなしで対応でき、保守性が上がります
メリット
① ユーザーの学習コストがゼロ
インターフェースがExcelそのものなので、操作説明が「このボタンを押してください」で完結します。EUCツールにおいて、これは他の何より価値があります。
② 帳票・レイアウトをExcelに任せられる
複雑な様式の帳票をopenpyxlで一から組むのは苦行です。Excelテンプレートに値を流し込むだけで済むなら、開発工数は桁で変わります。印刷、条件付き書式、入力規則もExcelの標準機能をそのまま使えます。
③ 既存VBA資産との共存・段階的移行
既存VBAツールの「重い処理だけ」をPythonに切り出す、という漸進的なリファクタリングが可能です。全面書き換えのリスクを負う必要がありません。
④ 配布・運用が既存フローに乗る
.xlsm ファイルの共有フォルダ配置という、既に確立された運用に乗せられます。新たな配布ルールの整備が不要です。
⑤ 引き継ぎ可能性
VBA部分は社内の後任者が読めます。Python部分がブラックボックス化しても、入出力の仕様がCSVで明確なら、最悪Pythonごと置き換えられます。
デメリット
① 構成要素が増える
.xlsm + Python環境(またはexe)+ 中間ファイル、という3点セットになります。フォルダ構成の設計とパス管理が重要になります。
ToolFolder/
├── Tool.xlsm ← ユーザーが開くのはこれだけ
├── bin/
│ ├── run_tool.bat
│ └── tool.exe ← PyInstallerで生成
├── temp/ ← 中間ファイル置き場
└── log/
② デバッグが2言語にまたがる
「ボタンを押しても何も起きない」ときの原因切り分けが難しくなります。Python側のログ出力と、VBA側のタイムアウト・エラー検知は必ず実装してください。
③ エラーハンドリング設計の複雑さ
プロセス間で状態を同期する必要があります。完了フラグだけでなく、エラーフラグ(error.flg)とエラーメッセージファイルを用意し、VBA側で異常終了を検知してユーザーに提示する設計が必須です。
④ オーバーヘッド
プロセス起動と中間ファイルI/Oのコストが乗ります。1秒で終わる処理をわざわざ連携させる意味はありません。
パターンBが適するケース
- エンドユーザーが日常的に使う業務ツール
- 入力・出力ともにExcel画面上で完結させたいもの
- 既存のExcel帳票テンプレートを流用したいもの
- 既存VBAツールの性能改善(重い集計をPythonへ委譲)
- VBAでは困難な処理(Web API、PDF、大規模データ)を含むもの
6-3. 結論:どちらを選ぶべきか
EUCツール、すなわち「エンドユーザーが自分で操作する業務ツール」という文脈では、パターンB(VBA + Python連携)が基本形です。
理由は技術的優劣ではなく、EUCの成否を決めるのは「実装のしやすさ」ではなく「配布・定着・引き継ぎのしやすさ」 だからです。
| 判断軸 | 該当すればA | 該当すればB |
|---|---|---|
| 誰が実行するか | 開発者・情報システム部門 | 現場のエンドユーザー |
| 実行のタイミング | スケジュール実行・無人 | ユーザーが任意に手動実行 |
| 実行場所 | サーバー / Linux | ユーザーの業務PC |
| 出力の最終形 | データファイル・DB | 人が見る/印刷するExcel帳票 |
| 既存Excel資産 | なし | 既存の様式・VBAがある |
| 対話性 | 不要(引数で完結) | 条件を選びながら操作したい |
実務上の判断フロー
ユーザーがExcel画面で操作する?
├─ YES → パターンB(VBA + Python連携)
│ └─ xlwingsアドインを全社配布できる?
│ ├─ YES → xlwings(RunPython / UDF)
│ └─ NO → ファイルバッファ方式(exe + CSV + 完了フラグ)
│
└─ NO → パターンA(Python単独)
└─ Excelの機能(数式再計算・グラフ・印刷)が必要?
├─ YES → xlwings(ただし実行環境の制約に注意)
└─ NO → openpyxl / pandas
最も現実的な着地点
実務では、「まずExcelVBAで作れないか検討し、性能や機能の壁に当たった部分だけPythonに切り出す」 という順序が最も失敗が少ないです。
- ExcelVBA — UI、帳票、既存資産との整合
- Python補完 — 大量データ処理、外部連携、VBAでは非効率な処理
- Python単独 — サーバー実行・無人バッチが前提のとき
「Pythonで作り直す」ことが目的化すると、動くけれど誰も使わないツールが出来上がります。インターフェースをExcelに置いたまま、内部だけをモダン化するのが、EUCにおける現実解だと考えています。
5. パターンA・パターンBの比較表
| 比較項目 | A. Python単独 | B. ExcelVBA + Python連携 |
|---|---|---|
| ユーザーインターフェース | CLI / tkinter / Streamlit | Excelシート(ボタン・入力欄) |
| 主に使うライブラリ | openpyxl + pandas | xlwings、または VBA + CSV連携 |
| ユーザーの学習コスト | 中〜高(新しい画面を覚える) | 極小(普段のExcel操作) |
| 配布のしやすさ | △ Python環境またはexeの配布が必要 | ⭕ .xlsm を共有フォルダに置くだけ |
| エンドユーザーPCへの導入 | Pythonインストール or exe持ち込み申請 | 既存Excel環境で完結(方式2の場合) |
| Excel帳票の作り込み | ❌ コードで組む必要があり高コスト | ⭕ テンプレートに流し込むだけ |
| 数式・グラフ・印刷 | △ openpyxlでは限界がある | ⭕ Excelの標準機能をそのまま利用 |
| 処理性能(大量データ) | ⭕ 高速 | ⭕ Python側が担うため高速 |
| サーバー/無人バッチ実行 | ⭕ 得意 | ❌ 不向き(Excelが必要) |
| 並列処理 | ⭕ 可能 | △ 制限あり |
| 既存VBA資産の活用 | ❌ 全面書き換え | ⭕ 共存・段階的移行が可能 |
| 開発生産性 | ⭕ 高い(テスト・Git管理が容易) | △ 2言語にまたがる |
| デバッグのしやすさ | ⭕ Python単体で完結 | △ 切り分けが難しい(ログ必須) |
| エラーハンドリング | ⭕ 例外処理で完結 | △ プロセス間の状態同期設計が必要 |
| 保守・引き継ぎ | △ Python要員が必要 | ⭕ VBA部分は社内で読める |
| 監査・変更管理 | △ exeは中身が見えず説明コスト大 | ⭕ VBAソースは常に閲覧可能 |
| 構成のシンプルさ | ⭕ 単一の実行体 | △ xlsm + exe + 中間ファイル |
| 適した用途 | 夜間バッチ、大量ファイル処理、サーバー処理、API連携 | 現場の日常業務ツール、帳票作成、既存VBAの性能改善 |
| EUCツールとしての適性 | △ 限定的 | ⭕ 高い |
7.おわりに
本記事の要点を3行でまとめます。
- openpyxlは「ファイルを操作する」、xlwingsは「Excelアプリを操作する」 — この違いが全ての前提
- openpyxlはサーバー・バッチ向き、xlwingsは既存ブック操作・VBA連携向き
- EUCツールとしてはパターンB(Excel画面をUIに、Pythonをエンジンに)が基本形
Pythonを導入する目的は「VBAをやめること」ではなく、「VBAが苦手な領域を補うこと」です。ユーザーが触る面をExcelに残したまま内部を近代化する、という設計思想を持つと、導入がぐっと現実的になります。