本業で、更新指示のExcelを投げ込むとページ用のHTMLが出てくるツールを、AIと一緒に作りました。
自分はエンジニアではありません。コードは書けません。書けませんが、「何がしたいか」と「何がおかしいか」は言えます。その2つだけでツールは形になりました。
ところが、出てきたHTMLを実際のページに貼ってみたら。
バナー画像が、ひとつも表示されませんでした。
原因はバグではありませんでした。設計の出発点が間違っていただけです。そして出発点をひっくり返したら、機能は何ひとつ足していないのに事故が止まりました。
この記事はその入れ替えの記録です。HTMLの話として書きますが、Excelの台帳を一括更新するマクロでも、設定ファイルを書き換えるスクリプトでも、まったく同じ話になります。「今あるものに、変更点のメモを当てる」作業は、全部この構造をしています。
この記事で持ち帰れること
① 更新ツールが壊れる、いちばんよくある原因
② 「何も変えない」を先に作ると、それがそのままテストになるという考え方
③ 位置ではなく中身で照合する方法(そのまま使えるコード付き)
④ 自分のツールを点検するチェックリスト5項目
⑤ 非エンジニアがAIに頼むときの、言い方の違い
やっていた作業
週に一度、あるページに並んでいるバナーの一覧を差し替える作業です。指示は色付きのExcelで来ます。
- 黄色のセル=新しくする/差し替える
- 青のセル=消す
- 色なし=そのまま置いておく
ページは30枚以上、バナーは合計200本以上。これを毎回、手でHTMLに書き起こしていました。時間もかかるし、手で書く以上どこかで打ち間違えます。
だからツールを作りました。ここまでは、たぶんよくある話だと思います。
最初に作ったもの:更新資料を「正」にした
素直に作りました。Excelを読む → HTMLを組み立てる。それだけです。
動きました。ちゃんとHTMLが出てきました。出てきたので、本番に貼りました。そして画像が消えました。

資料に書かれていないことは、ツールにとって「存在しない」
理由が分かってみれば、あたりまえの話でした。
▼ 資料に載っていなかった情報
- 資料の画像欄に書いてあるのは 「秋の特集バナー」のような呼び名。実際のファイル名(
bnr_autumn_2026_536x536.jpgのようなもの)とは別物 - そのリンクを別窓で開くかどうかは、資料のどこにも書かれていない
- 画像の置き場所のルールも書かれていない。今まで人間が覚えていた
つまり、更新資料には現物の情報が全部は載っていないのです。人間は足りない分を頭の中で補いながら作業していました。それをそのまま機械にやらせたので、補われないまま、空っぽで出てきた。ただそれだけでした。
更新資料は「変更点のメモ」であって、「正解そのもの」ではない
メモを正解として扱うと、メモに書かれていない部分が全部ゼロになります。これが今回の事故の正体でした。
しかもタチが悪いのは、ツール自体は正常に動いていたことです。エラーも出ません。「Excelの内容を反映したHTML」としては、完璧に正しいものが出ていました。間違っていたのは仕様のほうでした。
直し方:出発点をひっくり返す
作り直した手順は、たった2つです。
- 今のページから全部読み取って、そのままHTMLに組み直す(=現物のコピーを作る)
- そこに更新資料を当てて、指定された所だけ差し替える
やっていることは前と同じに見えますが、決定的に違う点があります。資料に書かれていない情報が、①で先に全部そろっていることです。②で上書きされなかった情報は、現物のものがそのまま残ります。だから空っぽになりません。
①で「差分ゼロ」が出せることが、そのままテストになる
これがこの設計の、いちばんおいしいところです。
①だけを動かして出したHTMLは、今の本番と1文字も違わないはずです。違ったら、それはツールが現物を読み違えている証拠になります。人間が判定する必要すらなく、文字列を比べるだけで分かります。
実際にやってみたら、現物のソースと1行ずつ比べて45行中44行が完全一致しました。

