本記事は3部構成のシリーズの後編です。

  • 前編(008):なぜ必要か・判定ロジック・Pythonスクリプトの実装
  • 中編(0081):設定のstockphoto.json統合・batファイル作成・Streamlit UIへの組み込み
  • 後編(本記事):発生したエラーと対処・完成構成と運用フロー

前編・中編でスクリプトの実装から設定統合・UI組み込みまでの手順を記録しました。 本記事では実装中に実際に発生したエラーとその対処法、完成した全体構成と推奨する運用フローをまとめます。

発生したエラーと対処

① [DONE]ログが2行出力される

最初の実装では処理完了後のログに [DONE] shudou_delete complete. が2行連続で表示されていました。

[DONE] shudou_delete complete.
[DONE] shudou_delete complete.

原因は、Pythonスクリプト(shudou_delete.py)の末尾に print("[DONE] shudou_delete complete.") を書いていた上に、batファイル側でも処理成功時に echo [DONE] ... >> LOG していたためです。

他のスクリプト(furiwake_okng.pyなど)の実装を確認すると、[DONE] の完了マーカーはbat側だけが書くという規約になっていました。 Python側の最終出力はサマリー情報(チェック対象件数・記入件数・SKIP件数)であり、[DONE] は書きません。 対処としてPythonの末尾の print("[DONE] ...") を削除し、bat側の出力のみに統一しました。

出力担当内容修正後の状態
Python(shudou_delete.py)処理サマリー(件数など)✅ そのまま
Python(shudou_delete.py)[DONE] マーカー❌ 削除
bat(run_shudou_delete_ui.bat)[DONE] マーカー✅ そのまま(こちらが正式)

② ファイル名に先頭・末尾スペースが混入するリスク

Excelのセル値に先頭や末尾のスペースが混入していることがあります。 直接目視では気づきにくく、ファイル名として完全一致にならないため 「ファイルが存在するにもかかわらず手動削除と誤判定される」リスクがあります。

対処として、Excelから取得したファイル名文字列に必ず .strip() を適用してから比較します。 最初の実装時から組み込んでいたため実害は発生しませんでしたが、記録として残しておきます。

file_name = str(file_name).strip().lower()

③ openpyxlの列番号指定はアルファベットではなく1始まりの整数

pandasでは df.iloc[:, 19] のように0始まりで列を指定しますが、 openpyxlでは ws.cell(row=r, column=20) のように1始まりの整数で指定します。 B列は2、T列は20です。

最初にpandasの感覚でインデックスをずらして間違えたため、 設定ファイルの filename_colstatus_col にはExcelのアルファベット列(B=2、T=20)と1対1で対応する1始まり整数を使うよう統一しました。 実際のExcelの列構成を確認するには以下のデバッグコードが有効です。

# 列確認用デバッグコード(本番時は削除)
for col_idx, cell in enumerate(ws[1], start=1):
    print(f"col={col_idx} : {cell.value}")

④ search_rootの設定ミスによる誤判定

テスト環境でフォルダ構成を変えて動かしたとき、search_root の値が実際の画像格納フォルダをカバーしていなかったため、 全ファイルが「存在しない」と判定されて大量の行に「手動削除」が記入されてしまいました。

これはスクリプトのバグではなく設定ミスですが、影響が広範囲に及ぶため事前の注意が必要です。 実行前に search_root の値と実際の画像フォルダのルートが一致しているかを確認してください。 また、初回実行時は本番のExcelではなくコピーで動作確認するのを推奨します。 万一誤記入された場合、[DONE] が出力される前にプロセスを強制停止しても保存はすでに完了しているため、 バックアップから復元が必要になります。

完成した全体構成と運用フロー

今回作成・更新したファイルの一覧です。

ファイル名配置場所内容
shudou_delete.pybat\python\新規作成。ファイル存在チェックとSTATUS自動記入のメイン処理
run_shudou_delete_ui.batbat\新規作成。stockphoto.json を参照して shudou_delete.py を呼び出す
stockphoto.jsonbat\shudou_delete セクションを追記
app.pybat\「🗑️ 手動削除チェック」ページの追加、ログ確認ページのプロセス一覧に追加

batファイルの動作フローをまとめます。

  1. Streamlit UIが run_shudou_delete_ui.bat ログファイルパス で起動
  2. batが stockphoto.json からPython実行パスをPowerShellで取得
  3. python -X utf8 bat\python\shudou_delete.py bat\stockphoto.json を実行
  4. 標準出力・エラー出力をログファイルにリダイレクト
  5. 終了コードが0なら [DONE] をログに書いて終了
  6. Streamlit UIがログファイルを監視して画面にリアルタイム表示

推奨する実行タイミング

手動削除チェックは、目視でのNG除外(画像削除)を行ったタイミングで随時実行できます。 特にOKNG収集(run_collect_exam_ok_ng.bat)の前に実行しておくと、 「空白行=審査結果がまだ出ていない行」という状態を維持でき、残件数の把握が正確になります。 処理の性質上、既存の値を上書きしないため、後からまとめて実行しても問題ありません。

Streamlit UIに追加されたメニュー一覧は007記事から以下のように更新されました。

ページ対応するbat主な機能
📥 データ収集run_collect_exam_ok_ng.batEXAM/OK/NG収集 → history更新 → Excel更新
🤖 AI解析run_analyze_stock.batCLIPスコア算出 + Ollamaメタデータ生成
🔍 アップスケールrun_upscayl_filerename.bat高解像度化 → done移動 → リネーム
📂 OK/NG振り分けrun_furiwake_okng.batExcelSTATUS参照してフォルダ振り分け
🗑️ 手動削除チェック(今回追加)run_shudou_delete_ui.batファイル存在チェックでSTATUS自動記入
📄 出力ファイルCSV・Excel・ログをワンクリックで開く

手動削除チェックを運用に組み込んだことで、Excelの空白行が「審査結果待ちのみ」で構成されるようになりました。 「現在いくつの画像が審査中か」がひと目で把握できる状態になり、 収集スクリプトで取りこぼしが発生していないかどうかの判断もしやすくなっています。 件数が増えるほどこの管理精度の差が効いてくるため、早めに運用フローに組み込んでおくことをお勧めします。

FAQ

「手動削除」と記入された後にファイルを元に戻した場合、自動でクリアされますか?

自動ではクリアされません。スクリプトは書き込みのみを行い、既存の値を削除する処理はありません。 ファイルを元のフォルダに戻した後、Excelの該当セルを手動で空白に戻す必要があります。 その後に再度チェックを実行すれば、そのファイルは「存在する」と判定されるため「手動削除」とは記入されなくなります。

「手動削除」という記入文字列は変更できますか?

変更できます。stockphoto.jsonshudou_delete.marker_text の値を書き換えるか、 Streamlit UIの詳細設定欄から変更してください。「削除済み」「手動除外」など任意の文字列が使えます。 ただし 006記事の振り分け処理など他の処理がSTATUS列の値を参照している場合、 その処理が「手動削除」という文字列をどう扱っているかを確認してから変更してください。

Excelのファイルが開いたままでも実行できますか?

Excelでファイルを開いたまま実行すると、openpyxlによる保存時にファイルロックエラーが発生する場合があります。 実行前にExcelファイルを閉じた状態にしておくことを推奨します。 エラーが発生した場合、チェック自体は正常に行われているため、Excelを閉じてから再実行すると上書き保存が完了します。