GASでgoogleカレンダーへデータ移行時エラー「短時間に作成したカレンダーまたはカレンダーの予定の数が多すぎます」


GASを使いgoogleカレンダーへデータ登録時、以下のエラーが頻発し対応策がわかりません。

[code]

    短時間に作成したカレンダーまたはカレンダーの予定の数が多すぎます。
    しばらくしてからもう一度お試しください。
    
[/code]

  * カレンダー登録データ数は全6万件程度。2000件目程度で上記エラーが出現
  * 2実行目以降は、次第に登録数が極端に減り、しまいには登録ができなくなります。
  * 1実行あたり6分未満トリガーも設定しましたが、同エラーメッセが出現
  * Gsuite有料会員です
  * トリガの間に Utilities.sleep(1000) 等を追加してもエラーになります
  * データ量が多いので、forを使用せずmap等を使用しています

なにか解決方法のヒントを頂けないでしょうか。

[code]

    function func() {
      var start_time = new Date();
      // 現在アクティブなスプレッドシートを取得
      var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = spreadSheet.getSheetByName('シート1');
      var dd = sheet.getRange('A:E').getValues();
      var lastcol = 6;
    
      var properties = PropertiesService.getScriptProperties();  //途中経過保存用
      var startRowKey = "startRow";
      var triggerKey = "trigger";
    
      var startRow = parseInt(properties.getProperty(startRowKey));
      if(!startRow){
          //初実行の場合
          startRow = 1;
      }
      //シート記載
      sheet.getRange(startRow+1, lastcol).setValue('開始/'+start_time+'開始行：'+startRow +'行目スタート');
      Logger.log('開始：'+startRow +'+1行目スタート');
    
      var cal = CalendarApp.getDefaultCalendar();
      var n = 350;
      var endRow = 1500;
    
      if(startRow <= endRow ){
          // 一部行のみ取得
          var data = dd.slice( startRow, startRow += n );
          try {
            var result = data.map(function (d) {var ev = cal.createEvent('*'+d[0],new Date(d[1]),new Date(d[2]),{description:d[3],guests:d[4]}).setGuestsCanModify(true);});
            properties.setProperty(startRowKey, startRow); 
            setTrigger(triggerKey, "func");
            return;
    
          } catch(e) {
    
            Logger.log(startRow+'行まで'+'エラーの内容:' + e);
            sheet.getRange(startRow-1, lastcol).setValue('エラー内容:' + e+'/終了時間'+new Date()+'行番号/'+startRow);
          }
      }
    
          Logger.log('最終行終了：'+startRow);
          sheet.getRange(startRow, lastcol).setValue('終了/'+new Date()+'最終行：'+startRow);
          deleteTrigger(triggerKey);
          properties.deleteProperty(startRowKey);  
    }
    
    //指定したkeyに保存されているトリガーIDを使って、トリガーを削除する
    function deleteTrigger(triggerKey) {
      var triggerId = PropertiesService.getScriptProperties().getProperty(triggerKey);
    
      if(!triggerId) return;
    
      ScriptApp.getProjectTriggers().filter(function(trigger){
        return trigger.getUniqueId() == triggerId;
      })
      .forEach(function(trigger) {
        ScriptApp.deleteTrigger(trigger);
      });
      PropertiesService.getScriptProperties().deleteProperty(triggerKey);
    }
    
    //トリガーを発行
    function setTrigger(triggerKey, funcName){
      deleteTrigger(triggerKey);   //保存しているトリガーがあったら削除
      var dt = new Date();
      dt.setMinutes(dt.getMinutes() + 1);  //１分後に再実行
      var triggerId = ScriptApp.newTrigger(funcName).timeBased().at(dt).create().getUniqueId();
      //あとでトリガーを削除するためにトリガーIDを保存しておく
      PropertiesService.getScriptProperties().setProperty(triggerKey, triggerId);
    }
    
[/code]




自己解決したので報告します

主な解決ポイントは  
・.mapではなくfor文使用  
・for文内に Utilities.sleep(1000);を追加する  
・1実行500件程度  
・最小限のソースにしぼる！  
（GASは大量データ処理は弱そうなので、データ加工は別プログラム実行に分け、加工済データを用意）  
（スプレッドシート読み込み、書き込みは重いので、なるべく控えるor実行回数最小にする）  
(descriptionもtriger()使い、事前に無駄な空白削除しておく)  
・管理者で実行する

[code]

    var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = spreadSheet.getSheetByName('シート名');
    var dd = sheet.getDataRange().getValues();
    //一部行のみ取得
    var d = dd.slice(1,3);//★行番号slice(1,3)=行番号2～3を取得
    // カレンダー取得
    var cal = CalendarApp.getDefaultCalendar();
    for (var s = 0; s<d.length; s++){
      cal.createEvent(d[s][1],new Date(d[s][2]),new Date(d[s][3]),{description:d[s][4],guests:d[s][5]}).setGuestsCanModify(true);
      Utilities.sleep(1000);
    } 
    
[/code]

ありがとうございました。