残った1行は、ツールのバグではありませんでした。現物側の書き方がそろっていなかったのです。同じ種類の画像なのに、1本だけパスの書式が違っていました。長年いろんな人が更新してきたページなので、こういうゆれが混ざります。
つまりこの比較は、ツールのテストであると同時に、現物の健康診断にもなっていました。差分ゼロを目指すと、一致しなかったところが全部「見るべき場所」として出てくるからです。
言い方を変えると、こうなります。
「何も変えない」ボタンが無いツールは、変えた結果が正しいかどうかを確かめる基準を持っていない。
落とし穴その2:位置で対応づけない
最初のツールは、「資料の3行目 → ページの3本目」という具合に、並び順で対応づけていました。これが盛大に外れます。
理由は単純で、現物は自分の知らないうちに更新されているからです。今回も、30枚あるページのうち9枚が、資料が作られたあとに別の担当者の手ですでに更新済みでした。3本目はもう3本目ではありません。
なので、位置を捨てました。代わりに中身で探します。
// 資料の1行に対応する「現物のバナー」を、中身で探す。
// 位置(index)は一切使わない。現物は勝手に動いているから。
function findByContent(want, list, taken) {
const keys = [
x => normUrl(x.url), // ① 遷移先URL … いちばん変わりにくい
x => normText(x.text), // ② 表示している文言
x => normText(x.image), // ③ 画像のファイル名 … いちばん揺れる
];
for (const key of keys) {
const k = key(want);
if (!k) continue;
const i = list.findIndex((x, idx) => !taken[idx] && key(x) === k);
if (i >= 0) { taken[i] = true; return list[i]; } // 一度使った現物は再利用しない
}
return null; // どれにも当たらない = これは新しく足すもの、と判断できる
}
ポイントは照合の順番を「変わりにくいもの順」に並べることです。リンク先URLは滅多に変わりません。文言は少し変わります。ファイル名はいちばんよく変わります。だからこの順で試して、当たったところで止めます。
taken で「一度使った現物」に印を付けているのも大事な部分です。これが無いと、同じような文言のバナーが2本あったときに、両方が同じ現物に吸い寄せられます。
そしてどれにも当たらなかったものは「新規」と判断できます。わざわざ資料に「これは新規です」と書いてもらう必要がなくなりました。
落とし穴その3:2回流しても同じ結果になるか
同じ資料を2回流したら結果が変わるツールは、怖くて使えません。「もう反映したっけ?」が分からなくなるからです。
これも1か所直すだけで解決しました。
// 資料から組み立てた結果が、現物とまったく同じだったら、
// 現物のほうをそのまま採用する(=「変更した」と数えない)
if (現物にあった && 組み立てた結果 === 現物のまま) {
結果.push(現物のもの);
return;
}
たったこれだけで、すでに反映済みのページが自動的に「変更なし」に落ちます。実際、2回目を流すと「更新されるページ:0枚」と表示されます。
こうなると気が楽です。迷ったらもう一回流せばいいので、「反映済みかどうか」を人間が覚えておく必要がなくなりました。作業の記憶を人間が持たなくてよくなるのは、思っていたよりずっと効きました。
うれしい誤算:正しい状態を機械が持つと、資料の間違いが浮いてくる
これは狙っていなかった副産物です。
現物という基準を機械が持った瞬間、更新資料側の間違いが、勝手に浮かび上がってきました。
| 資料に書かれていたこと | 機械の反応 |
|---|---|
| 画像名の欄に「テキスト・URL変更」という指示文が書いてある | その名前の画像は現物に無い → 現物の画像を使い、警告を出す |
| テスト環境のURLがそのまま残っている | 本番URLに直したうえで警告を出す |
| 実在しないファイル名が書いてある | 現物のどれにも当たらない → 警告を出す |
| 「消して」と書かれているが、現物にもう無い | すでに消えている → 警告を出す |
| 並び順の番号が重複している | 順番が決まらない → 警告を出す |
どれも、人間が目視で見つけるのはしんどい種類の間違いです。画像名の欄に指示文が書いてあるミスなど、印刷して見比べても気づける気がしません。
「正しい状態」を持っている側からしか、間違いは見えない
資料だけを見ていても、資料の間違いは見つかりません。現物と突き合わせて初めて「これは合っていない」と言えます。チェックツールを別に作らなくても、この設計にした時点でチェック機能が付いてきました。
持ち帰り:更新ツールの点検チェックリスト
自分のツール(あるいは誰かが作ってくれたツール、AIに作らせたツール)を点検するなら、この5つだけ見れば足ります。
更新ツール 点検リスト
- 「何も変えない」状態を出力できるか。それは現物と一致するか
- 資料に書かれていない情報を、現物から引き継げているか
- 並び順ではなく、中身で照合しているか
- 同じ資料を2回流して、結果が同じになるか
- 反映する前に「どこが何行変わるか」が見えるか
1つでも「いいえ」があるなら、そこが次に事故る場所です。ちなみに自分は、1〜5すべてが「いいえ」のツールを作って、まんまと事故りました。
とくに5番は地味ですが効きます。「このページは60行中1行だけ変わります」と先に見えるので、貼ったあとに確認する場所が一気に絞れます。全部を見比べる必要がなくなりました。
非エンジニアがAIに頼むときの、言い方の違い
自分はコードが読めません。それでもこの作り直しは頼めました。言い方を変えただけです。
| 最初に言っていたこと | 言い直したこと |
|---|---|
| 「このExcelを読んでHTMLを作って」 | 「まず今のページを読み取って、それだけで今とまったく同じHTMLが出せることを先に確かめて。そのあとExcelで上書きして」 |
| 「画像が出ないから直して」 | 「画像のファイル名は現物のほうが正しい。資料の名前を使っていいのは、新規のときだけ」 |
| 「うまく当たらないんだけど」 | 「順番で対応づけるのをやめて、中身で探して」 |
共通しているのは、「何を正しいことにするか」を人間の側が決めて渡している点です。
ここはAIには決められません。「現物と資料、どちらを勝たせるか」は業務の事情そのものなので、現場を知っている人にしか決められない。逆に言えば、非エンジニアでもここだけは自分で決めないといけない部分です。
コードは1行も書けなくても、「本番が正です」の一言は言えます。実際、その一言でツールは作り直されました。
似たような話は、Chromeサイドパネルにブックマークレットを集約する拡張機能を作ったときや、祝日つきカレンダー時計を自作したときにもありました。うまくいくときは、たいてい仕様の一番大事なところを人間が言語化できたときです。逆にAntigravityで3Dゲームを作ろうとして失敗したときは、そこが曖昧なまま「いい感じにして」と投げ続けていました。
HTMLに限らない話です
今回はWebページの話でしたが、構造が同じ作業は身のまわりにいくらでもあります。
- 商品マスタの一括更新(今の在庫表 + 変更分のExcel)
- 設定ファイルの書き換え(今の設定 + 変更依頼)
- 名簿・台帳の年次更新(去年の名簿 + 異動リスト)
- 翻訳ファイルの差し替え(現行の文言 + 修正依頼)
どれも「今あるもの」があって、そこに「変更点のメモ」が来る、という形をしています。
このとき、メモのほうを正にしてゼロから作り直すと、メモに書いていないものが全部消えます。今あるものを正にして、メモの分だけ上書きすると、消えません。それだけの違いで、事故るかどうかが決まります。
まとめ
結局いちばん効いた一手
「まず、何も変えないものを出せるようにする」
機能としては何の役にも立ちません。出力しても現物と同じものが出るだけです。
でもこれが出せた瞬間に、「少しだけ変える」が信用できるようになりました。
そこから先は、変わった行を数えるだけで済むようになりました。
ツールを作るとき、つい「やりたいこと」から作り始めてしまいます。でも更新の仕事に関しては、「何も起きない」を先に作ったほうが、結果的にずっと早かったというのが今回の結論です。
作り直しにかかった時間より、画像が消えた原因を探していた時間のほうが長かったので、なおさらそう思います。
※ 本記事は個人の業務改善の記録です。社名・サイト名・ページの具体的な内容は伏せ、仕組みの部分だけを一般化して書いています。記載している数値(33ページ/208本/45行中44行 など)は実際の作業のものです。