「あの内容」が書かれたファイルを探し始めたが、なかなか見つからず一日の大半を使ってしまった経験は誰でも一度はあるかと思います
ファイル名であればすぐに検索できますが、ファイルの中身となると、一旦ファイルを開いて検索する必要がありますね
ここでは「あの内容」が書かれたファイルを高速で見つける方法について解説します
動画の説明
先ずはどのようなことができるかについて、下記の動画をご覧ください
状況
デスクトップに、フォルダが2つ
各フォルダには、ファイルが各10個
これらのファイルのどこからに検索したいキーワード(ここでは、「ノブシゲ」「nobby」)があります
Pythonを起動
デスクトップにあるフォルダ内のファイル内に、キーワードが書かれている箇所を検索します
検索した結果を表示
・キーワードのヒット数
・キーワードが存在する場所(フォルダ、ファイル、シート、レンジ)
Pythonを使用する理由
このようにファイルの中身を検索することは、エクセルVBAでも可能です
しかしながら筆者は、Pythonを使用することをおすすめします
なぜならば、圧倒的に早い!からです
先程の動画では、処理を開始してから終了するまでにかかった時間は、約0.2秒です
では、同じ処理をエクセルVBAで実行してみましょう(下記の動画をご覧ください)
処理を開始してから終了するまでにかかった時間は、約10秒です
約50倍の違いがあります
また、コードも少なくかけるというメリットがあります
今回の場合、13行
エクセルVBAの場合は、82行でした
Pythonのメリットをまとめると
- 処理速度が速い
- コードが少なくかける
となります
Pythonが速い理由
エクセルVBAを使った場合にかかった時間 10秒の内訳を見ていくと
10秒中 約9.9秒は、エクセルファイルを開く処理に使われています
処理時間の約99%が、ファイルを開く処理にかかっているというわけですね
エクセルVBAとPythonでは、ファイルを開くときに下記の違いがあります
- エクセルVBAは、Excelブックのすべてを読み込んでいる
- Pythonは、Excelブックのxmlだけを読み込んでいる
xml
<div> ~ </div>
のように表現されるマークアップ言語です
文字や文字の位置情報など検索に必要な情報だけ読み込んでいるいます
参考サイトwikipedia
Pythonが読み込んでいるデータが少ないため処理時間が節約できています
Pythonのデメリット
エクセルVBAと比較した場合、Pythonは初期設定がちょっと必要です
エクセルVBAの場合は、Microsoft Office がインストールされていればすぐに始められますが
Pythonの場合は、Pythonやエディタのインストールと設定が必要になります
Pythonの初期設定については下記の記事をご覧ください
![](https://nobushige.com/wp-content/uploads/2022/12/Python-160x90.jpg)
コードの説明(Python)
先ずはPythonのコードの全体です 全体で17行のコードがあります
import openpyxl as excel
import os
import time
start = time.time()
PATHS = [r'C:\Users\●●●●\Desktop\フォルダ1\\',r'C:\Users\●●●●\Desktop\フォルダ2\\']
KEYS = ['ノブシゲ','nobby']
for key_ in KEYS:
for path_ in PATHS:
for fn in os.listdir(path_):
wb = excel.open(os.path.join(path_,fn))
for ws in wb.worksheets:
for rows in ws.iter_rows(ws.min_row, ws.max_row, ws.min_column, ws.max_column):
for cell in rows:
if str(cell.value) in key_:
print(key_,os.path.basename(os.path.dirname(path_)),fn,ws.title, cell.coordinate)
end = time.time()
print(format(end - start))
●●●● の箇所は、ご使用しているPCによって異なります 各コードを見ていきます import openpyxl as excel import os import time import ~ で、Pythonのライブラリを呼び出しています openpyxl、os、time が、それぞれライブラリです これらライブラリを呼び出すことでここから以下の処理が実行できるようになっています ~ as ・・ で、ライブラリの名前を別名に置き換えています openpyxl as excel は、openpyxl を excel という名前に置き換えています こうすることで、文字数の長い openpyxl の代わりに、文字数の短い excel を書くことで openpyxl のライブラリを使用することができるようになります
ライブラリ 特殊な機能をもった関数やクラスをまとめたもの Pythonでは目的にあったライブラリを呼び出してそれを使うというのが一般的な使い方です 参考サイトwikipedia
start = time.time()
処理の開始時の時間を start という変数に代入しています 処理の最後にも時間を取得して処理全体の経過時間を取得します
PATHS = [r'C:\Users\●●●●\Desktop\フォルダ1\\',r'C:\Users\●●●●\Desktop\フォルダ2\\']
KEYS = ['ノブシゲ','nobby']
●●●● の箇所は、ご使用のPCによって異なります
PATHS という配列に、2つのパスを格納しています 角カッコ”[ ]” の中に、値を入れることで、配列が作れます 値を追加するときは、カンマ”,”で区切ります 今回は 2つフォルダを検索するため、フォルダ1 と フォルダ2 のパスを格納しています 同様に、KEYS という配列に、2つの検索ワードを格納しています
配列 複数の値を、1つの変数や定数に格納するときに使用します 参照サイトwikipedia
for key_ in KEYS:
for 変数 in 配列 : で、変数に配列の値を代入しながら、以下の処理を繰り返しています KEYS には、2つ分の検索ワードが格納されていますので、1つずつ key_ という変数に代入しています 今回の場合は、先ず”ノブシゲ”(検索ワード)について検索を行い、次に”nobby”(検索ワード)について検索しています
for path_ in PATHS:
こちらも上記同様に、for 変数 in 配列 : で、変数に配列の値を代入しながら、以下の処理を繰り返しています PATHS には、2つ分のフォルダのパスが格納されていますので、1つずつ path_ という変数に代入しています 今回の場合は、先ずフォルダ1について検索を行い、次にフォルダ2の検索を実行しています
for fn in os.listdir(path_):
path_ の中に格納されているフォルダ内のファイル名を一つずつ fn という変数に格納しています
wb = excel.open(os.path.join(path_,fn))
path_ に格納されたフォルダ内の fn に格納されたファイル名 を読み取っています 読み取ったファイルを wb という変数に格納しています
for ws in wb.worksheets:
wb に格納されたファイル内のワークシートを一つずつ ws という変数に格納しています
for rows in ws.iter_rows(ws.min_row, ws.max_row, ws.min_column, ws.max_column):
ws に格納されたワークシート内の行(複数のセル)を一つずつ rows という変数に格納しています .min_row、.max_row、.min_column、.max_column はそれぞれ .min_row:使用範囲の最小行 .max_row:使用範囲の最大行 .min_column:使用範囲の最小列 .max_column:使用範囲の最大行 を意味しています ワークシート内のすべてのセルを検索するのではなく、文字が存在するセルのみを検索するようにしています こうすることで処理速度を速くしています
for cell in rows:
rows に格納された行(複数のセル)の(単一の)セルを一つずつ cell という変数に可能しています
if str(cell.value) in key_:
if “条件” : で、”条件” に一致する場合、以下の処理を実行します 「cell に格納された文字列に、key_(検索キーワード)が含まれる」ことが条件となります
print(key_,os.path.basename(os.path.dirname(path_)),fn,ws.title, cell.coordinate)
print(~) で、コマンドプロンプトに “~” の部分を表示させます ここでは、
- 検索キーワード
- フォルダ名
- ファイル名
- シート名
- セルのアドレス
を表示させています
end = time.time()
全体の処理の最後の時間を end という変数に格納しています
print(format(end - start))
全体の処理にかかった時間を表示させています
Pythonの起動方法
Win + “test” + enter
test.bat ファイルを起動させています
- Windowsキー押下
- “test” キーイン
- Enterボタン押下
Windowsキー Windows 対応のキーボードにWindows のロゴマークが印字された特殊キー (通常)左下側にあります
▼ Windowsキーの場所とビジュアルの一例です
![Windowsキーの場所と画像の例](https://nobushige.com/wp-content/uploads/2022/07/Python_find_4.jpeg)
test.bat という バッチファイルを呼び出しています
このバッチファイル内に、今回のPythonコードを起動させるコードを書いています
これにより
- バッチファイルを呼び出す = Pythonコードを起動させる
としています
コードの説明(batファイル)
全体のコードです
cd C:\Users\●●●●\Documents\Python\public_package
python test.py
pause
一つずつコードを見ていきます
cd C:\Users\●●●●\Documents\Python\public_package
●●●● の箇所は、ご使用のPCによって異なります
cd ~ で、フォルダに移動します ここでは、Pythonファイル(test.py)があるフォルダに移動しています 筆者のPCでは、上記のフォルダにPythonファイルを置いています 読者様の場合は、読者様のPCにPythonファイルがあるフォルダを設定してください
python test.py
python ~ で、Pythonファイルを起動させます
pause
コマンドプロンプトが閉じないように一時停止させています
コマンドプロンプト マウスやアイコンの代わりに文字入力によりPCを操作するために表示する画面です 参考サイトwikipedia
▼ コマンドプロンプトのビジュアルの一例です
![コマンドプロンプトの画面の一例](https://nobushige.com/wp-content/uploads/2022/07/Python_find_5-300x157.jpg)
この記事で使用したファイル
ここで使用したファイルについてこちらから入手できます Pythonファイルや検索したいフォルダの保存場所は、読者様のPCによって違ってきます そのためこれらの箇所については書き換えてご使用をお願いします
この記事ではPythonでファイルの中身を検索する方法について解説しました
筆者は、はじめこの作業をエクセルVBAで処理していました。このときは、手作業よりも楽チンだと感じ満足していました
しかしながら、しばらくするとちょっと時間がかかるのが気になり始めました
そして、もっと早く検索する方法がないかを模索している中 Pythonに出会い
圧倒的な処理速度に感動しました
この記事を読んでくださった読者様も同じような感動を味わっていただけると幸いです
今後もPythonの魅力をお伝えする記事を掲載していきますので、楽しみにしていてください
コメント