Подтвердить что ты не робот

Создавать события календаря Google из таблицы, но не допускать дублирования

Я пытаюсь написать script, который будет принимать данные из электронной таблицы Google и создавать события в календаре Google.

Мне удалось это прекрасно, но он производил дубликаты каждый раз, когда я запускал его. Поэтому теперь я пытаюсь предотвратить это, создав столбец 17 в электронной таблице с автоматически созданным уникальным идентификатором события для каждой строки, а затем каждый раз при запуске script он будет искать идентификатор события для каждой строки и удалять соответствующее событие в календаре, прежде чем воссоздать его с исходными данными или обновленными данными, если я изменил строку.

Я новичок в создании скриптов любого типа и булыжник вместе, но сейчас ударяю о стену. Может кто-нибудь помочь разобраться в этом?

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);
    }
}
4b9b3361

Ответ 1

Это очень похоже на вопрос, заданный всего два дня назад, а именно синхронизацию электронной таблицы событий с календарем. Похоже, вы хотите, чтобы электронная таблица была хозяином происходящих событий, что значительно упростило бы проблему. Основы того, что вам нужно сделать, описаны в этом ответе. Если вы хотите просто изменить существующий код, у меня есть реализация ниже.

У меня есть модифицированная версия кода из этого блога, который изменит ранее существовавшие записи календаря в соответствии с информацией в электронной таблице, Я разместил свою таблицу по-разному, и это отражено в коде.

Дата | Название | Время начала | Время окончания | Расположение | Описание | EventID

Столбец идентификатора события заполняется script при создании новых событий и затем используется в последующих вызовах для извлечения событий из календаря, тем самым избегая дублирования.

Script

/**
 * 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 a EventSeries, который не поддерживает метод setTime(). Если вы не ожидаете изменить время событий, это нормально. В противном случае вы можете изменить Event на EventSeries, установив правила повторения и время, или удалите старое событие и создайте новый, как показано в Удалить/Восстановить. Проблема 1154.
  • Таблица всегда выигрывает. Любые изменения событий (в соответствующих полях), записанные через Календарь Google, будут перезаписаны script.

Ответ 2

Id нравится публиковать это для всех, кто хотел бы использовать его, я модифицировал script для работы на листе, который я уже использовал. Формат даты и дублирование событий были двумя проблемами, которые необходимо было исправлять, но после некоторого тестирования им очень понравилось, как это работает. Я использую его для работы с книгами и обмена ими с моими сотрудниками, которые являются мобильными, и работают по типу конструкции по всей город. Следующий шаг - вытащить события календаря в электронную таблицу, чтобы он мог работать в обоих направлениях, и я могу использовать приложение календаря на своем телефоне, чтобы заказывать задания "на лету", поэтому, если у кого-то есть какие-либо советы в ушах, мне также нужен script для вставки данных ответа формы в тот же лист и добавления полных строк, где номера заданий соответствуют сохранению существующих данных.

`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;
}
}

`