\ お問い合わせはこちら /

Python で Excel を自動操作する【win32com 超実践ガイド】

Windows + Excel 環境向けの記事です。

win32com なら、ほぼすべての Excel 操作を Python から自動化 できます。

本記事では、必要な知識をすべてまとめました。

目次
  1. 1. 事前準備(環境・基本構造)
  2. 2. Excel アプリケーションの基本操作
  3. 3. ブック操作
  4. 4. ワークシート操作
  5. 5. セル・レンジの基本操作
  6. 6. セルの書式設定
  7. 7. コピー&ペースト・オートフィル
  8. 8. 行・列の操作
  9. 9. フィルタ・並び替え
  10. 10. 名前付き範囲・Names 操作
  11. 11. テーブル(ListObject)の操作
  12. 12. グラフ・図形の操作
  13. 13. ページ設定・印刷・PDF 出力
  14. 14. 数式・WorksheetFunction の利用
  15. 15. ピボットテーブルの作成
  16. 16. マクロ実行・VBA モジュール操作
  17. 17. エラーハンドリングと COM オブジェクトの後始末
  18. まとめ:win32com で Excel を「ほぼ何でも」自動化できる

1. 事前準備(環境・基本構造)

Python から Excel を操作する準備

pywin32 をインストールし、win32com.client.Dispatch から Excel.Application を起動します。

Bash
pip install pywin32
Python
from win32com.client import Dispatch, constants


def open_excel(visible=False):
    excel = Dispatch("Excel.Application")
    excel.Visible = visible  # True にすると画面表示される
    return excel


def quit_excel(excel):
    excel.Quit()

2. Excel アプリケーションの基本操作

Excel.Application を起動する

Python
from win32com.client import Dispatch

excel = Dispatch("Excel.Application")
excel.Visible = True  # Excel を表示

既存の Excel インスタンスに接続する

すでに起動している Excel に接続したい場合。

Python
from win32com.client import GetObject

excel = GetObject(Class="Excel.Application")
excel.Visible = True

アラートダイアログ(保存確認など)を抑制する

自動処理ではダイアログを出さないのが基本です。

Python
excel.DisplayAlerts = False
# 処理...
excel.DisplayAlerts = True  # 戻す

言語定数の利用(constants)

xlUp などの Excel 定数は constants から使えます。

Python
from win32com.client import constants

excel = Dispatch("Excel.Application")
print(constants.xlUp)  # -4162 などの数値

3. ブック操作

新規ブックを作成する

Python
excel = Dispatch("Excel.Application")
excel.Visible = True

wb = excel.Workbooks.Add()
ws = wb.ActiveSheet
ws.Range("A1").Value = "Hello Excel"

既存のブックを開く(読み書き)

Python
filepath = r"C:\path\to\file.xlsx"

wb = excel.Workbooks.Open(
    filepath,
    UpdateLinks=False,   # 外部リンク更新の抑制
    ReadOnly=False,      # 読み取り専用を解除
)

読み取り専用で開く

Python
wb = excel.Workbooks.Open(r"C:\path\to\file.xlsx", ReadOnly=True)

ブックを保存する(上書き保存)

Python
wb.Save()  # すでにパスがあるブック

ブックを別名で保存する(SaveAs)

Python
new_path = r"C:\path\to\new_file.xlsx"
wb.SaveAs(new_path)

ファイル形式を指定して保存する(例: xlsx, xlsm, pdf 以外)

# xlsm(マクロ有効ブック)で保存
xlOpenXMLWorkbookMacroEnabled = 52
wb.SaveAs(r"C:\path\to\macro_book.xlsm", FileFormat=xlOpenXMLWorkbookMacroEnabled)

ブックを閉じる(保存する / しない)

Python
# 保存して閉じる
wb.Close(SaveChanges=True)

# 保存せず閉じる
wb.Close(SaveChanges=False)

開いているすべてのブックを列挙する

Python
for wb in excel.Workbooks:
    print(wb.Name, wb.FullName)

4. ワークシート操作

アクティブシートを取得する

Python
ws = wb.ActiveSheet
print(ws.Name)

シートを名前で取得する

Python
ws = wb.Worksheets("Sheet1")

シートをインデックスで取得する(1始まり)

Python
ws = wb.Worksheets(1)  # 一番左のシート

新しいシートを追加する

Python
# 末尾に追加
new_sheet = wb.Worksheets.Add()
new_sheet.Name = "新しいシート"

