Excelでは開けるのに、プログラムでは読めなかった

Excelでは開けるのに、プログラムでは読めなかった|月次の照合作業を自動化した話

月に一度、2つのデータを突き合わせる作業 月次でやっている確認作業がある。 システムに登録された案件のデータと、正しい情報がまとまった台帳。この2つを突き合わせて、登録した時点で正しい請求先が書かれていたかを1件ずつ確認する。書かれていなかったものは後で直さなければならないので、洗い出しておく必要がある。 判断はそう単純ではない。番号で書かれているものもあれば、会社名だけ書かれているものもある。書き方が少し違うだけで実質は合っているケースもある。そもそも確認の対象外にしている取引先もある。 つまり**「これは合っている、これは違う」を人の目で判断していく作業**で、件数がまとまると相当に骨が折れる。これをなんとかしたかった。 最初の壁:Excelでは開けるのに、プログラムでは読めない 作業の入り口は、システムからデータをExcel形式で書き出すこと。これをプログラムで読み込んで処理する——そのはずだった。 ところが、読み込もうとするとエラーになる。**「このファイルは壊れています」**と言われる。 不思議なのは、同じファイルをExcelで開くと普通に開けることだ。中身も正常に見える。壊れているようにはまったく見えない。 「じゃあこっちの書き方が悪いんだろう」と思って何度も試したが、どうやっても読めない。ここでかなり時間を使った。 Excelファイルは、実は「圧縮ファイル」だった 原因を調べる過程で、自分が知らなかったことを知った。 **Excelファイル(.xlsx)は、中身が複数のファイルに分かれていて、それをひとまとめに圧縮した"箱"**なのだ。ZIPと同じ仕組みで、拡張子を.zipに書き換えれば中を覗くこともできる。 そして箱の中には、「どこに何が入っているか」を示す目次が付いている。 今回のファイルは、この目次の部分が壊れていた。 Excelは寛容だった:目次が怪しくても、中身を自力で探しに行って開いてくれる プログラムは正直だった:目次を信じて読もうとするので、「目次が壊れている=このファイルは壊れている」と判断して止まる つまりどちらも正しい動作で、「Excelで開けるから正常なファイル」とは限らないということだった。 目次を作り直して読ませた 対処は、箱の目次を無視して中身を頭から順に探し出し、目次を付け直すという方法をとった。 ファイルの中には、部品の始まりを示す決まった印がある。それを全部拾い出して、正しい構造に組み立て直す。そうすればプログラムからも普通に読めるようになる。 正直、この対処は自分ひとりでは絶対にたどり着けなかった。「Excelでは開けるのにプログラムでは読めない」という症状を伝えたら、Claudeが「ファイルの構造そのものが壊れている可能性がある」という筋を出してくれた。 自分にはそもそも「Excelファイルの中に目次がある」という知識がなかったので、疑うことすらできなかった。 前にも書いたが、非エンジニアがいちばん助かるのは「自分が知らないから疑えないこと」を出してもらえる場面だと思う(ClaudeとCopilotの比較でも同じことを書いた)。 本題:人の曖昧な判断を、ルールに落とす ファイルが読めるようになってからが本題だった。 これまで目でやっていた照合を、機械に任せるにはルールを言葉にしなければならない。やってみて気づいたのは、自分がやっていた判断は「合っている/違う」の2つではなかったということだ。 整理してみると、実際にはこうなっていた。 判定 どういう状態か 一致 正しい番号がきちんと書かれている 不一致 番号は書かれているが、正しいものと違う 名称のみ記載 番号はないが、取引先の名前は書かれている 名称のみ(ニュアンス) 名前の書き方が少し違うが、実質は合っていそう 記載なし 何も書かれていない 対象外 もともと確認の対象にしていない取引先 自分で無意識にやっていた判断を並べてみると、あいだの段階がいくつもあった。これに気づけたのが一番の収穫だったかもしれない。 「ニュアンス一致」という段階を作った いちばん悩んだのが4つ目の**「書き方が少し違うが、実質は合っていそう」**というケースだ。 会社名の書き方は揺れる。「株式会社」が付いているかどうか、略称で書かれているか、前後に余計な文字が付いているか。人が見れば同じだと分かるが、文字として完全に一致はしない。 これを「不一致」に入れてしまうと、要確認の山に大量の"実は問題ない案件"が混ざる。かといって「一致」にしてしまうと、本当に違うものを見逃すかもしれない。 そこで、専用の段階をひとつ作った。「たぶん合っているが、機械が断定はしない」という置き場所だ。 これは前回の記事で書いた「迷ったら要確認に入れる」と同じ考え方だ。白黒つけられないものを無理にどちらかへ寄せず、グレーの箱を用意する。 曖昧なものを扱うときは、これがいちばん事故が少ないと思う。 出てくるのは、色分けされた1つのExcel 処理が終わると、Excelファイルが1つ出てくる。中は9枚のシートに分かれている。 全体の集計(何件中、何件が要確認か) 全件の一覧(判定ごとに色分け) 要確認のものだけを集めたシート そのほか、判定ごとのシート 判定は色で分けてある。合っているものは緑、はっきり違うものは濃い赤、何も書かれていないものは赤、対象外はグレー。 狙いは全件を見なくて済むようにすることだ。以前は全部に目を通していたが、今は「要確認」のシートだけ開けばいい。 これも前に書いた話とつながる。書類の仕分けの記事で「人が見る場所を1か所に絞ることのほうが価値がある」と書いたが、今回も同じだった。自動化の成果は"作業が消えること"だけでなく、“見るべき場所が減ること"にもある。 今は「照合して」と伝えれば、このExcelが出てくるところまで自動になっている。 まとめ この作業から学んだことを3つ。 「Excelで開けるから正常」とは限らない。 システムが書き出したファイルは、見た目が普通でも中身が壊れていることがある 自分の判断を書き出すと、思っていたより段階が多い。 「合っている/違う」の2択でやっているつもりで、実は5〜6段階の判断をしていた グレーの箱を用意する。 白黒つけられないものを無理に寄せず、専用の置き場所を作ったほうが結果的に速い そして毎回思うのだが、詰まったときに効くのは「自分が知らないことを疑ってもらえる」ことだった。Excelファイルの中に目次があるなんて、この作業をするまで知りもしなかった。知らないことは疑えない。そこを埋めてもらえるかどうかが、非エンジニアが自動化を進められるかの分かれ目になっていると思う。

