はじめに
GASでシート末尾に値を追加するappendRow()について、
同時に実行したら同じ行を編集してしまうのか、検証しました。
結論:同時実行は競合します。
以下、検証方法の紹介です。
コードと出力結果
function myFunction() {
const sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
let now = dayjs.dayjs();
while(now.format("HH:mm")!="09:30"){
now = dayjs.dayjs();
}
sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
Utilities.sleep(300);
sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
Utilities.sleep(300);
sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
Utilities.sleep(300);
sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
Utilities.sleep(300);
sh.appendRow([dayjs.dayjs().format("YYYY/MM/DD HH:mm:ss")]);
}
4つのタブで同じスクリプトエディタを開き、実行します。
すると9:30になった瞬間同時に書き込みが走り、合計20行に値が入るはずです。
しかし、何度かやっても17~19行しか値が入りませんでした。
やはり20回の実行のうち、最終行を取得するタイミングが重なってしまうようでした。
気になる方はシートからエディタを開いてコピペして試してみてください。
(シートなので証拠になりませんが、イメージ図です。)
対処方法はあるのか
appendRow()を使う限り、競合の可能性は捨てきれないでしょう。
appendRow()以外の方法で、絶対に競合を避けたい場合には、
GoogleDriveにファイルを保存する等の手段があります。
シート行に保存しようとしていたデータ1つ1つについて、
Drive上にJSONなどのファイルを設ければ、競合可能性を相当下げることができます。
ファイル名を日次+UUIDなどにしておけば、同名ファイルが生成されることもありません。
注意点として、それらのJSONを同時に変更可能な仕様にしてはいけません。
さいごに
GoogleAppsScriptを使う以上、
一部の処理ではどうしても競合が発生してしまいます。
上述のような打開策もありますが、仕様が分かりにくくなります。
外部のデータベースの利用なども視野に入れて仕様検討するのが無難かと思います。