GAS初心者です
よろしくお願い致します
teratailさんで質問をしながら進めてまいりました
みなさんのご協力に感謝いたします
今回はGASの処理時間の工夫について教えていただきたく、質問いたします
「フォームの回答 1」というシートがGoogleフォームの回答が反映されているシートで、2500程度の行数と7列のあるデータを扱います
そのシートのデータを1日の終わりに、指定された各スプレッドシートにコピーして、「フォームの回答 1」のシートはデータを削除して翌日を迎える
という流れを作りたいと考えています
現状、下記のスクリプトの記述で、GW後からほぼ毎日動作してくれているのですが、5/16はエラー(Exception:ドキュメントにアクセス中にスプレッドシートのサービスがタイムアウトしました)が出ました
「6分以内に処理を終えないといけない」という問題だと思い、トリガーの設定ページで処理時間の確認をしました
すると、エラーがでた5/16は93.745秒
それ以外の日も565秒〜808秒かかりながらも処理が完了していると表示されていました
トリガーは1日の終わりの23:00〜00:00に発動するように設定しています
6分の壁ということであれば、360秒が限界であり、この処理時間がエラーの原因になっているのだろうと自分としては予想しましたが、解決策を見出すことができませんでした
どうぞよろしくお願い致します
処理の内容としては、回答データは行ごとに個人のデータが回収されているので、行ごとに指定されたスプレッドシートにコピーをしたいです
以下、前回の質問のURLです
https://teratail.com/questions/336191
GAS
1function myFunction() { 2 //コピー元になるデータを取得 3 var ss = SpreadsheetApp.openById('Googleフォームの回答回収スプレッドシート'); 4 var sh = ss.getSheetByName('フォームの回答 1'); 5 var _lastRow = sh.getLastRow(); 6 var data = sh.getRange(2, 1, _lastRow, 7).getValues(); 7 data = sh.getRange("A2:G").getValues(); 8 9 10 var copymasterdata = sh.getRange(2,1,_lastRow,5).getValues(); 11 var copymastersh = ss.getSheetByName('マスターデータ保管'); 12 var _lastRowmasterPlus1 = copymastersh.getLastRow()+1; 13 14 copymastersh.getRange(_lastRowmasterPlus1,1,copymasterdata.length,5).setValues(copymasterdata); 15 16 var classidsh = ss.getSheetByName('IDキー'); 17 var classiddata = classidsh.getDataRange().getValues(); 18 // キーごとにデータを集約するための連想配列 19 var arrays = {}; 20 // キーシートのシートIDをarraysのキーに設定 21 for (var i = 0; i < classiddata.length; i++){ 22 arrays[classiddata[i][0]] = []; 23 } 24 25 // データを各シートIDごとに集約する。 26 for (var i = 0; i < data.length; i++){ 27 line = data[i]; 28 // キーデータのある6列目~7列目を順番に繰り返す。 29 for(var j = 5; j < 7; j++){ 30 // 6列目または7列目のキーがarraysに存在するならば、 31 // そのキーに対応するデータをpush 32 if(line[j] in arrays){ 33 arrays[line[j]].push(line.slice(0,5)); 34 } 35 } 36 } 37 38 // 振り分け先の各スプレッドシート共通のシート名 39 var targetSheetName = 'データ保管'; 40 41 // 集約したデータを各スプレッドシートに書き込む 42 for (var i = 0; i < classiddata.length; i++){ 43 var classid = classiddata[i][0]; 44 var copyss = SpreadsheetApp.openById(classid); 45 var copysh = copyss.getSheetByName(targetSheetName); 46 if (copysh == null){ 47 Logger.log(`エラー:スプレッドシート[ID=${classid}] に「${targetSheetName}」という名前のシートが存在しません。`) 48 return; 49 } 50 var copy_lastRowPlus1 = copysh.getLastRow() + 1; // 書き込み先の最終行+1 51 var copydata = arrays[classid]; // キーを指定して書き込むデータを格納。 52 if (copydata == null || copydata.length < 1) continue; // エラー対策。データがない場合はスキップ。 53 var lastColumn = 5 // カラム数を設定 54 var lastRow = copydata.length; // 行数を取得 55 copysh.getRange(copy_lastRowPlus1, 2, lastRow, lastColumn).setValues(copydata); 56 } 57 Logger.log('処理終了'); 58 59 60//Logger.log(_lastRow); 61 sh.deleteRows(3,_lastRow-2); 62 sh.getRange('A2:G2').clearContent(); 63 64 //二次元配列に埋め込む関数をセット 65 var formformula = [ 66 [ 67 `=arrayformula(vlookup(B2:B,'名簿'!A:J,10,0))`, 68 `=arrayformula(vlookup(B2:B,'名簿'!A:K,11,0))` 69 ] 70 ]; 71 72 //関数を埋め込む 73 sh.getRange(2,6,1,2).setValues(formformula); 74}
以下、ダミーファイルによるスプレッドシートの構成です
これは「IDキー」のシートで、タイトルなどはなく、検索したいスプレッドシートキーのみを入力しています
写真では「データ保管用」となっていますが、実際には「データ保管」という名前のシートを使用しています
以下、2021/5/18 21:06 追記
振りレッドシートに含まれているシートのダミー画像です
全部で5つのシートで構成されています
それぞれのシートに関数が組み込まれているので、画像に内容を書き込みました
- データ保管
- today
- 項目1
- 項目3
- query