# 特定のシートの前に追加
before_sheet = wb.Worksheets("Sheet1")
new_sheet = wb.Worksheets.Add(Before=before_sheet)

シートを削除する

Python
excel.DisplayAlerts = False  # 削除確認ダイアログを抑制
wb.Worksheets("削除対象").Delete()
excel.DisplayAlerts = True

シートをコピー・移動する

Python
# "Sheet1" を最後にコピー
ws = wb.Worksheets("Sheet1")
ws.Copy(After=wb.Worksheets(wb.Worksheets.Count))

# "Sheet1" を最後に移動
ws.Move(After=wb.Worksheets(wb.Worksheets.Count))

シート名を変更する

Python
ws = wb.Worksheets("Sheet1")
ws.Name = "売上集計"

シートの表示/非表示/VeryHidden

Python
# 非表示
ws.Visible = False

# 再表示
ws.Visible = True

# VeryHidden(VBEからでないと戻せないレベル)
xlSheetVeryHidden = 2
ws.Visible = xlSheetVeryHidden

5. セル・レンジの基本操作

単一セルに値を書き込む / 読み込む

Python
ws = wb.Worksheets("Sheet1")

# 書き込み
ws.Range("A1").Value = "Hello"
ws.Cells(1, 2).Value = 123  # B1 に 123

# 読み込み
val_a1 = ws.Range("A1").Value
val_b1 = ws.Cells(1, 2).Value
print(val_a1, val_b1)

数式をセットする

Python
ws.Range("A1").Value = 10
ws.Range("A2").Value = 20
ws.Range("A3").Formula = "=SUM(A1:A2)"

表示値(.Text)と内部値(.Value)の違い

Python
cell = ws.Range("B1")
cell.NumberFormat = "#,##0.00"
cell.Value = 1234.567

print(cell.Value)  # 1234.567
print(cell.Text)   # "1,234.57" など書式に応じた文字列

複数セルに一括で値を書き込む(2次元タプル)

Python
data = (
    ("名前", "年齢", "部署"),
    ("山田", 30, "営業"),
    ("佐藤", 28, "開発"),
)

ws.Range("A1:C3").Value = data

わかりやすい 2D 配列取得

Python
values = ws.Range("A2:C4").Value  # ((row1...), (row2...), ...)
for row in values:
    print(row)

行・列・UsedRange の取得

Python
used = ws.UsedRange
print(used.Address)

# 行オブジェクト
row_3 = ws.Rows(3)
row_3.Font.Bold = True

# 列オブジェクト
col_b = ws.Columns("B")
col_b.Interior.ColorIndex = 6  # 黄色

6. セルの書式設定

フォント(太字・サイズ・色)を設定する

Python
rng = ws.Range("A1:C1")
rng.Font.Bold = True
rng.Font.Size = 12
rng.Font.Color = 0x0000FF  # BGR 順(青)

背景色(塗りつぶし)を設定する

Python
rng = ws.Range("A2:C10")
rng.Interior.Color = 0x00FF00  # BGR(緑)

罫線を設定する

Python
rng = ws.Range("A1:C3")
border = rng.Borders
border.LineStyle = 1  # xlContinuous
border.Weight = 2     # xlThin など

表示形式(NumberFormat)を設定する

Python
ws.Range("B2:B10").NumberFormat = "#,##0"
ws.Range("C2:C10").NumberFormat = "yyyy/mm/dd"

セルの結合・中央揃え

Python
rng = ws.Range("A1:C1")
rng.Merge()
rng.HorizontalAlignment = -4108  # xlCenter
rng.VerticalAlignment = -4108    # xlCenter

7. コピー&ペースト・オートフィル

セル範囲のコピー&ペースト

Python
ws.Range("A1:C3").Copy(Destination=ws.Range("E1"))

値だけ貼り付ける(PasteSpecial)

Python
ws.Range("A1:C3").Copy()
ws.Range("E1").PasteSpecial(Paste=constants.xlPasteValues)
excel.CutCopyMode = False

オートフィル(連番やパターン)

Python
ws.Range("A1").Value = 1
ws.Range("A2").Value = 2
source = ws.Range("A1:A2")
target = ws.Range("A1:A10")
source.AutoFill(Destination=target, Type=constants.xlFillSeries)

8. 行・列の操作

行の挿入・削除

Python
# 3行目に行を挿入
ws.Rows(3).Insert()

# 5行目を削除
ws.Rows(5).Delete()

列の挿入・削除

