【業務自動化】Chapter2-3:置換するファイル形式を選択式にしよう

ながみえ

一つ前のページでは 表記ゆれ置換ツール を作成しました。

今回は 置換対象ファイルをCSVにも拡張 しましょう。

Chapter1:PythonでExcelを操作しよう
Chapter2:PyInstallerで自動化ツールを(.exe)作ろう
 ・Chapter2-1:Pythonスクリプトを実行ファイルに変換しよう
 ・Chapter2-2:表記ゆれを一瞬で直す置換マシンを作ろう
 ・Chapter2-3:置換の対象ファイルを増やそう ◁今回はここ
 ・Chapter2-4:エラー処理を追加しよう
 ・Chapter2-5:ダイアログウィンドウを追加しよう
Chapter3:便利な自動化ツールを5つ作ろう
Chapter4:Webスクレイピング入門
Chapter5:自動化ツールを作って稼ごう

前回の記事では、Excelで管理している「表記ゆれリスト」を使い、テキストファイル内の用語を一括で置換するツールを作成しました。

しかし、実務では扱うデータが必ずしもテキストファイルとは限りません。

CSVファイル(例えば顧客リストや取引履歴など)を対象に同様の置換を行いたい場面もよくあります。

そこで今回の記事では、ユーザーが処理対象のファイル形式(txt / csv)を選べるようにし、CSVにも対応したツールに改良する方法を学びます。

新しく導入する ライブラリはPyInputPlus です。これは入力値をチェックしながら受け付ける外部モジュールで、ユーザーに誤った入力をさせない仕組みを簡単に追加できます。

記事を読み終える頃には、以下のようなスキルが身についているでしょう。

  • 既存のコードを拡張して機能を追加する手順
  • PyInputPlusを使った選択式メニューの作成
  • CSVファイルをPythonで安全に読み書きする方法

<<前のページ

業務自動化の記事一覧

次のページ>>

PyInputPlusとcsvモジュールの使い方解説

サンプルスクリプトを紹介する前に、今回の記事で新たに登場する2つのモジュール、pyInputPluscsv を紹介します。

あわせて読みたい
openpyxl使える関数・メソッド・クラス一覧【Excel自動化の基本リファレンス】
openpyxl使える関数・メソッド・クラス一覧【Excel自動化の基本リファレンス】
【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

pyInputPlusモジュールの紹介

PyInputPlusモジュール は、Python の外部ライブラリで、input()関数を拡張して入力の検証や制御を簡単に行えるようにしたものです。

ユーザーからの入力に対して、型チェック・範囲指定・再入力制御などを組み込みでサポートします。

例えば、pyInputPlusモジュールに含まれる inputInt()関数 を使って入力をすると、入力値が整数でなかった場合は自動的にエラーを出して再入力を促します。

つまり、ユーザーが文字列や浮動小数点数などを入れても、勝手に int()変換エラーで落ちることはなく、エラーメッセージを表示してもう一度入力待ちに入ります。

PyInputPlusのインストール手順とサンプルコード

コマンドプロンプトに以下のコードを打ち込んで、pyinputplusをインストールしましょう。

pip install pyinputplus

インストールができたら、以下のコードをコピーして実行し、いろいろな入力を試してみて下さい。

通常の input()関数より安全(型変換エラーや不正値を防げる)であり、再入力処理のロジックを自分で書かなくて済む点を体感しましょう。

import pyinputplus

# 整数入力(1~10の範囲)
age = pyinputplus.inputInt("年齢を入力してください (1-10): ", min=1, max=10)
print(f"あなたの年齢: {age}")

# 選択肢から入力
fruit = pyinputplus.inputChoice(['apple', 'banana', 'orange'])
print(f"選ばれたフルーツ: {fruit}")

# Yes/No 入力
proceed = pyinputplus.inputYesNo("続行しますか? (yes/no): ")
if proceed == "yes":
    print("続行します!")
else:
    print("終了します。")

PyInputPlus 関数一覧表

PyInputPlusに含まれる主要な関数を、表形式で整理します。

