通过电子表格

时间:2016-08-07 17:37:27

标签: google-apps-script google-sheets google-calendar-api

我正在尝试创建一个工作表,从单个Google工作表中将事件创建到多个Google日历中。我正在使用从Mogsdad发表的这篇文章Create Google Calendar Events from Spreadsheet but prevent duplicates中的精彩解决方案修改的表格。然而,我一直在将我的工作重复三次进入3个不同的日历,并希望我第一次参加编程。我的想法是我想更进一步,添加一个下拉列(标记状态),其中包含(未确认,保存日期,已确认),然后在一个或所有三个日历中创建一个名为与条件相同的日历下降。

我的表格安排如下: -

  

日期|标题|开始时间|结束时间|位置|说明|甚至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 = "30kpfnt5jlnooo688qte6ladnk@group.calendar.google.com";
  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, 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;
  }
  // Record all event IDs to spreadsheet
  range.setValues(data);
}

所以我意识到我需要定义新信息以进入“已确认”日历以及另外2个日历。我的问题是我不知道如何适应一系列if循环来将事件引导到3个日历。我也希望日历是附加的,例如所有事件都出现在“未确认的日历”事件中,以便在升级到该状态时保存日期,然后在设置为“确认”时最终显示。因此,所有3个日历中都会显示已确认的事件,但只会出现未经证实的事件。

我对编程几乎是全新的,所以请您好好并原谅我对其他人的公然庸俗工作(感谢Mogsdad),我感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

欢迎编程!一旦掌握了它,您就会想要编写您使用的每个Google产品的脚本。 :)

如果我正确理解您的问题,您希望能够选择在运行函数exportEvents()时事件进入的日历。有几种方法可以做到这一点,你不需要任何额外的循环!您可以使用对象并按名称引用它们。

我首先要做的是,您当前定义calcalId的位置是创建一个定义三个日历的对象,如下所示:

var cal1 = "30kpfnt5jlnooo688qte6ladnk@group.calendar.google.com";
var cal2 = "string url for second calendar";
var cal3 = "string url for third calendar";
var calendars = {
   Unconfirmed: CalendarApp.getCalendarById(cal1),
   SaveTheDate: CalendarApp.getCalendarById(cal2),
   Confirmed: CalendarApp.getCalendarById(cal3)
}

对象calendars现在包含三个日历的日历对象,以便为状态,为对象。然后,当您抓取每行的数据时,添加

var cal = row[7];

现在,cal包含指示状态的字符串。您可以通过对newEvent定义进行一次更改来充分利用链接:

var newEvent = calendars[cal].createEvent(title, tstart, tstop, {description:desc,location:loc}).getId();

这里发生的是calendars[cal]获取与表中字符串对应的日历对象,然后您可以添加新事件。这确实需要对工作表进行更改 - 将状态列中的标签从“保存日期”更改为“SaveTheDate”,以使其与变量名称匹配。应该这样做!

修改

要将事件添加到多个日历,我会使用if语句,但您不需要循环。以下内容可行:

calendars['Unconfirmed'].createEvent(title...  // Add to unconfirmed no matter what
if (cal != 'Unconfirmed'){
  calendars['SaveTheDate'].createEvent(title... // Add to SaveTheDate only if not Unconfirmed
}
if (cal == 'Confirmed'){
  calendars['Confirmed'].createEvent(title...  // Only add to Confirmed if Confirmed
}