GASで変更した点をスプレッドシートに即時反映させる
背景
GASを用いてスプレッドシートにデータをセットしてPDFを発行する際に正しく出力されていないことに気づいた
本記事の対象
- スプレッドシートでシートを変更したときに、最新状態に反映させる方法を学ぶ
- PDFを出力するときに正しく出力させる
既存のコード
claspを使用してGASの開発を行っているため、TypeScriptのコードになりますが、GASでも同様の問題に直面するはずです。
シートの更新をするコード
updateSheet.ts
const getSheet = (sheetName: string) => {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
if (!sheet) throw new Error("Sheet not found");
return sheet;
};
const updateSheet = () => {
const sheet = getSheet("your sheet name");
sheet.getRange("A1").setValue("hoge");
};
PDFを保存するコード
(細かい処理は省略しています)
savePdf.ts
const getPdfUrl = (): string => {
return "https://pdf_service_url";
};
//シートをバイナリ形式に変換
const getPdfBlob = (url: string): GoogleAppsScript.Base.Blob => {
const token = ScriptApp.getOAuthToken();
const options = {
headers: { Authorization: "Bearer " + token },
};
return UrlFetchApp.fetch(url, options).getBlob();
};
//バイナリ形式をPDF形式に変換後保存
export const savePdf = () => {
const pdfUrl = getPdfUrl();
try {
const folder = DriveApp.getFolderById("folderId");
const blob = getPdfBlob(pdfUrl).setName("fileName");
folder.createFile(blob.setName("fileName"));
} catch (error) {
console.error("saveAsPdf error", error);
throw new Error("PDFの保存に失敗しました");
}
};
上記のupdateSheet
関数を使用したあとに、savePdf
関数を使用すると、A1のセルに"hoge"が反映されずに前の状態(なにも記載されていなかったら白紙)のPDFが出力されてしまう。
原因
- GASは処理が反映されるのにタイムラグがある
- プログラムを
データ更新→PDF出力
のフローを行っても、スプレッドシート上には反映されずに、PDF出力→データ更新
というフローになってしまっている
解決策
- 変更点をスプレッドシートに即時反映させる
flush()
を使用
変更点
savePdf.ts
// 修正前
export const savePdf = () => {
const pdfUrl = getPdfUrl();
try {
const folder = DriveApp.getFolderById("folderId");
const blob = getPdfBlob(pdfUrl).setName("fileName");
folder.createFile(blob.setName("fileName"));
} catch (error) {
console.error("saveAsPdf error", error);
throw new Error("PDFの保存に失敗しました");
}
};
//修正後
export const savePdf = () => {
const pdfUrl = getPdfUrl();
try {
//追記
SpreadsheetApp.flush()
const folder = DriveApp.getFolderById("folderId");
const blob = getPdfBlob(pdfUrl).setName("fileName");
folder.createFile(blob.setName("fileName"));
} catch (error) {
console.error("saveAsPdf error", error);
throw new Error("PDFの保存に失敗しました");
}
};
上記のようにSpreadSheetApp.flush()
を使用すると解決しました
おわりに
GASでPDFの出力をする際に、正しく反映されないことに気づき、原因を探りました。
今回のようにエラーが出ずに、出力結果を見ないと気づけないようなバグは非常に怖いです。タイムラグがあり、正しく出力されてしまうこともあり、原因特定に時間がかかるというのも非常に厄介でした。
このようなことを避けるためにも、新しく使用する技術については、ドキュメントをしっかり読み込み開発をするべきだと思い勉強になりました。