エラーも出ずに、前の見積書PDFが消えていた|メールから見積書を自動で作って気づいたこと

作業着姿の日本人男性がノートパソコンの画面に向かい、表計算シートで作った見積書の仕組みを確かめている様子を描いた、落ち着いた色味の写実的なイラスト AI活用

皆さんこんにちは、横浜で清掃業をしているヤスです。

見積依頼のメールが来るたびに、こんな作業をしていないでしょうか。

  • メールを読んで「何の作業か」「何台か」を確認する
  • 単価表を開いて、該当する金額を探す
  • 見積書に書き写して、計算して、PDFにして保存する

1件ならまだいいのですが、毎回となると地味に重い作業です。しかも書き写しのミスは、そのまま金額のミスになります。

前回の記事では、「同じメールでも、AIは実行するたびに答えが少しずつ変わる。だから最後は人が決める」と書きました。今回は見積書づくりです。金額を扱うので、前回以上にAIを疑ってかかるつもりで作り始めました。

ところが、結果はまったく逆でした。

AIの判定は一度も間違えませんでした。壊れていたのは、全部私が書いたコードのほうでした。

しかもエラーは一切出ず、前に作った見積書のPDFが静かに消えていました。

※この記事に登場する会社名・人名・住所・単価は、すべて練習用に作った架空のダミーです。実在のお客様や実際の取引の話ではありません。


結論:行を選ぶだけで、見積書PDFが案件フォルダに入る

完成した仕組みの流れはこうです。

  1. 「確認待ち」シートで、見積もりたい依頼の行を選ぶ
  2. AIが依頼内容を読み、「どの作業を・いくつ」かを判定する
  3. GAS(Googleのサービスを自動で動かす小さなプログラム)が、単価表から金額を引いて見積書に書き込む
  4. 計算はシートの数式が行う
  5. PDFにして案件フォルダへ保存。案件管理シートに「見積中」で登録される
GASを利用して自動作成された「ヤスメンテナンス」の御見積書画像。「ミドリ商事 御中」宛の「エアコン洗浄(壁掛けエアコン3台)」の見積もりとして、数量や単価(12,000円)から合計金額(39,600円)まできれいに計算・出力されている様子。

使ったのは、GAS、OpenAI API(AIを外から呼び出すための窓口)、Googleスプレッドシート、Googleドライブです。

きっかけはこれまでと同じで、クラウドワークスで見た設備工事会社のバックオフィス効率化の募集です。稼働条件が合わず応募は見送りましたが、書かれていた業務を練習教材として1つずつ作っています。今回は「見積書等の書類作成」のうち、読み取り → 転記 → 計算 → PDF化 → フォルダ保存までの前半を作りました。

この仕組みは、シリーズで作ってきた3つの続きです。

今回でこの4つが、メール受信から見積・対応待ち管理までの1本の流れになりました。


一番大事にしたこと:計算はAIにやらせない

作り始める前に、ひとつだけ決めたことがあります。金額の計算を、AIにやらせないことです。

第2話で、同じメールでも実行するたびにAIの答えが変わることを経験しました。これが金額で起きたら、取り返しがつきません。

そこで、役割をはっきり分けました。

担当やること
AI「何を・いくつ」を読み取るだけ
GAS単価表から単価を引く、シートに書き込む、PDFにする
シートの数式掛け算・小計・消費税・合計
人単価の最終決定、値引きの判断、承認

値引き欄は、常に「0」で書き込む作りにしました。AIにもGASにも、値引きは決めさせません。

募集文にも「販売価格の決定や最終承認は担当者が行う」という趣旨が書かれていました。ここは人が持つべき部分だと思います。


作り方:7つのステップ

ステップ1:単価マスタを作る

単価マスタとは、作業ごとの単価をまとめた一覧表のことです。「作業名」「単位」「単価」を1行ずつ並べます。私はエアコン洗浄、エアコン交換、換気扇交換、給湯器交換など10項目を入れました。

なぜか:AIには、この一覧の中から選ばせるからです。自由に書かせると、金額と結びつきません。

ステップ2:見積書シートを作る

入力欄は黄色にして、どこに書き込むかを分かりやすくします。小計・消費税・合計は、すべてシートの数式で計算させます。

なぜか:計算の答えがブレない場所に、計算を任せるためです。

ステップ3:AIへの指示にルールを入れる

入れたルールは次の4つです。

  • 作業名は、単価マスタの一覧の中から名称だけを書く
  • 数量を読み取る。書かれていなければ「不明」にする(1と決めつけない)
  • 洗浄か交換かなど、決められないときは「判断できない」と返し、候補を書く
  • 一覧にない作業は「一覧にない作業」と返す

