web-dev-qa-db-ja.com

スプレッドシートからGoogleカレンダーイベントを作成しますが、重複を防ぎます

Googleスプレッドシートからデータを取得し、Googleカレンダーにイベントを作成するスクリプトを作成しようとしています。

私はそれをうまく管理しましたが、実行するたびに複製を作成しました。だから今、私は各行の自動生成された一意のイベントIDを使用してスプレッドシートの列17を作成し、スクリプトが実行されるたびに各行のイベントIDを見て対応するイベントを削除することを防止しようとしています行を変更した場合、元のデータまたは更新されたデータで再作成する前に、カレンダーで.

私はあらゆる種類のスクリプト作成に慣れていないので、これをまとめて考えましたが、今は壁にぶつかっています。誰でもこれを整理するのを助けることができますか?

function CalInsert() {
    var cal = CalendarApp.getDefaultCalendar();
    var id = SpreadsheetApp.getActiveSheet().getRange(2,17).getValue();

    if (id != 0) {
        var event = cal.getEventSeriesById(id);
        event.deleteEventSeries();
    }

    var sheet = SpreadsheetApp.getActiveSheet();
    var startRow = 2; // First row of data to process
    var numRows = sheet.getLastRow(); // Number of rows to process
    var dataRange = sheet.getRange(startRow, 1, numRows, sheet.getLastColumn());
    var data = dataRange.getValues();

    for (i in data) {
        var row = data[i];
        var title = row[0]; // First column
        var desc = row[13]; // Second column
        var tstart = row[14];
        var tstop = row[15];

        var event = cal.createEvent(title, tstart, tstop, {description:desc});
        var eventid = event.getId();
        SpreadsheetApp.getActiveSheet().getRange(2,17).setValue(eventid);
    }
}
26
user2240577

これは、イベントのスプレッドシートをカレンダーと同期することに関する2日前の質問に非常に似ています。スプレッドシートを、それが発生したイベントのマスターであるとみなしたいようです。これにより、問題が大幅に簡素化されます。あなたがする必要があることの基本は この答え でカバーされています。既存のコードを変更するだけの場合は、以下の実装を使用します。

this blog のコードの修正版があります。これは、スプレッドシートの情報に一致するように既存のカレンダーエントリを修正します。スプレッドシートの配置を変えましたが、これはコードに反映されています。

日付|タイトル|開始時間|終了時間|ロケーション|説明| EventID

イベントID列は、新しいイベントが作成されるとスクリプトによって入力され、その後の呼び出しでカレンダーからイベントを取得するために使用されるため、重複が回避されます。

脚本

_/**
 * Adds a custom menu to the active spreadsheet, containing a single menu item
 * for invoking the exportEvents() function.
 * The onOpen() function, when defined, is automatically invoked whenever the
 * spreadsheet is opened.
 * For more information on using the Spreadsheet API, see
 * https://developers.google.com/apps-script/service_spreadsheet
 */
function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Export Events",
    functionName : "exportEvents"
  }];
  sheet.addMenu("Calendar Actions", entries);
};

/**
 * Export events from spreadsheet to calendar
 */
function exportEvents() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var headerRows = 1;  // Number of rows of header info (to skip)
  var range = sheet.getDataRange();
  var data = range.getValues();
  var calId = "YOUR_CALENDAR_ID";
  var cal = CalendarApp.getCalendarById(calId);
  for (i=0; i<data.length; i++) {
    if (i < headerRows) continue; // Skip header row(s)
    var row = data[i];
    var date = new Date(row[0]);  // First column
    var title = row[1];           // Second column
    var tstart = new Date(row[2]);
    tstart.setDate(date.getDate());
    tstart.setMonth(date.getMonth());
    tstart.setYear(date.getYear());
    var tstop = new Date(row[3]);
    tstop.setDate(date.getDate());
    tstop.setMonth(date.getMonth());
    tstop.setYear(date.getYear());
    var loc = row[4];
    var desc = row[5];
    var id = row[6];              // Sixth column == eventId
    // Check if event already exists, update it if it does
    try {
      var event = cal.getEventSeriesById(id);
    }
    catch (e) {
      // do nothing - we just want to avoid the exception when event doesn't exist
    }
    if (!event) {
      //cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
      var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
      row[6] = newEvent;  // Update the data array with event ID
    }
    else {
      event.setTitle(title);
      event.setDescription(desc);
      event.setLocation(loc);
      // event.setTime(tstart, tstop); // cannot setTime on eventSeries.
      // ... but we CAN set recurrence!
      var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
      event.setRecurrence(recurrence, tstart, tstop);
    }
    debugger;
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);
}
_

削除/再作成

この代替方法では、eventIDを使用して、既存のイベントを見つけて削除します。その後、スプレッドシートのデータを使用して新しいイベントが作成されます。これには、開始時刻と終了時刻を含むイベントのすべての値を更新できるという利点があります(以下の注を参照)。一方、元のイベントに加えられた変更はすべて失われます。たとえば、他の人がイベントに招待された場合や、カスタムアラームが追加された場合などです。