Python
# 列Bの前に列を挿入
ws.Columns("B").Insert()

# 列Dを削除
ws.Columns("D").Delete()

行の高さ・列の幅を設定

Python
ws.Rows(1).RowHeight = 30
ws.Columns("A").ColumnWidth = 20

行・列の非表示・再表示

Python
# 行を非表示
ws.Rows("5:10").EntireRow.Hidden = True

# 列を非表示
ws.Columns("C:E").EntireColumn.Hidden = True

# 再表示
ws.Rows("5:10").EntireRow.Hidden = False
ws.Columns("C:E").EntireColumn.Hidden = False

9. フィルタ・並び替え

オートフィルタを設定する

Python
# A1:C1 を見出しとしたオートフィルタ
ws.Range("A1:C1").AutoFilter()

フィルタ条件を指定する

Python
# 2列目(B列)に対して "開発" の行のみ表示
ws.Range("A1:C100").AutoFilter(Field=2, Criteria1="開発")

フィルタを解除する

Python
ws.AutoFilterMode = False

並べ替え(Sort)

Python
data_range = ws.Range("A1:C10")
data_range.Sort(
    Key1=ws.Range("B2"),  # ソートキー
    Order1=constants.xlAscending,
    Header=constants.xlYes,
)

10. 名前付き範囲・Names 操作

名前付き範囲を作成する

Python
# シートローカルな名前
ws.Names.Add(
    Name="売上範囲",
    RefersTo="=Sheet1!$A$2:$A$10",
)

# ブック全体で使える名前
wb.Names.Add(
    Name="全社売上",
    RefersTo="=SUM(Sheet1!$B$2:$B$10)",
)

名前付き範囲から Range を取得する

Python
named_range = wb.Names("売上範囲")
rng = named_range.RefersToRange
print(rng.Address)

11. テーブル(ListObject)の操作

テーブルを作成する

Python
ws = wb.Worksheets("Sheet1")
ws.Range("A1:C1").Value = ("名前", "年齢", "部署")
ws.Range("A2:C4").Value = (
    ("山田", 30, "営業"),
    ("佐藤", 28, "開発"),
    ("田中", 35, "総務"),
)

tbl_range = ws.Range("A1").CurrentRegion
tbl = ws.ListObjects.Add(
    SourceType=0,
    Source=tbl_range,
    XlListObjectHasHeaders=1,
)
tbl.Name = "社員テーブル"

テーブルに行を追加する

Python
tbl = ws.ListObjects("社員テーブル")
new_row = tbl.ListRows.Add()
new_row.Range.Value = ("鈴木", 26, "マーケ")

テーブルデータを取得する

Python
tbl = ws.ListObjects("社員テーブル")
data_range = tbl.DataBodyRange  # 見出し行を除く範囲
for row in data_range.Value:
    print(row)

12. グラフ・図形の操作

簡単なチャートを作成する

Python
# データ準備
ws.Range("A1:B4").Value = (
    ("月", "売上"),
    ("1月", 100),
    ("2月", 150),
    ("3月", 120),
)

chart_obj = ws.ChartObjects().Add(Left=100, Top=50, Width=400, Height=300)
chart = chart_obj.Chart
chart.SetSourceData(ws.Range("A1:B4"))
chart.ChartType = constants.xlColumnClustered
chart.HasTitle = True
chart.ChartTitle.Text = "月次売上"

図形を追加する(テキストボックス)

Python
shape = ws.Shapes.AddTextbox(
    Orientation=1,  # xlHorizontal
    Left=10,
    Top=10,
    Width=200,
    Height=50,
)
shape.TextFrame.Characters().Text = "注意:値は概算です"

13. ページ設定・印刷・PDF 出力

ページ設定(余白・向き・拡大縮小)

Python
ps = ws.PageSetup
ps.Orientation = constants.xlLandscape
ps.Zoom = False
ps.FitToPagesWide = 1
ps.FitToPagesTall = 1
ps.LeftMargin = excel.InchesToPoints(0.5)
ps.RightMargin = excel.InchesToPoints(0.5)

印刷プレビュー・印刷実行

Python
# 印刷プレビュー
ws.PrintPreview()

# 直接印刷
ws.PrintOut()

PDF として保存する

Python
pdf_path = r"C:\path\to\output.pdf"
ws.ExportAsFixedFormat(
    Type=0,  # xlTypePDF
    Filename=pdf_path,
    Quality=0,  # xlQualityStandard
    IncludeDocProperties=True,
    IgnorePrintAreas=False,
    OpenAfterPublish=False,
)