ここで大事なのは、理由を2種類に書き分けさせることです。「一覧にない作業:〜」と「判断できない:〜(候補:A、B)」。人のやることが変わるからです。前者なら単価マスタに項目を足すか外注を検討する。後者なら、お客様に電話一本で確認すれば済みます。

なぜか:「決められないときは人に回す」を、AI自身に言わせるためです。

ステップ4:GASで単価を引いて書き込む

AIの返した作業名を単価マスタと照合して、単価を見積書に書き込みます。照合は、完全一致だけでなく部分一致でも当たるようにしておきます(理由は後のつまずきで書きます)。値引き欄には0を書き込みます。

ステップ5:案件番号を「3か所」見て振る

採番(番号を順番に割り振ること)は、次の3か所を見て行います。

  • 案件管理シート
  • 確認待ちシート
  • ドライブのフォルダ名

見積書を作ったら案件管理シートに登録し、元の行にも番号を書き戻します。

なぜか:1か所だけ見ると、同じ番号が何度も振られてしまいます。私はこれで見積書を消しました。

ステップ6:PDFにして保存・登録する

PDF化の直前に、入力欄だけ背景を白に戻します。PDFを第3話で作った案件フォルダに保存し、案件管理シートに「見積中」で登録します。

登録した案件は、10日間動きがなければ第1話の対応待ち一覧に「見積放置」として上がってきます。

ステップ7:「迷う材料」を仕込んだメールでテストする

実在のお客様のメールは使えません。なので、判断に迷う点をわざと仕込んだ架空のメールを5通作りました。

#内容試したいこと
①エアコン洗浄を3台基本形
②「エアコンのことで」4室分洗浄か交換か、勝手に決めないか
③換気扇交換2台+配管も見てほしい数量が片方だけ
④屋上防水工事単価マスタにない作業
⑤給湯器1台「できるだけ安く」勝手に値引きしないか

特に②が肝です。単価マスタには「エアコン洗浄(12,000円)」と「エアコン交換(95,000円)」の両方があります。AIが決め打ちしたら、金額が約8倍違ってしまいます。

第2話では、添付ファイルを試す材料を用意し忘れました。その反省で、今回は試したい判断の数だけメールを用意しました。


結果:AIの判定は6件すべて妥当だった

③が2つに分かれたので、判定は全部で6件です。

  • ① エアコン洗浄×3 → 見積書作成
  • ② 「判断できない:作業内容が不明(候補:エアコン洗浄、エアコン交換)」→ 人へ
  • ③a 換気扇交換×2 → 見積書作成
  • ③b 配管点検 → 「一覧にない作業」で人へ
  • ④ 「一覧にない作業:屋上防水工事」→ 人へ
  • ⑤ 給湯器交換×1 → 見積書作成。値引きは0のまま
GASとAIによるメール処理結果を管理するスプレッドシートの画面。「作業場所の住所」や「入居者様のご都合の良い時間帯」といったAIが抽出した要確認事項に対し、人間が「承認」や「未確認」を判定する仕組み。転記結果の列には「更新」や「見積書を作れません(判断できない)」といった結果が色分けされ、元メールへのリンクも並んでいる様子。

「できるだけ安くしてほしい」と書かれていても、AIは値引きを決めませんでした。防水工事を、似た項目に無理やり当てはめることもありませんでした。3件は見積書になり、3件はきちんと私のところに回ってきました。


つまずきポイント:壊れていたのは全部、私のコードだった

① 見積書は毎回できる。なのに、前のPDFが消えていた

テストで3件続けて見積書を作りました。3件とも、きれいにPDFができています。エラーもありません。

おかしいと気づいたのは、実行ログを見返したときでした。3件とも、同じ案件番号「2026-017」が振られていたのです。

私は「同じ名前のファイルがあれば上書きする」作りにしていました。つまり、先に作った2件のPDFは、静かに上書きされて消えていたことになります。

怖いのは、エラーが一切出ないことです。見積書は毎回ちゃんとできる。画面上は何も問題がありません。前のものが黙って消えるだけです。

第3話で「エラーが出ないほうが怖い」と書きましたが、今回はそれが自分のコードの中で起きていました。

原因は、採番の仕組みが案件管理シートだけを見ていたことでした。作ったばかりの案件は、まだそこに登録されていません。だから何度採番しても「次は017」になっていたのです。

直し方は3つです。

  • 案件管理シート・確認待ちシート・ドライブのフォルダ名の3か所を見て採番する
  • 見積書を作ったら案件管理シートに登録し、元の行にも番号を書き戻す
  • 採番のタイミングをAI判定の後にする(以前は判定の前に採番していたので、「該当なし」で終わった行でも番号を使ってしまっていました)