この代替方法を使用するには、一致するコードを次のように置き換えます。

_// Check if event already exists, delete it if it does
try {
  var event = cal.getEventSeriesById(id);
  event.deleteEventSeries();
  row[6] = '';  // Remove event ID    
}
catch (e) {
  // do nothing - we just want to avoid the exception when event doesn't exist
}
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();
row[6] = newEvent;  // Update the data array with event ID
debugger;
_

ノート

  • getEventSeriesByIdのドキュメントには、一致するイベントが見つからない場合にnullを返し、代わりに例外をスローするという誤った記述があります。 (厄介!)だから、水泳を続けるためだけにtry/catchブロックに入れました。
  • 残念ながら、getEventSeriesByIdはイベントの取得に機能しますが、returnsおよびEventSeriesオブジェクトはsetTime()メソッドをサポートしません。イベントの時間を変更する予定がない場合は、これで問題ありません。それ以外の場合は、recurrenceルールと回数を設定してEventEventSeriesに変更するか、古いイベントを削除して新しいイベントを作成できます、Delete/Recreateに示すように。 問題1154
  • スプレッドシートが常に優先されます。 Googleカレンダーを介して記録されたイベントの関連するフィールドの変更は、スクリプトによって上書きされます。
38
Mogsdad

使用したい人のためにこれを投稿したいので、すでに使用していたシート内で動作するようにスクリプトを変更しました。日付の形式とイベントの重複は修正が必要ないくつかの問題でしたが、いくつかのテストの後、これがどのように機能するかにかなり満足していません。市。次のステップは、カレンダーイベントをスプレッドシートにプルして両方の方法で動作できるようにすることです。また、スマートフォンのカレンダーアプリを使用してその場でジョブを予約できるので、すべての耳にアドバイスがあれば、挿入するスクリプトも必要です。応答データを同じシートに作成し、既存のデータをそのままにして、ジョブ番号が一致する完全な行を追加します。

`function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Export Events",
functionName : "exportEvents"
}];     sheet.addMenu("Calendar Actions", entries);
};

function parseDate(s) {
var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,
            jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
var p = s.replace(".", "").split('-');
return new Date(p[2], months[p[1].toLowerCase()], p[0]);
}

/**
* Export events from spreadsheet to calendar
*/
function exportEvents() {
var sheet = SpreadsheetApp.getActiveSheet();

var headerRows = 6;  // Number of rows of header info (to skip)
var range = sheet.getDataRange();
var data = range.getDisplayValues();
//var calId = "Your calendar Id"; // PRODUCTION
var calId = "Your_calendar Id to test"; // TEST
var cal = CalendarApp.getCalendarById(calId);
//Logger.log(cal);
//Logger.log(data.length);
for (i=0; i<data.length; i++) {
if (i < headerRows) continue; // Skip header row(s)
if (data[i][0].length < 1) continue; // Skip if no content.

var row    = data[i];
Logger.log(row);
var date   = parseDate(row[0]);  // First column
//Logger.log(date);
var title  = row[1];           // Second column

var tstart = new Date();
var s = row[2].split(":");
tstart.setHours(s[0]);
tstart.setMinutes(s[1]);
tstart.setSeconds(s[2]);
tstart.setDate(date.getDate());
tstart.setMonth(date.getMonth());
tstart.setYear(date.getYear());

var tstop = new Date();
var e = row[3].split(":");
tstop.setHours(e[0]);
tstop.setMinutes(e[1]);
tstop.setSeconds(e[2]);

tstop.setDate(date.getDate());
tstop.setMonth(date.getMonth());
tstop.setYear(date.getYear());
var loc  = row[4];
var desc = row[5];
var id   = row[6];              // Sixth column == eventId
// Check if event already exists, update it if it does
var event = null;
if (id.length > 0) {
try {
event = cal.getEventSeriesById(id);
}
catch (e) {
// do nothing - we just want to avoid the exception when event doesn't            exist
} 
}
if (!event) {
//cal.createEvent(title, new Date("March 3, 2010 08:00:00"), new
Date("March 3, 2010 09:00:00"), {description:desc,location:loc});
var newEvent = cal.createEvent(title, tstart, tstop,                                     
{description:desc,location:loc}).getId();                     
var r = i + 1;
var cell = sheet.getRange("G" + r);
cell.setValue(newEvent);
}
else {
Logger.log(event);
event.setTitle(title);
event.setDescription(desc);
event.setLocation(loc);
// event.setTime(tstart, tstop); // cannot setTime on eventSeries.
// ... but we CAN set recurrence!
var recurrence = CalendarApp.newRecurrence().addDailyRule().times(1);
event.setRecurrence(recurrence, tstart, tstop);
}
debugger;
}
}

`

4
Jarrod Rapson