14. 数式・WorksheetFunction の利用

WorksheetFunction を利用して計算する

Python
wf = excel.WorksheetFunction

result = wf.Sum((1, 2, 3))
max_val = wf.Max((10, 20, 5))

print(result, max_val)  # 6, 20

ワークシート上のデータを使って関数を適用する

Python
rng = ws.Range("B2:B10")
avg = wf.Average(rng)
print("平均値:", avg)

15. ピボットテーブルの作成

ピボットキャッシュを作成し、ピボットテーブルを追加する

Python
# データは Sheet1 の A1:D100 に存在する想定
src_ws = wb.Worksheets("Sheet1")
data_range = src_ws.Range("A1").CurrentRegion

pivot_ws = wb.Worksheets.Add()
pivot_ws.Name = "ピボット"

pivot_cache = wb.PivotCaches().Create(
    SourceType=1,  # xlDatabase
    SourceData=data_range,
)

pivot_table = pivot_cache.CreatePivotTable(
    TableDestination=pivot_ws.Range("A3"),
    TableName="売上ピボット",
)

# フィールド設定
pf_month = pivot_table.PivotFields("月")
pf_month.Orientation = 1  # xlRowField

pf_item = pivot_table.PivotFields("商品")
pf_item.Orientation = 2  # xlColumnField

pf_sales = pivot_table.PivotFields("売上")
pf_sales.Orientation = 4  # xlDataField
pf_sales.Function = -4157  # xlSum

16. マクロ実行・VBA モジュール操作

既存マクロを実行する(Application.Run)

Python
# "Module1" の "MyMacro" を実行(引数なし)
excel.Run("MyMacro")

# 引数あり
excel.Run("MyMacroWithArgs", "hello", 123)

VBA コードを標準モジュールに追加する(簡易例)

Python
vb_proj = wb.VBProject
modules = vb_proj.VBComponents
mod = modules.Add(1)  # vbext_ct_StdModule

code = """
Sub HelloFromPython()
    MsgBox "Hello from Python + VBA!"
End Sub
"""

mod.CodeModule.AddFromString(code)

※ VBA プロジェクトへのアクセスには、「VBA プロジェクト オブジェクト モデルへの信頼を有効にする」設定が必要です。

17. エラーハンドリングと COM オブジェクトの後始末

try / finally で Excel を確実に閉じる

Python
from win32com.client import Dispatch

excel = None
try:
    excel = Dispatch("Excel.Application")
    excel.Visible = False
    wb = excel.Workbooks.Add()
    ws = wb.ActiveSheet
    ws.Range("A1").Value = "処理中..."

    # ここに処理を書く
    wb.SaveAs(r"C:\path\to\file.xlsx")

finally:
    if excel is not None:
        excel.DisplayAlerts = False
        excel.Quit()
        excel = None

多重参照を減らして GC を促す

大量に COM オブジェクトを触る場合は、参照を局所化してスコープから外すと安定しやすくなります。

Python
def write_data(ws):
    rng = ws.Range("A1:C10")
    rng.Value = [[i, j, i * j] for i in range(1, 11) for j in range(1, 4)]
    # rng, ws はここでスコープ外になる

write_data(wb.Worksheets("Sheet1"))

まとめ:win32com で Excel を「ほぼ何でも」自動化できる

ここまでで紹介したようにwin32com を使えば、ほぼ手作業の Excel と同じレベルで Python から制御できます。

  • ブックの生成・読み書き・保存
  • シート・セル・行列・テーブル・チャート・ピボット
  • 印刷・PDF 化
  • マクロ実行・VBA コードの挿入

実務レベルのスクリプトでは、

  1. Excel 起動 → DisplayAlerts=False
  2. ブックを開く / 新規作成
  3. 処理用の関数に分割して、シート・セル操作をまとめる
  4. 保存・クローズ
  5. finally で Quit() する

という流れで書いておくと、安全でメンテしやすいです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

普段はエンジニアとして働きつつ、旅行では「住むように旅する」をテーマに動き回っています。

TABIGRAMMER では、
・旅の情報(台湾を中心としたアジア旅ガイド)
・ミニマリストの持ち物や旅の効率化テクニック
・ブログ運営やプログラミング記事

といった、旅とITが交差するコンテンツを発信しています。

難しいことをわかりやすく、旅をより快適に。そんなスタイルで記事を書いています。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)