実現したいこと
下記コードで正常に動作しますが、データが4万ほどありタイムアウトしてしまいます。
現状データを上から順にあてていくコードになっていますが処理速度をあげる書き方ありますでしょうか。。
発生している問題・分からないこと
データが多くタイムアウトしてしまう
エラーメッセージ
error
1「起動時間の最大値を超えました」
該当のソースコード
GAS
1function transferData() { 2 var sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('元データ'); 3 var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート2'); 4 var sheet3 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート3'); 5 var sheet4 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート4'); 6 7 var data = sheet1.getDataRange().getValues(); 8 var lastRowSheet2 = sheet2.getRange(sheet2.getLastRow(), 1).getRow() + 1; 9 var lastRowSheet3 = sheet3.getRange(sheet3.getLastRow(), 1).getRow() + 1; 10 var lastRowSheet4 = sheet4.getRange(sheet4.getLastRow(), 1).getRow() + 1; 11 var today = Utilities.formatDate(new Date(), "JST", "MM/dd"); 12 13 14~各シートの列番号取得~ 15 16 // 該当するデータを転記 17 for (var i = 1; i < data.length; i++) { 18 var Value1 = data[i][s1_syubetu]; 19 var Value2 = data[i][s1_rcid]; 20 var Value3 = data[i][s1_kekka1]; 21 var Value4 = data[i][s1_kekka2]; 22 var Value5 = data[i][s1_kekka3]; 23 var Value6 = data[i][s1_kekka4]; 24 25 // シート2 26 // 条件1: "★"または"▲" 27 // 条件2: IDが重複していない 28 if ((Value1 === "★" || Value1 === "▲") && !isDuplicate(Value2, sheet2, 3, lastRowSheet2)) { 29 30 // 転記 31 sheet2.getRange(lastRowSheet2, s2_today).setValue(today) 32 sheet2.getRange(lastRowSheet2, s2_sakuseisya).setValue(data[i][s1_sakuseisya]) 33 sheet2.getRange(lastRowSheet2, s2_rcid).setValue(data[i][s1_rcid]) 34 sheet2.getRange(lastRowSheet2, s2_sakuseibi).setValue(data[i][s1_sakuseibi]) 35 sheet2.getRange(lastRowSheet2, s2_nyuukyubi).setValue(data[i][s1_nyuukyubi]) 36 sheet2.getRange(lastRowSheet2, s2_cmp).setValue(data[i][s1_cmp]) 37 sheet2.getRange(lastRowSheet2, s2_tenpo).setValue(data[i][s1_tenpo]) 38 sheet2.getRange(lastRowSheet2, s2_tantou).setValue(data[i][s1_tantou]) 39 lastRowSheet2++; 40 } 41 42 // シート3 43 // 条件1:「結果1」「結果2」「結果3」「結果4」のどれかに”●” 44 // 条件2: IDが重複していない 45 if ((Value3 === "●" || Value4 === "●" || Value5 === "●" || Value6 === "●") && !isDuplicate(Value2, sheet3, 3, lastRowSheet3)) { 46 47 // 転記 48 sheet3.getRange(lastRowSheet3, s3_today).setValue(today) 49 sheet3.getRange(lastRowSheet3, s3_sakuseibi).setValue(data[i][s1_sakuseibi]) 50 sheet3.getRange(lastRowSheet3, s3_rcid).setValue(data[i][s1_rcid]) 51 sheet3.getRange(lastRowSheet3, s3_syubetu).setValue(data[i][s1_syubetu]) 52 sheet3.getRange(lastRowSheet3, s3_nyuukyubi).setValue(data[i][s1_nyuukyubi]) 53 sheet3.getRange(lastRowSheet3, s3_cmp).setValue(data[i][s1_cmp]) 54 sheet3.getRange(lastRowSheet3, s3_tenpo).setValue(data[i][s1_tenpo]) 55 lastRowSheet3++; 56 } 57 58 // シート4 59 // 条件1:「結果1」「結果2」「結果3」「結果4」のどれかに”◎” 60 // 条件2: レコードIDが重複していない 61 if ((Value3 === "◎" || Value4 === "◎" || Value5 === "◎" || Value6 === "◎") && !isDuplicate(Value2, sheet4, 3, lastRowSheet4)) { 62 63 // 転記 64 sheet4.getRange(lastRowSheet4, s4_today).setValue(today) 65 sheet4.getRange(lastRowSheet4, s4_sakuseibi).setValue(data[i][s1_sakuseibi]) 66 sheet4.getRange(lastRowSheet4, s4_rcid).setValue(data[i][s1_rcid]) 67 sheet4.getRange(lastRowSheet4, s4_nyuukyubi).setValue(data[i][s1_nyuukyubi]) 68 sheet4.getRange(lastRowSheet4, s4_cmp).setValue(data[i][s1_cmp]) 69 sheet4.getRange(lastRowSheet4, s4_tenpo).setValue(data[i][s1_tenpo]) 70 sheet4.getRange(lastRowSheet4, s4_tantou).setValue(data[i][s1_tenpo]) 71 sheet4.getRange(lastRowSheet4, s4_bikou).setValue(data[i][s1_bikou]) 72 lastRowSheet4++; 73 } 74 } 75 // テキストボックス表示 76 var ui = SpreadsheetApp.getUi(); 77 ui.alert('完了しました', ui.ButtonSet.OK); 78} 79// 重複チェック 80function isDuplicate(value, sheet, column, poge) { 81 var columnData = sheet.getRange(2, column, poge - 1, 1).getValues().flat(); 82 return columnData.includes(value); 83}
試したこと・調べたこと
- teratailやGoogle等で検索した
- ソースコードを自分なりに変更した
- 知人に聞いた
- その他
上記の詳細・結果
処理の並列化など調べましたがこのコードにどう適応するのか思いつかなかったため。
補足
特になし
処理を早くするというアプローチではなく、
6分の壁を超える方法を検討した方が良いと思いました。
下記の情報が参考になると思います。
https://uncle-gas.com/avoid-timeout-error/
こちらの記事も読んでいたのですが(30分上限に該当)
そもそも30分も処理にかかるのがネックだったので質問させていただきました。
やりようがなければ処理を分割するこちらの方法も検討したいと思います。
ありがとうございます!
ご提示のスクリプトは、
転記処理がセル単位で行われていたり、
重複チェックに毎回列の値を取得しているなど、
大量のデータを処理することを想定していないものとなってます。
タイムアウトの対策として考えられるのは、
元のシートからシート2~4への転記の処理を
1) 今は元データのみ配列で処理しているのを、
重複チェックも含めて配列で処理し、
転記用の配列を生成した上で、
結果の配列を一括でシートに転記できるのではないか。
2) それぞれのシートごとのスクリプトに分割して
処理ことができるのではないか。
ということでしょうか。
YellowGreen様
ご回答ありがとうございます!
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
2) それぞれのシートごとのスクリプトに分割して
処理ことができるのではないか。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
こちらで進めていきたいのですが、
それぞれForで処理する、で良いのでしょうか?
順序としては、1) → 2)だと思いますので、
1)について、回答欄に記しましたので試してみてください。
1)で処理速度が格段に上がりましたので2)の処理は大丈夫かなと思います。
本当にありがとうございました!!
回答1件
あなたの回答
tips
プレビュー