2026年8月15日 · 1 分
Salesforceの未連携チェックを自動化した

Salesforceの未連携チェックを自動化した|CSV連携でハマった6つの罠

「朝にしかできない仕事」だった Salesforceに登録された作業実績が、別の仕組みに正しく連携されているか。連携に失敗したものが残っていないか。これを毎日確認する仕事があった。 厄介だったのは、この確認が朝にしかできなかったことだ。 データを集計するバッチ処理が夜間に走る。だから前日分の結果が出揃うのは朝。そして確認した内容は朝礼で共有する必要がある。つまり毎朝、出社してから朝礼までのあいだに、Salesforceを開いてレポートを出して、未連携のものを拾い出す——という作業が固定で入っていた。 自動化の価値は「時短」だけではなかった こういう話を書くとき、たいていは「作業時間が何分減りました」という数字を出すものだと思う。ただ、今回いちばん効いたのはそこではなかった。 朝のいちばん忙しい時間帯を、この作業のために空けておかなくてよくなった。 作業そのものの時間が長いわけではない。それでも「朝礼に間に合わせなければならない」という制約があると、その時間は他のことに使えない。別の急ぎが入れば焦るし、遅れれば朝礼に響く。時間の"長さ"ではなく"時間帯"を拘束されることの負担は、実際にやっている人にしか分かりにくい部分だと思う。 自動化してからは、朝礼の前にはもうTeamsに一覧が届いている。自分が何時に出社しようが関係ない。この安心感が、削減できた分数よりずっと大きかった。 同じように「たいした時間じゃないから」と我慢している作業がある人は、時間の長さではなく"いつやらなければいけないか"で見直してみるといいかもしれない。 作ったもの 構成はシンプルだ。 Salesforce のレポート(毎日 自動実行) ↓ CSVを添付したメールが届く Power Automate ├ メールを受け取る(差出人と添付で判定) ├ CSVを1行ずつの形に分解する ├ 連携に失敗している行だけを抜き出す ├ 必要な4項目だけを取り出す └ 表の形にしてTeamsに投稿 Salesforceにはレポートを定期実行して結果をメールで送る機能がある。まずこれで毎日CSVが自分宛に届くようにして、そのメールをPower Automateが受け取って処理する、という流れだ。 なぜCSVとメールなのか 見ての通り、かなり古典的なやり方だ。今どきシステム同士を繋ぐならもっとスマートな方法がある。それでもこうした理由は2つある。 ひとつは、Claudeから直接Salesforceを触ることが、この時点ではできなかったこと。以前に社内環境で「何ができて何ができないか」を調べたときの結論がそのまま効いている(詳しくはこの記事に書いた)。 もうひとつは、メール経由なら管理者に頼まずに自分で組めたこと。システム同士を直接つなぐ設定には管理者の権限が要る。一方「レポートをメールで受け取る」「届いたメールを処理する」だけなら、一般ユーザーの権限で完結する。 つまりこれは、制約の中で自分だけで完結させるための選択だった。理想の構成ではないが、動くものが今日できることのほうが大事だと判断した。 ハマった6つの罠 ここからが本題。Power Automateの式を書く部分で、想像の3倍くらい詰まった。同じところで止まる人が絶対にいると思うので、全部書いておく。 罠1:文字化けする 届いたCSVの中身が文字化けした。原因はSalesforce側のCSV出力がShift-JISという古い文字の形式になっていたこと。 解決:Salesforceのレポート設定でエンコードをUnicode(UTF-8)に変更した。処理する側で頑張るより、出す側を直したほうが早い。 罠2:CSVが1行の塊のまま分解できない CSVを行ごとに分けようとしたのに、全部がひと繋がりのまま出てくる。改行で区切っているつもりが区切られない。 原因は改行の正体がCR+LFという2文字の組み合わせだったこと。単純な改行文字で切ろうとしても一致しない。 解決:区切り文字を直接指定する形にした。 split(base64ToString(items('For_each')?['contentBytes']), decodeUriComponent('%0D%0A')) 呪文にしか見えないと思うが、意味が分からなくても問題ない。自分も細部は分かっていない。「CSVが1行にまとまってしまう」ときはこの形と覚えておけば足りる。 罠3:フィルターが全件を通してしまう 「連携に失敗した行だけ」を抜き出したいのに、全部の行が通ってしまう。条件が効いていない。 原因は、CSVの中の値が 0 ではなく "0" だったこと。前後にダブルクォートが付いていて、見た目は同じでも別物として扱われていた。 解決:比較する前にクォートを取り除く。 @and(greater(length(split(item(), ',')), 8), equals(trim(replace(split(item(), ',')[8], '"', '')), '0')) 「見た目は合っているのに一致しない」ときは、たいてい目に見えない何かが混ざっている。前にも列名に改行が紛れ込んでいて同じ目に遭った。この手の問題は本当に気づきにくい。 罠4:Teamsに「True」とだけ届く 通知が動いた。喜んで見たら、Teamsに投稿されていたのは True の1単語だった。 原因は、投稿する内容を選ぶところでメールのHTML本文のほうを間違って選んでいたこと。似た名前の項目が並んでいて、正しいものを選べていなかった。 解決:選択肢の検索欄で「テーブル」と検索して、目当ての出力を選び直した。Power Automateは選択肢が大量に並ぶので、目で探さず検索するのが確実だった。 ...

2026年8月15日 · 1 分