チュートリアル

簡単にライブラリーを使用するためのチュートリアルコレクション

チュートリアル»Python»Spire.XLS for Python»変換»Python で TXT ファイルを CSV に変換する方法
2026-10-16

Python で Excel のデータを検索して置換する方法

商品名の改称や部署の統合など、表の中の同じ表記をまとめて直したい場面は少なくありません。数式で参照されているわけではなく、ただ文字だけを新しい名前に揃えたい——そんなとき、Excel の[検索と置換]ダイアログを開いて 1 件ずつ確認していくのは、行数が増えるほど手間になります。

本記事では、Spire.XLS for Python を使用して Python で Excel のデータを検索して置換する方法 を紹介します。シート全体を対象にする場合と、特定のセル範囲に限定する場合の 2 通りを、実際の動作を確認しながら解説します。

クイックナビゲーション

実行環境の準備

本記事のコードは Spire.XLS for Python と plum-dispatch v1.7.4 で検証しています(動作確認は Spire.XLS for Python 16.8.2)。Excel 本体は必要ありません。

pip install Spire.XLS

スクリプトでは、次の 2 行をインポートします。

from spire.xls import *
from spire.xls.common import *

以降のサンプルには、商品別と担当者別の 2 つの集計表を持つブックを使います。金額は数値セル(桁区切り #,##0)で、どちらの表にも「合計」と「合計(税込)」の行があります。

検索と置換の対象になるサンプルブック

検索の基本:FindAllString() が返すもの

置換の前段は検索です。Worksheet.FindAllString() に探したい文字列を渡すと、一致したセルが CellRange のコレクションとして返ります。for 文でそのまま反復でき、各要素はセル範囲なので Text や Style を普段どおり操作できます。

found = sheet.FindAllString("合計", False, False)
print(len(found))          # 見つかったセルの件数

サンプルブックで実行すると、4 件が見つかります。

FindAllString('合計', False, False) -> 4 件
   '売上データ'!A5: '合計'
   '売上データ'!A6: '合計(税込)'
   '売上データ'!A12: '合計'
   '売上データ'!A13: '合計(税込)'

ここで押さえておきたいのが 一致の判定ルールです。実測した挙動は次のとおりです。

  • 大文字と小文字は区別されない — "plan" と "PLAN" は同じ結果になります。区別するオプションはありません。
  • 部分一致である — 「合計」で検索すると「合計(税込)」もヒットします。
  • ワイルドカードや正規表現は使えない — "合*" のような指定は 0 件になります。
  • 比較対象は「表示されている文字列」 — 数値セルは書式を適用したあとの文字列で判定されます。#,##0 を設定した 2,940 のセルは "2,940" でヒットし、"2940" ではヒットしません。

第 2・第 3 引数は数式に関するフラグです(数式を対象に含めるか、その計算結果を含めるか)。文字列セル・数値セルを検索するだけなら False, False のままで構いません。実際、4 通りの組み合わせを試しても結果は同じでした。

なお、数値セルを検索で見つけたあと CellRange.Text を読むと空文字が返ります。 Text が返すのは文字列セルの中身だけだからです。画面に見えているとおりの文字列を確認したいときは、CellRange.DisplayedText を使ってください。

cell = sheet.Range["B5"]
print(cell.Text)           # ''       ── 数値セルでは空
print(cell.DisplayedText)  # '2,940'  ── 画面に見えている文字列

シート全体のデータを置換する

見つかったセルは CellRange なので、書き換えは Text への代入だけで済みます。シート全体を対象にする場合の流れは次のとおりです。

  1. ブックを読み込む
  2. Worksheet.FindAllString() で一致するセルを集める
  3. 見つかったセルをループし、Text に新しい値を代入する
  4. あとから確認しやすいように背景色を付ける
  5. 別名で保存する
from spire.xls import *
from spire.xls.common import *

# Workbook オブジェクトを作成し、ファイルを読み込む
workbook = Workbook()
workbook.LoadFromFile("SampleSales.xlsx")

# 最初のワークシートを取得
sheet = workbook.Worksheets[0]

# 「合計」を含むセルをシート全体から探す
found = sheet.FindAllString("合計", False, False)

# 見つかったセルの値を「総計」に書き換える
for cell in found:
    cell.Text = "総計"
    cell.Style.Color = Color.get_Yellow()

# 別名で保存
workbook.SaveToFile("ReplaceInWorksheet.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

シート全体の「合計」を置換した結果

4 セルすべてが「総計」になりました。ただし、2 つの表の「合計(税込)」も「総計」になっている点に注目してください。FindAllString() は部分一致でセルを拾いますが、Text への代入はセルの中身を丸ごと差し替える操作です。一致した部分だけが置き換わるわけではないため、後ろに続く文字列は失われます。

「合計(税込)」の行はそのまま残したい——そうした場合は「一致した部分だけを置き換える」の方法を使ってください。

特定のセル範囲だけを置換する

商品別の表はそのままにして、担当者別の表だけを直したいこともあります。その場合は Worksheet ではなく、セル範囲に対して FindAllString() を呼びます。書き換えの手順はシート全体のときと同じです。

from spire.xls import *
from spire.xls.common import *

workbook = Workbook()
workbook.LoadFromFile("SampleSales.xlsx")
sheet = workbook.Worksheets[0]

# 置換したいセル範囲を取得(担当者別の表)
target = sheet.Range["A8:D13"]

# その範囲の中だけで「合計」を含むセルを探す
found = target.FindAllString("合計", False, False)

for cell in found:
    cell.Text = "総計"
    cell.Style.Color = Color.get_Yellow()

workbook.SaveToFile("ReplaceInRange.xlsx", ExcelVersion.Version2016)
workbook.Dispose()

セル範囲 A8:D13 だけを置換した結果

対象が 2 件に減り、上の商品別の表は「合計」のまま残っています。範囲は Range["A8:D13"] のようなアドレス指定でも、Range[8, 1, 13, 4] のような行・列指定でも構いません。

一致した部分だけを置き換える

セルの中身を丸ごと書き換えたくない場合は、見つかったセルの現在の値を読み、文字列として差し替えてから代入します。テキストセルであれば CellRange.Text に現在の値が入っているので、Python の str.replace() がそのまま使えます。

found = sheet.FindAllString("合計", False, False)

for cell in found:
    cell.Text = cell.Text.replace("合計", "総計")
    cell.Style.Color = Color.get_LightGreen()

実行すると、次のように「(税込)」が保たれたまま置き換わります。

一致した部分だけを置き換えた結果

シート全体を対象にしてよいなら、Worksheet.ReplaceAll() を使う手もあります。こちらはセルの値の一部だけを差し替え、戻り値として置換件数を返します。第 3 引数は省略できず、2 引数で呼び出すと NotFoundLookupError で停止します。

# シート全体で「合計」を「総計」に差し替える(戻り値は置換件数)
count = sheet.ReplaceAll("合計", "総計", False)
print(count)   # 4

一方、セル範囲に対する CellRange.Replace() は実測では機能しません。 呼び出しても例外は出ず、戻り値は None のまま、値も変化しません。範囲を限定して一部だけを置き換えたいときは、CellRange.FindAllString() で対象を絞り、cell.Text.replace(...) で書き換える形にしてください。

なお、ReplaceAll() は数値セルを文字列に変えてしまいます。桁区切り書式の 1,200 を "2,000" に置換すると、セルは数値ではなく文字列の 2,000 になります。数値を保ったまま書き換えたいときは、FindAllString() で見つけたセルに CellRange.Value を使います。

for cell in sheet.FindAllString("2,940", False, False):
    cell.Value = "3,000"      # 数値として入る(NumberValue は 3000.0)

まとめ

検索から置換までの流れを、あらためて確認します。

  1. 探す — Worksheet.FindAllString() でシート全体、CellRange.FindAllString() でセル範囲から、一致するセルを集める
  2. 書き換える — 見つかったセルの Text に新しい値を代入する。前後の文字列を残したいときは cell.Text.replace() を使う
  3. 印を付ける — Style.Color で背景色を付けておくと、置換箇所をあとから目視で確認できる

判定は「表示されている文字列」に対する部分一致で、大文字小文字は区別されません。ワイルドカードや正規表現は使えないため、複雑な条件で絞り込みたい場合は、いったん全件を取り出してから Python 側で if を書くほうが確実です。

「合計」のような短い語を検索するときは、意図しないセルまで拾いやすい点にも気を付けてください。置換前に found の中身を出力して、対象を一度確認する習慣を付けておくと安全です。

Spire.XLS for Python の全機能を評価したい場合は、30 日間の無料ライセンスを申請できます。なお無償の試用版では、保存したファイルに評価用の警告シートが追加されます。ライセンスを適用するとこれも出力されなくなります。

FAQ

大文字と小文字を区別して検索・置換できますか?

できません。FindAllString() は大文字小文字を区別せずに比較するため、"plan" と "PLAN" は同じ結果を返します。区別するための引数やオプションは用意されていません。大文字小文字を厳密に扱いたい場合は、found の各セルについて CellRange.Text を Python 側で比較し、条件に合うものだけを書き換えてください。

「合計」を含むセルではなく、完全一致のセルだけを置換するには?

FindAllString() に完全一致の指定はないため、見つかったセルを取得したあとに値を比較して絞り込みます。テキストセルであれば CellRange.Text にセルの中身が入っているので、次のように書けます。

found = [c for c in sheet.FindAllString("合計", False, False) if c.Text == "合計"]

この条件では「合計(税込)」は除外され、「合計」だけが書き換わります。数値セルが混ざる可能性がある場合は、CellRange.DisplayedText で比較してください。

数式セルの中身も置換されますか?

数式そのものは検索対象になりません。=1+2 のような数式があるセルを "1+2" で検索してもヒットしません。数式の計算結果を対象にしたい場合は、Workbook.CalculateAllValue() で計算させたうえで、第 2・第 3 引数を両方 True にします。実測では、この組み合わせのときだけ =CONCATENATE("合","計") のセルが「合計」でヒットしました。

ブック内の複数のシートをまとめて置換できますか?

できます。FindAllString() はワークシート単位のメソッドなので、シートを順に処理します。このとき for sheet in workbook.Worksheets で反復しないでください。 反復で得られるのは XlsWorksheet という別のオブジェクトで、FindAllString() を持っていません。インデックスで取得します。

for i in range(workbook.Worksheets.Count):
    sheet = workbook.Worksheets[i]
    for cell in sheet.FindAllString("合計", False, False):
        cell.Text = "総計"

数値セルを置換したら文字列になってしまいました。

Worksheet.ReplaceAll() は値の一部を文字列として差し替えるため、数値セルが文字列に変わります(桁区切り書式の 1,200 を "2,000" に置換すると、セルは文字列の 2,000 になります)。数値のままにしたい場合は、FindAllString() で見つけたセルに CellRange.Value で代入してください。cell.Value = "3,000" のように桁区切りを含む文字列を渡しても、数値の 3000 として格納されます。

置換したセルにだけ色を付けられますか?

付けられます。見つかったセルは CellRange なので、CellRange.Style.Color に色を代入します。Color.get_Yellow() や Color.get_LightGreen() のように名前付きの色を指定できます。塗りつぶしではなく文字色を変えたい場合は Style.Font.Color、太字にしたい場合は Style.Font.IsBold を使ってください。

Read 1 times