関数名説明
inputStr()文字列入力を受け付ける
inputNum()数値(整数または浮動小数点)を受け付ける
inputInt()整数入力を受け付ける
inputFloat()浮動小数点入力を受け付ける
inputChoice()指定した選択肢から入力させる
inputYesNo()Yes / No の入力を受け付ける(yes/no, y/n)
inputBool()真偽値の入力を受け付ける(true/false, yes/no, 1/0)

自動化ツールを作る際には非常に便利ですので、是非使用していきましょう。

csvモジュールの基本|reader/writerでセル単位の置換

csvモジュール は、Pythonに標準で搭載されている(追加インストール不要)モジュールで、CSVファイル の読み書きを簡単に行うためのツールです。

主な特徴は以下の通りです。

  • テキストファイル形式の CSVファイルを行ごとに読み書き できる
  • 区切り文字(デフォルトは ,)を自由に指定可能(タブ区切りやセミコロン区切りも対応)
  • readerwriter による基本操作

csv.readerの使い方|UTF-8 / BOMなど文字コードの扱い

例えば、単純にCSVファイルを読み込むコードは以下のようになります。

import csv

# CSVファイルを読み込む
with open("data.csv", newline="", encoding="utf-8-sig") as f:	# UTF-8(BOM付き)でファイルを開く
    reader = csv.reader(f)  # リーダーオブジェクトを作成
    rows = [row for row in reader]  # 行をリストに格納

print(rows)

このコードはdata.csvを読み込み、その中身のデータを変数rowsに格納して出力しています。

1.with open(“data.csv”, newline=””, encoding=”utf-8-sig”) as f:
  • "data.csv" というファイルを開いて、変数 f にファイルオブジェクトを代入します。
  • newline="" は改行コードを自動で変換しないようにする設定です。余計な空行が入らないようにするために指定します。
  • encoding="utf-8-sig" はファイルがUTF-8(BOM付き)で保存されている場合でも正しく読み込めるようにする設定です。

この行によって、CSVファイルの中身を読み取れる準備が整います。

2.reader = csv.reader(f)
  • ファイルオブジェクト f を元に、csv.reader を使って CSVの各行を順番に取り出せるオブジェクト を作ります。
  • このオブジェクトからは「1行ずつ」データを取り出せます。
  • 1行は「リスト」として返されます(列ごとに要素が分かれる)。
3.rows = [row for row in reader]
  • reader から全ての行を取り出して、リストにまとめています。
  • これは「リスト内包表記」と呼ばれる書き方で、for row in reader を回して取り出した row を1つの大きなリストに格納します。

結果として rows は「リストの中にリストが入っている形(二次元リスト)」になります。

csv.writerの使い方|安全な上書き防止と新規ファイル出力

単純にCSVファイルに書き込むコードは以下のようになります。

import csv

# 書き込みたいデータ(2次元リスト)
rows = [
    ["名前", "年齢", "出身地"],
    ["太郎", "20", "東京"],
    ["花子", "25", "大阪"]
]

