1

職場用のGoogleAppsスプレッドシート名簿を作成しています。実際の名簿はかなり単純で、いくつかの計算と、その時間の勤務時間に応じてセルの色を変更するonEditスクリプトがあります。

この新しい名簿の主要な部分の1つは、各人がシフトを通知するためのGoogleカレンダーイベントを作成する機能です。名簿が作成され、イベントは毎月作成する必要があります。月の初めに、名簿を作成するスタッフが機能を実行し、その月のすべてのイベントを各自に対して作成します。(私はそれが理にかなっていることを願っています...)

私のコードは以下のとおりです。「スプラッシュ」(シートインデックス0)と呼ばれるシートには、チームの各スタッフメンバーの名前と電子メールが含まれています。名簿は、シートインデックス1から無限大に作成されます。

名簿シート自体の列Aには、各スタッフの名前が含まれています。列Bには開始時刻が含まれ、列Cには終了時刻が含まれます。

function sendInvites() {
  // Gather Prelim Information
  var splash = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Splash");
  var nameRange = splash.getRange("A6:B9"); // Need to change this to be the full staff list in Splash

  var inviteSheet = Browser.inputBox("Sheet to send invites from (Number)", Browser.Buttons.OK_CANCEL)
  var days = SpreadsheetApp.getActiveSpreadsheet().getSheets()[inviteSheet];
  var dayRange;

  //Initiate iteration through Names, according to the Splash sheet
  for(nameRow=nameRange.getRow(); nameRow<=9; nameRow++){ //Change to Corresponding iterate
    // Gather Name and Email information for the each person
    var col = nameRange.getColumn();
    var row = nameRow;
    var name = splash.getRange(row, col).getValue();
    var email = splash.getRange(row, col+1).getValue();
    var cal = CalendarApp.getCalendarById(email);

    //Initiate iteration through Days, according to the Roster
    for(i=0; i<=6; i++){
      //Specify Day Ranges
      switch(i){
        case 0: //Saturday
          dayRange = days.getRange("A1:O6"); break;
        case 1: //Sunday
          dayRange = days.getRange("A10:O15"); break;
        case 2: //Monday
          dayRange = days.getRange("A19:O41"); break;
        case 3: //Tuesday
          dayRange = days.getRange("A45:O67"); break;
        case 4: //Wednesday
          dayRange = days.getRange("A71:O93"); break;
        case 5: //Thursday
          dayRange = days.getRange("A97:O119"); break;
        case 6: //Friday
          dayRange = days.getRange("A123:O145"); break;
      }

      //Find Name in dayRange
      for(dayRow=dayRange.getRow(); dayRow<=dayRange.getLastRow(); dayRow++){
        var searchCol = dayRange.getColumn();
        var searchRow = dayRow;        
        var searchName = days.getRange(searchRow, searchCol).getValue();

        if (name==searchName){
          // Gather and format Date and Time information for invitation
          var eventName = "Phones";
          var date = Utilities.formatDate(dayRange.getValue(), "GMT+1000", "EEE MMM dd yyyy");
          var startCell = days.getRange(searchRow, searchCol+1).getValue();
          var endCell = days.getRange(searchRow, searchCol+2).getValue();

          if (startCell != ""){
            var startTime = date + " " + Utilities.formatDate(startCell, "GMT+1000", "HH:mm:ss");
            var endTime = date + " " + Utilities.formatDate(endCell, "GMT+1000", "HH:mm:ss");

            //Create a calendar event with the details above
            Utilities.sleep(500); //Pause event creation for half second, to allow the last event to be fully created (Avoids "Calendar: Mismatch: etags error")
            cal.createEvent(eventName, new Date(startTime), new Date(endTime)).removeAllReminders();
          }

          continue;
        }
      }
    }
  }
}

私が今抱えている問題は、ロジックは機能しますが、すべてのイベントが作成されているわけではないということです。私は自分を含めて4人のスタッフでテストしています。カレンダーをスローする前に、名前の1.5回の反復のみを完了します:不一致:etagsエラー。

このエラーは、カレンダーが一度に2回変更されているときに発生することを認識しています。これを可能にするために、イベントを作成する前に0.5秒のスリープ時間を追加しました。今では非常にまれですが、まだ発生しています。私はそれを2秒間スリープさせてみました、私はそれを別のポイントに移動しようとしました。これらはすべて、eTagsエラーが発生します。

ここからどこへ行くのかよくわかりません。名簿はほぼ使用できる状態になっているように感じますが、まだ十分に安定していません。

何かアイデアがある場合、または説明が必要な場合はお知らせください。

4

1 に答える 1

1

「etags」エラーを回避するには、try/catch が必要です。Google の分散ストレージに新しい連絡先オブジェクトを作成するには時間がかかるため、エラーを生成する操作は removeAllReminders() です。

これらの恐ろしい「etags」エラーを回避するために、ヘルパー関数を使用します。

function retryMethod(object, method) {
  for (i=0; i<10; i++) {
    try {
      return object[method]();
    }
    catch (e) {
      if (e.message.indexOf('Mismatch: etags') == -1) throw e;
      Utilities.sleep(500);
    }
  }
  throw new Error('retryMethod failed after retrys method ', method, ' object ', object)
}

次に、「cal.createEvent(」行を次のように書き換えることができます。

retryMethod(cal.createEvent(eventName, new Date(startTime), new Date(endTime)), 'removeAllReminders');

createEvent が null かどうかを確認してください。

実際には、「etags」エラーを発生させるほとんどの関数呼び出しが実際に成功しているため、現在のヘルパー関数はわずかに異なります。

于 2012-09-18T05:31:55.143 に答える