Excel自動化

開発ログ: 120,000 行のスプレッドシートが実際に壊れていること

121,254 行と 180 万セルのスプレッドシートでの作業セッション、および大規模なクロステーブル分析が終了し、その出力を検証し、使用可能な書式設定されたレポートを返す前に変更する必要があった 5 つの項目。

ほとんどのスプレッドシート機能は、画面に収まるデータでテストされます。このログは、15 列にわたる 121,254 行 - およそ 180 万セル を使用した販売ワークブックでの作業セッションと、製品、顧客、注文、販売テーブルを結合し、辞退製品、在庫補充リスク、価値の低い顧客にフラグを立てるという、ありきたりに聞こえるリクエストをカバーしています。

その要求には特別なことは何もありません。とにかく、分析自体とはほとんど関係のない理由で、何度か失敗しました。以下は、実際に何が壊れ、何が変化したかを示します。

遅いクエリではなくプラットフォームの制限

最初の失敗は耐久ジョブ システムのバグのように見えました。本当の原因は Google Apps Script のルール: エディター アドオンは、1 時間に 1 回を超える頻度で起動する時間駆動トリガーを作成できない場合があります。

バックグラウンド ジョブの設計では、1 分間のトリガーを想定していました。この想定は、コンテナにバインドされたスクリプトが自由にスケジュールできるという開発中に保持されていましたが、同じコードがインストールされたアドオンとして実行された瞬間に保持されなくなりました。トリガーをインストールするリクエストは低下しませんでした。トリガーがスローされ、ジョブが作成された がスローされたため、作業は開始されませんでした。

2 つの変更が続きました。トリガーのインストールはベストエフォートになりました。トリガーは 1 分間のペースで試行され、1 時間ごとに戻り、最後にはトリガーがまったく存在しない状態になり、スローされることはありません。そして、最初の処理ステップは、タスクを再度検索する必要がある 2 番目の呼び出しではなく、タスクを作成したのと同じ実行内で実行されるようになりました。

その 2 番目の詳細は、思っている以上に重要でした。 Apps Script のプロパティは、複数の実行にわたって確実に読み書きできるわけではないため、直前に書き込まれたタスクが次の呼び出しで "タスクが見つかりません" として返される可能性があります。

進捗状況の報告は完了することと同じではありません

ようやく仕事が始まったものの、まだ終わっていない。このツールは 1 ステップ実行した後、「バックグラウンドで作業が継続している」というステータスを返しました。

その文は誤りでした。利用可能な 1 時間未満のトリガーがないため、バックグラウンドでは何も続行されません。アシスタントはステータスを読み取り、パーセンテージをユーザーに伝えて停止しました。ジョブは 121,253 行中 34,000 行で無期限に保留されたままになります。

ランタイムは、制限された予算内でジョブ自体を完了に導き、後続のすべてのステータス呼び出しによって、単にジョブを読み取るだけでなく作業を進めます。予算が使い果たされた場合、ステータス テキストには、タスクが未完了であり、他に何も進められないことが明確に示されます。

原則は直接述べる価値があります: 進捗レポートは成果物ではありません。 ユーザーがパーセンテージではなくテーブルを要求しました。

リクエストは、モデルが認識できるツールによってのみ処理できます

ツールの選択を正確に保つために、GetSheetAI はリクエストに基づいてターンごとにツールのサブセットを公開します。その仕組みは Excel ツールセットを中心に構築されており、Google Sheets アドオンにはそこにしか存在しない 22 個のツールが登録されています。これらのツールはすべてのリクエストから除外されていました。

効果は特殊であり、見落としがちでした。棒グラフを要求すると、44 個のツールのうち 6 個が表示され、非表示のツールの中にチャート ツールが含まれていました。並べ替えツールを使用せずに、44 個中 5 個の範囲を並べ替えるように要求しました。アシスタントは拒否したわけではありません。実際には、その仕事を行うツールが見えませんでした。

シートには、対応する各 Excel をミラーリングする独自のツールとバンドルのマッピングがあり、フィルターは意見のないツールを削除するのではなく通過します。テストでは、登録されたツール名をソースから直接読み取るようになりました。そのため、ツールを分類せずに追加すると、黙ってアクセス不能になるのではなく、ビルドに失敗します。

同じクラスのギャップがフレージングにも現れました。 「新しいシートの作成」を意味する中国語のリクエストは、パターンがシートの 2 つの一般的な単語のうち 1 つしか認識しなかったため、ルールに一致しませんでした。シート作成ツールは非表示のままで、アシスタントはワークシートの作成が不可能であると報告しました。そうではありませんでした。

エラー メッセージは製品の一部です

いくつかの失敗は、解決策を示さずに問題を説明するメッセージが原因でした。

存在しないシートに書き込むと、"要求されたリソースは存在しません。" が返されました。これは、壊れたアドインのようです。シートが存在しないこと、書き込みツールがシートを作成しないこと、および 2 つの呼び出しがシートを作成することを示します。

非常に広い範囲で行レベルの分類を拒否すると、単なる拒否が返されました。集約結果のラベル付けはどのようなサイズでも機能するため、メッセージではそのパスに最初にグループという名前が付けられ、次にグループ化された結果に分類ルールが適用されます。

上書きガードは blocked: true のみを返し、これは失敗として読み取られます。ここでは、ターゲットが既にデータを保持していることと、その続行方法について説明します。

これらはどれも表面的なものではありません。いずれの場合も、前のメッセージはまだ完了可能なタスクを終了しました。

決定論的な式にはより多くの算術演算が必要です

20170702 のような整数日付キーから 201707 などの年月を導出するには、floor(x / 100) またはモジュロのいずれかが必要です。どちらも存在しませんでした。 2 回の試行が失敗し、派生列は放棄されました。

式レイヤーには、floorroundabs、および mod が含まれるようになり、サポートされていない関数エラーでは、拒否されたものに名前を付けるだけでなく、完全なセットがリストされ、その正確な式が示されます。

現状

同じワークブック上で永続パスが完了しました。121,253 行すべてが処理、グループ化、書き込み、フォーマットされ、すべての結果チャンクが検証されました。 Excel では、同じリクエストにより 397 製品すべてにわたる分類が生成されました。132 品目は最近販売がなく、101 品目は再入荷リスクのフラグが立てられ、99 品目は下落、65 品目は通常でした。データをどこにでも移動するのではなく、ソース テーブルに対してネイティブ SUMIFS を使用して計算されました。

知っておく価値のある動作値:

  • 耐久ルーティングしきい値: 100,000 セル 以上。
  • ソース チャンキング: 制限付き読み取り、ライトバック時にチャンクごとに検証されます。
  • 回帰カバレッジ: 共有ランタイム全体で 826 テスト せいぜい
  • Google スプレッドシート アドオンのバックグラウンド実行: 時間ごと そのため、サイドバーが開いている間、サイドバーは長時間のジョブを駆動します。

最後の点は一時的なものではなく、実際の制限です。インストールされたアドオンは、より頻繁に作業をスケジュールすることができないため、サイドバーが開いている間に大規模なジョブが進行します。永続的なチェックポイント設定は、チェックポイントを閉じても完了した作業が失われることはないことを意味しますが、正直に説明すると、作業はスケジュールされたものではなく、実行されるものです。

このセッションから得られた広範な教訓は、規模に関するものではありませんでした。これらの障害はいずれも、プラットフォーム ルール、隠しツール、エラーのどこにも名前のないサポートされているパスなど、ユーザーには見えないものをシステムが認識しているケースでした。サイズがすべてを一度に見えるようにするためのものでした。