

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]


CC BY-SA 4.0
2019-05-07T09:28:39.020
54796
2019-12-01T02:15:57.283
2019-12-01T02:15:57.283
32986
34217
question
google-apps-script google-cloud
GASでgoogleカレンダーへデータ移行時エラー「短時間に作成したカレンダーまたはカレンダーの予定の数が多すぎます」


10万個以上予定を作成すると、制限が掛けられるようです。

> 短期間にカレンダーで作成した予定の数が 100,000 個を超えた場合、数時間にわたりカレンダーを編集できなくなることがあります。  
>  このような種類の制限が完全にリセットされるまで、数か月かかることがあります。  
>  [カレンダーの使用に関する制限事項 - G Suite 管理者
> ヘルプ](https://support.google.com/a/answer/2905486?hl=ja)

ヘルプを確認する限り見つからなかったのですが、おそらく **短期間で集中的にAPIを実行したことによる制限**
というものが存在して発生し、その後2回目以降で上記エラーが発生した（6万x2）のではないでしょうか？


CC BY-SA 4.0
2019-05-09T02:46:15.120
54843
2019-05-09T02:57:52.897
2019-05-09T02:57:52.897
29826
29826
54796
answer


私は迂闊にも for 文で連続イベント登録してしまい、同様の状態になりました。  
1,000 件強あたりでエラーが発生、その後、「しばらくしてからもう一度お試しください。」ということなので、24
時間を経過させましたが、エラーは解決せず、カレンダーの制御ができなくなってしまいました。

ふと、何気なく思いついて、イベントの description
の内容を実装変更して実行してみたら（日付とタイトルはどうしても変更する訳にはいかなかった）、その瞬間からエラーが発生しなくなりました。

何故解決できたのか今でも不明ですが、一度、エラーを発生させたイベントと同等もしくは酷似した内容ではダメで、そこから大きく実装を変更したのが解決の糸口になったのかもしれません。


CC BY-SA 4.0
2019-05-09T05:39:03.333
54848
2019-05-09T05:39:03.333
34241
54796
answer


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

主な解決ポイントは  
・.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]

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


CC BY-SA 4.0
2019-05-29T02:28:24.753
55327
2019-05-29T02:30:33.083
2019-05-29T02:30:33.083
19110
34517
54796
answer