# CSVに書き込み
with open("output.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.writer(f)   # writerオブジェクトを作成
    writer.writerows(rows)   # まとめて書き込み

このコードはoutput.csvを読み込み、変数rowsのデータを書き込んでいます。

1.with open(“output.csv”, “w”, newline=””, encoding=”utf-8-sig”) as f:
  • "output.csv" という名前で新しいファイルを「書き込みモード ("w")」で開きます。
  • newline="" は改行コードを正しく扱うための指定です。
  • encoding="utf-8-sig" にすることで、Excelで開いたときに文字化けを防げます。
2.writer = csv.writer(f)
  • 書き込み専用の writer オブジェクトを作成します。
  • このオブジェクトを使うことで、リストの内容をCSV形式に変換してファイルに書き込めるようになります。
3.writer.writerows(rows)
  • writerows() は 複数行のリストを一度に書き込む メソッドです。
  • rows を渡すと、1つのリストを1行として順に書き込みます。

置換ツールをCSV対応に改良|選択して一括置換

まずは、これまでテキストファイルのみを対象にしていた表記ゆれ一斉置換ツールを、CSVファイルにも対応できるように修正していきます。

具体的には、プログラムの冒頭でユーザーに「txt」か「csv」を選ばせ、その入力値に応じて処理を分岐させます。

今回の学習で使用するxlsxファイルとtxtファイルを配布しますので、↓↓のダウンロードリンクをクリックして適切な場所に保存して下さい。

Q
ファイルの保存場所について

ダウンロードしたファイルは以下の階層になるように保存して下さい。

この理由については、Chapter2-1 の記事で詳しく解説しています。

Chap2/   					# チャプター2全体の保存フォルダ
│
├── Chap2-1/				# チャプター2-1の保存フォルダ
│   ├── Chapter2-1.py
│   ├── Workbooks/
│   │   └── Chapter2-1.xlsx
│   └── Chapter2-1.exe
│
├── Chap2-2/				# チャプター2-2の保存フォルダ
│   ├── Chapter2-2.py
│   ├── Workbooks/
│   │   └── Chapter2-2.xlsx
│   ├──texts/
│   │   └── サンプルテキスト.txt
│   └── Chapter2-1.exe
│
├── Chap2-3/
├── ・・・

サンプルスクリプトの全体像(txt/CSV選択〜一括置換)

以下は、テキストファイルに加えてCSVファイルも置換対象にできるように修正したプログラムです。

ユーザーが起動時に「txt」か「csv」を選択できる仕組みが追加されています。

前回のコードとの相違点は次の章で解説するので、まずはコード全体をコピーして実行してみましょう。

import openpyxl     # xlsxを読み取るための外部モジュール
import pathlib      # ファイルやフォルダのパスを扱うための標準モジュール
import sys          # 実行環境を判定するために使用(py または exe)
import pyinputplus  # 入力値のチェックを行う外部モジュール
import csv          # CSVファイルを読み書きするための標準モジュール

# 実行環境に応じて基準ディレクトリを決定(exeかpyファイルか)
if getattr(sys, 'frozen', False):
    BASE_DIR = pathlib.Path(sys.executable).parent  # exe で動いている場合
else:
    BASE_DIR = pathlib.Path(__file__).parent        # pyファイルとして動いている場合
file_path = BASE_DIR / "workbooks"      # Excelファイルを格納するフォルダ
text_path = BASE_DIR / "input_files"    # 置換するファイルを格納するフォルダ

# Excelファイルを読み込み、シートを選択
book = openpyxl.load_workbook(file_path / "Chapter2-2.xlsx")
sheet = book.active

# 置換するファイル形式を選択
file_type = pyinputplus.inputChoice(["txt", "csv"],
    "置換するファイル形式を選択してください(txt/csv)"
    )

# 置換リスト(Excelから読み込む検索語・置換語)の定義
READ_START_ROW_NO = 3   # データ読み込みを開始する行
OLD_WORD_COL_NO = 2     # 検索する文字列が書かれた列
NEW_WORD_COL_NO = 3     # 置換後の文字列が書かれた列
old_words = []          # 検索する文字列のリスト
new_words = []          # 置換後の文字列のリスト

# Excelから置換リストを読み込む
for i in range(READ_START_ROW_NO, sheet.max_row+1): # データが書かれた全ての行に対して
    old_word = sheet.cell(i, OLD_WORD_COL_NO).value # 検索語を読み取り
    if old_word is None:            # 検索語が空白なら
        break                       # 繰り返しを終了
    old_words.append(str(old_word)) # 検索語をリストに追加

    new_word = sheet.cell(i, NEW_WORD_COL_NO).value # 置換語を読み取り
    if new_word is None:            # 置換語が空白なら
        new_word = old_word         # 検索語をそのまま使う
    new_words.append(str(new_word)) # 置換語をリストに追加

# テキストファイルを処理
file_counter = 0
if file_type == "txt":
    for target_file in text_path.glob(f"*.{file_type}"): # フォルダ内の全てのテキストファイルに対して
        # 改行して置換開始の宣言
        print()
        print(f'{target_file.name}のテキストを置換します')
        # テキストファイルを読み込み、検索語を置換語に置き換え
        file_text = target_file.read_text(encoding = "UTF-8")
        for i in range(len(old_words)):
            file_text = file_text.replace(old_words[i], new_words[i])
        # 新しいファイルを作成
        new_file_path = target_file.parent / f"【表記ゆれ修正済み】{target_file.stem}.{file_type}"
        new_file_path.write_text(file_text, encoding="UTF-8")
        file_counter += 1

# CSVファイルを処理
elif file_type == "csv":
    for target_file in text_path.glob(f"*.{file_type}"):  # フォルダ内の全てのCSVファイルに対して
        print()
        print(f'{target_file.name}のCSVを置換します')

        # CSVを読み込む
        with open(target_file, newline='', encoding="utf-8-sig") as f:
            reader = csv.reader(f)
            rows = [row for row in reader]

        # セル単位で置換処理
        for i in range(len(old_words)):
            rows = [[cell.replace(old_words[i], new_words[i]) for cell in row] for row in rows]

        # 新しいCSVファイルを作成
        new_file_path = target_file.parent / f"【表記ゆれ修正済み】{target_file.stem}.{file_type}"
        with open(new_file_path, "w", newline='', encoding="utf-8-sig") as f:
            writer = csv.writer(f)
            writer.writerows(rows)

        file_counter += 1

# 改行して終了
print()
print(f'{file_counter}ファイル置換完了')
input("Enterキーでプログラムを終了します")

サンプル解説|inputChoice()導入とCSVセル置換の追加点

このスクリプトのポイントを順を追って見ていきましょう。

必要なモジュールの読み込み

import openpyxl     # xlsxを読み取るための外部モジュール
import pathlib      # ファイルやフォルダのパスを扱うための標準モジュール
import sys          # 実行環境を判定するために使用(py または exe)
import pyinputplus  # 入力値のチェックを行う外部モジュール
import csv          # CSVファイルを読み書きするための標準モジュール

ここではプログラムで利用するライブラリ(モジュール)を読み込んでいます。

openpyxl、pathlib、sysについてはここまでの記事で解説済みです。

pyinputplusモジュール は、ユーザーからの入力を検証する外部ライブラリです。

今回のポイントとなる 選択式メニュー を実現するために利用します。

csvモジュール は、CSVファイルを読み書きするための標準モジュールです。

Excel形式とは異なり、CSVは「カンマ区切りのテキストデータ」なので、このモジュールを使うことでセル単位の処理が可能になります。

実行環境に応じた基準ディレクトリの決定とExcel読込

# 実行環境に応じて基準ディレクトリを決定(exeかpyファイルか)
if getattr(sys, 'frozen', False):
    BASE_DIR = pathlib.Path(sys.executable).parent  # exe で動いている場合
else:
    BASE_DIR = pathlib.Path(__file__).parent        # pyファイルとして動いている場合
file_path = BASE_DIR / "workbooks"      # Excelファイルを格納するフォルダ
text_path = BASE_DIR / "input_files"    # 置換するファイルを格納するフォルダ

# Excelファイルを読み込み、シートを選択
book = openpyxl.load_workbook(file_path / "Chapter2-2.xlsx")
sheet = book.active

ここでは、プログラムがどの環境で動いているか(Pythonスクリプトとしてか、exe化された状態か)を判定し、その結果に応じて処理対象フォルダを正しく指定します。

さらに、表記ゆれ置換に必要な Excelファイルを読み込み、シートを操作対象として準備 しています。

Q
詳細解説(過去記事で解説済み)

sysとpathlibを使って、実行環境ごとの基準パス設定します。

  • PyInstallerでexe化した場合は sys.executable を使って実行ファイルの場所を基準にします。
  • Pythonスクリプトとして動かす場合は __file__ を基準にします。

この仕組みによって、Pythonスクリプトでもexeファイルでも同じように動作します。

その後、load_workbook()関数 で既存のExcel ファイル(.xlsx)を読み込み、activeプロパティで開いているシートを取得しています。

置換対象のファイル形式選択|PyInputPlus.inputChoice()の実装

# 置換するファイル形式を選択
file_type = pyinputplus.inputChoice(["txt", "csv"],
    "置換するファイル形式を選択してください(txt/csv)"
    )

ここでは、ユーザーが「txt」ファイルを処理したいのか、それとも「csv」ファイルを処理したいのかを選択できるようにしています。

単純に input() で文字を受け取る方法では入力ミスが起きやすいため、ここでは PyInputPlusモジュールの inputChoice()関数 を使用して、あらかじめ指定した選択肢の中からユーザーに入力させます。

  • 第1引数 ["txt", "csv"]
    → ユーザーが選べる選択肢を定義しています。
  • 第2引数 "置換するファイル形式を選択してください(txt/csv)"
    → 実行時に表示されるメッセージです。

入力された値は file_type 変数に格納され、後の処理(if file_type == "txt": の分岐)に活用されます。

Excelから置換リストを読み込むための準備

# 置換リスト(Excelから読み込む検索語・置換語)の定義
READ_START_ROW_NO = 3   # データ読み込みを開始する行
OLD_WORD_COL_NO = 2     # 検索する文字列が書かれた列
NEW_WORD_COL_NO = 3     # 置換後の文字列が書かれた列
old_words = []          # 検索する文字列のリスト
new_words = []          # 置換後の文字列のリスト

この部分では、Excelに記載された「検索語」と「置換語」を正しく取得するための準備をしています。

どの行・どの列からデータを読み込むのかを変数で指定し、実際に使うための空のリストを用意しています。

この部分は前回のコードと全く同じです。

Excelから検索語と置換語を読み込む処理

# Excelから置換リストを読み込む
for i in range(READ_START_ROW_NO, sheet.max_row+1): # データが書かれた全ての行に対して
    old_word = sheet.cell(i, OLD_WORD_COL_NO).value # 検索語を読み取り
    if old_word is None:            # 検索語が空白なら
        break                       # 繰り返しを終了
    old_words.append(str(old_word)) # 検索語をリストに追加

    new_word = sheet.cell(i, NEW_WORD_COL_NO).value # 置換語を読み取り
    if new_word is None:            # 置換語が空白なら
        new_word = old_word         # 検索語をそのまま使う
    new_words.append(str(new_word)) # 置換語をリストに追加

Excelに記載された表記ゆれ置換リストをプログラム内のリストに取り込んでいます。

3行目以降を1行ずつ確認し、検索語と置換語のペアを old_wordsnew_words に追加していく流れです。

この部分は前回のコードと全く同じです。

テキスト(.txt)を一括置換|表記ゆれ修正と出力ファイル命名

# テキストファイルを処理
file_counter = 0
if file_type == "txt":
    for target_file in text_path.glob(f"*.{file_type}"): # フォルダ内の全てのテキストファイルに対して
        # 改行して置換開始の宣言
        print()
        print(f'{target_file.name}のテキストを置換します')
        # テキストファイルを読み込み、検索語を置換語に置き換え
        file_text = target_file.read_text(encoding = "UTF-8")
        for i in range(len(old_words)):
            file_text = file_text.replace(old_words[i], new_words[i])
        # 新しいファイルを作成
        new_file_path = target_file.parent / f"【表記ゆれ修正済み】{target_file.stem}.{file_type}"
        new_file_path.write_text(file_text, encoding="UTF-8")
        file_counter += 1

テキストファイル(.txt)を順に読み込み、Excelから取得した置換リストに基づいて文字列を修正 しています。

if文がついたことと、ファイル形式を指定する部分が「.txt」⇒「{file_type}」になった点以外は前回のコードと全く同じです。

CSVをセル単位で置換|csv.reader/writerで安全に出力

# CSVファイルを処理
elif file_type == "csv":
    for target_file in text_path.glob(f"*.{file_type}"):  # フォルダ内の全てのCSVファイルに対して
        print()
        print(f'{target_file.name}のCSVを置換します')

        # CSVを読み込む
        with open(target_file, newline='', encoding="utf-8-sig") as f:  # UTF-8(BOM付き)でファイルを開く
            reader = csv.reader(f)          # CSVリーダーを作成
            rows = [row for row in reader]  # 各行をリストに格納(2次元リスト)

        # セル単位で置換処理
        for i in range(len(old_words)):
            # 行ごと(row)にセル(cell)を走査して文字列置換
            rows = [[cell.replace(old_words[i], new_words[i]) for cell in row] for row in rows]

        # 新しいCSVファイルを作成
        new_file_path = target_file.parent / f"【表記ゆれ修正済み】{target_file.stem}.{file_type}"
        with open(new_file_path, "w", newline='', encoding="utf-8-sig") as f:
            writer = csv.writer(f)  # CSVライターを作成
            writer.writerows(rows)  # 置換後のデータを書き込み
        file_counter += 1

この部分ではフォルダ内にあるすべてのCSVファイルを読み込み、指定された文字列を別の文字列に置き換えたうえで、新しいファイルとして保存する処理 をしています。

処理完了メッセージとプログラムの終了

# 改行して終了
print()
print(f'{file_counter}ファイル置換完了')
input("Enterキーでプログラムを終了します")

すべての置換処理が終わったあとに結果をユーザーへ伝え、Enterキーが押されるまでプログラムを終了しないようにしています。

これにより、exe化して実行した場合でも「ウィンドウが一瞬で閉じて結果が確認できない」という問題を避けられます。

PyInstallerでツール化・まとめ

ここまで作成したプログラムは、テキストファイルだけでなくCSVファイルも対象にできるようになりました。

さらに、PyInputPlusを利用してユーザーに選択肢を提示することで、入力ミスを防ぎつつ柔軟な処理が可能になっています。

PyInstallerでスクリプトをツール化しよう

実務で使用するためには、Pythonのソースコードを毎回コマンドラインから実行するのではなく、誰でも簡単にダブルクリックで動かせる実行ファイル(exe形式) にしておきましょう。

この手順についてはすでに 過去の記事で解説済み なので、ここでの説明は省略します。

コマンドプロンプト以下のコードを実行してください。

pyinstaller --onefile Chapter2-3.py

これで、前回と同様にPythonをインストールしていないPCでも実行できるようになります。

作成されたexeファイルを適切な位置に移動させることを忘れないよう注意しましょう。

まとめ

今回の節では、これまでのテキストファイル専用の表記ゆれ置換ツールを拡張し、以下のような進化を実現しました。

  • PyInputPlus を使うことで、ユーザーが選択式でファイル形式を指定できるようになった
  • CSVファイル処理 を追加し、実務でよく使うデータ形式にも対応できるツールになった

つまり今回の学習を通じて、「小さなスクリプトを実務で役立つツールに進化させる」ための第一歩 を踏み出せました。

次の節ではさらに発展させ、ツールにエラー処理を組み込むことで、より信頼性の高い仕上がりを目指します。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいExcel自動化学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

業務自動化の記事一覧

次のページ>>

次のステップ:業務自動化を「実務レベル」まで引き上げたい方へ

このコース(Chapter1〜2)の無料教材では、Python と Excel(openpyxl)を使って「単純作業を自動化する」ための基本的な考え方やコードの書き方を身につけることができます。

ただ、実際の業務で使おうとすると、次のような壁にぶつかりがちです。

  • 社内で使える「ちゃんとしたツール」っぽい形にしたい
  • エラーが出たときに、自分で原因を特定して直せない
  • 副業したくても本当に正しく動くか自信がない

そこで、格安で販売中のChapter3以降では「現場でそのまま使える業務自動化スクリプト」を作りながら学べる構成としました。

そこでは、Chapter2までで学んだ内容を土台にしつつ、

  • 実務でよくあるパターン別のサンプルコード
  • トラブルシューティング(エラーの潰し方)の考え方
  • より高度な自動化を実現するWebスクレイピングの基本
  • 業務自動化スキルを用いて副業で稼ぐための具体的な方法

などを通して、「自分の職場に合わせてカスタマイズできる力」を身につけることを目指します。

教材は↓↓のリンクボタンの販売所で購入するとPDFやpyファイルでダウンロードできます。

もしくは、各学習記事内で会員登録して頂くと、そのままこのサイト内で全ての記事を読めるようになります。

どこよりも安く手実践的なこの教材を、是非ご活用下さい^^

記事URLをコピーしました