教訓:エラーが出ない失敗が、一番見つけにくい。

② PDFにしたら、明細の見出しが消えた

見積書シートでは、入力欄を黄色で塗って目印にしていました。これをPDFに出したくなかったので、PDF化の直前に背景を白にする処理を入れていました。

ところが、その範囲に明細の見出し行(濃紺の背景に白い文字)が含まれていました。背景だけ白になり、白地に白文字。見出しが見えなくなりました。

直し方は、色を白にする対象を入力欄だけに絞ることでした。見出し行には触りません。

教訓:「まとめて白に」は、巻き込み事故を起こす。

③ AIが作業名に単位をくっつけてきた

唯一AIが関わったつまずきも、原因は私の渡し方にありました。

最初、AIは「エアコン洗浄」と正しく返していました。ところがあるとき、「エアコン洗浄(単位:台)」と返してきたのです。

単価マスタの文字とは一致しません。判定自体は正しいのに、「マスタにない項目」として弾かれてしまいました。

原因は、作業一覧をこの形で渡していたことでした。

- エアコン洗浄(単位:台)

AIは、この行全体を「名称」だと受け取っていたのです。第2話の「同じ入力でも答えが変わる」が、形を変えて出てきました。

直し方は2つ入れました。

  1. 一覧の渡し方を「- エアコン洗浄 / 単位:台」に変え、「名称だけを書く」と指示に明記する
  2. それでもずれたときのために、GAS側で部分一致(文字の一部が合っていれば同じとみなす照合)でも拾えるようにする

部分一致で拾ったときはログ(実行の記録)に残し、後から気づけるようにしました。

教訓:指示を直して終わりにしない。ずれても動く作りにしておく。

④ その他の小さなつまずき

  • シート名が一致せず「シートが見つかりません」(シリーズ通算4回目です)
  • 見積書シートのコピーを忘れて、単価マスタだけ移していた
  • コードを差し替えたとき、閉じ括弧が1つ残って構文エラー(書き方のルール違反で動かないエラー)

動くことと、人に出せる書類になることは別だった

最初に出力したPDFは、黄色の塗りつぶしと作り手向けのメモがそのまま入っていて、とても人に出せるものではありませんでした。

そこから、次のように直しました。

  • PDFの出力範囲を限定し、作り手向けのメモを含めない
  • 入力欄の黄色と青文字を、PDF化の間だけ白地・黒文字にする
  • 宛先に会社らしい語が含まれていれば「御中」、なければ「様」に切り替える
  • 自社情報(社名・住所・電話・メール・担当者)の欄を追加
  • 有効期限(発行日から30日後)を自動で入れる
  • 「下記のとおり、お見積り申し上げます。」の一文を追加
  • 上部に御見積金額を大きく表示する

仕組みが動いた時点では、まだ半分でした。


まとめ:疑うべきは、AIだけではなかった

今回の手順をおさらいします。

  1. 単価マスタを作る
  2. 計算は数式に任せる見積書シートを作る
  3. AIには「一覧から選ぶ・決められなければ人に回す」ルールを渡す
  4. GASで単価を引き、値引きは0で書き込む
  5. 案件番号は3か所を見て振る
  6. 入力欄だけ白にしてPDF化・保存・登録
  7. 迷う材料を仕込んだメールでテストする

第2話では「AIは揺れるから人が承認する」と書きました。今回はその逆です。AIは安定していて、私のコードが静かにデータを消していました。

AIを疑うことばかり考えていました。でも確認すべきなのは、自分が作ったものも同じだったのです。

最初の一歩の提案です。

もし同じような仕組みを作っているなら、テストで同じ処理を3回続けて実行して、保存先のフォルダを開いてみてください。ファイルが3つ残っているかを確かめるだけです。エラーが出ていなくても、それだけで気づけることがあります。

そしてもうひとつ。「一覧から選ばせる」「決められないときは人に回す」という型は、見積書以外にも使えます。作業報告書、発注書、問い合わせの振り分けなどです。まずは、いつも使っている作業と単価を、スプレッドシートに5行だけ書き出してみるところからです。それがこの仕組みの土台になる単価マスタになります。

だんだん仕事で使えるツールになりつつありますね。さらにバージョンアップさせます!


次回予告

今回作った見積書には、続きがあります。

お客様から発注書が届いたとき、その金額がこちらの見積書と合っているか。
金額が違っていても、気づかないまま工事が進んでしまうことがあります。

次回は、発注書と見積金額を自動で照合する仕組みを作ろうと思います。
是非お楽しみに!

次におすすめの記事はこちら

写真で見積書PDFを全自動作成!4業種対応AIの作り方【GAS連携・失敗談つき】

コメント

タイトルとURLをコピーしました