简体   繁体   English

如何在多个 gmail 日历上运行脚本

[英]How to run a script on several gmail calendars

I have multiple staff who input their day into a goggle calendar and I take the data and run stats.我有多名员工将他们的一天输入到护目镜日历中,我获取数据并运行统计数据。 At the moment I can only take data from one calendar at a time.目前我一次只能从一个日历中获取数据。 How can I take this script and make it work on several calendars?我怎样才能使用这个脚本并让它在多个日历上工作?

Note that each calendar has its own target sheet.请注意,每个日历都有自己的目标表。 I've tried duplicating the script but only one version seems to work at a time.我试过复制脚本,但一次似乎只有一个版本有效。

function export_gcal_to_gsheet() {
  var mycal = "person email";
  var cal = CalendarApp.getCalendarById(mycal);
  var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PersonCalendar");
  sheet.clearContents();
  var calColor = cal.getColor();
  var colors = Calendar.Colors.get().calendar;
  var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
  var offset = 6;
  var { v, c } = events.reverse().reduce((o, e, i) => {
    var color = e.getColor();
    var row = offset + i + 1;
    var c = colors[color] ? colors[color].background : calColor;
    var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
    o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
    o.c.push([c]);
    return o;
  }, { v: [], c: [] });
  var values = [header, ...v];
  sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
  sheet.getRange(7, 7, v.length - 1).setNumberFormat('.00');
  sheet.getRange(7, 15, c.length).setBackgrounds(c);
}

In your script, only one Calendar ID is used.在您的脚本中,只使用了一个日历 ID。 In order to use multiple Calendar IDs, when your showing script is modified for using multiple Calendar IDs, how about the following modification?为了使用多个日历ID,当你的展示脚本被修改为使用多个日历ID时,下面的修改怎么样?

Modified script 1:修改后的脚本 1:

In this modification, all values are put to "PersonCalendar" sheet.在此修改中,所有值都放在“PersonCalendar”表中。

function export_gcal_to_gsheet() {
  var calendarIds = ["person email1", "person email2",,,]; // Please set your Calendar IDs.

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("PersonCalendar");
  sheet.clearContents();
  var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
  var colors = Calendar.Colors.get().calendar;
  var { vv, cc } = calendarIds.reduce((oo, mycal) => {
    var cal = CalendarApp.getCalendarById(mycal);
    var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
    var calColor = cal.getColor();
    var offset = 6;
    var { v, c } = events.reverse().reduce((o, e, i) => {
      var color = e.getColor();
      var row = offset + i + 1;
      var c = colors[color] ? colors[color].background : calColor;
      var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
      o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
      o.c.push([c]);
      return o;
    }, { v: [], c: [] });
    oo.vv = [...oo.vv, ...v];
    oo.cc = [...oo.cc, ...c];
    return oo;
  }, { vv: [], cc: [] });
  var values = [header, ...vv];
  sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
  sheet.getRange(7, 7, vv.length - 1).setNumberFormat('.00');
  sheet.getRange(7, 15, cc.length).setBackgrounds(cc);
}
  • In this modification, by retrieving the values from multiple Calendar IDs, all retrieved values are put to the Spreadsheet.在此修改中,通过从多个日历 ID 中检索值,将所有检索到的值放入电子表格。

Modified script 2:修改后的脚本 2:

In this modification, the values of each Calendar are put to each sheet.在此修改中,每个日历的值都放在每个工作表中。

function export_gcal_to_gsheet() {
  var obj = [{ mycal: "person email1", sheetName: "PersonCalendar" }];
  var colors = Calendar.Colors.get().calendar;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  obj.forEach(({ mycal, sheetName }) => {
    var cal = CalendarApp.getCalendarById(mycal);
    var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
    var sheet = ss.getSheetByName(sheetName);
    sheet.clear(); // or sheet.clearContents();
    var calColor = cal.getColor();
    var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
    var offset = 6;
    var { v, c } = events.reverse().reduce((o, e, i) => {
      var color = e.getColor();
      var row = offset + i + 1;
      var c = colors[color] ? colors[color].background : calColor;
      var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
      o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
      o.c.push([c]);
      return o;
    }, { v: [], c: [] });
    var values = [header, ...v];
    sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
    sheet.getRange(7, 7, v.length - 1).setNumberFormat('.00');
    sheet.getRange(7, 15, c.length).setBackgrounds(c);
  });
}

Modified script 3:修改后的脚本 3:

In this modification, the values of each Calendar are put on each sheet.在此修改中,每个日历的值都放在每个工作表上。 And, by using Sheets API, the process cost is reduced a little from that of "Modified script 2".并且,通过使用工作表 API,与“修改脚本 2”相比,工艺成本有所降低。 So, please enable Sheets API at Advanced Google services .因此, 请在 Advanced Google services 启用 Sheets API

function export_gcal_to_gsheet() {
  var obj = [{ mycal: "person email1", sheetName: "PersonCalendar" },,,]; // Please set calendar IDs and sheet names.

  var colors = Calendar.Colors.get().calendar;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var { valuesBatchUpdate, batchUpdate } = obj.reduce((oo, { mycal, sheetName }) => {
    var cal = CalendarApp.getCalendarById(mycal);
    var calColor = cal.getColor();
    var events = cal.getEvents(new Date("July 01, 2022 00:00:00 UTC"), new Date());
    var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
    var offset = 6;
    var { v, c } = events.reverse().reduce((o, e, i) => {
      var color = e.getColor();
      var row = offset + i + 1;
      var c = colors[color] ? colors[color].background : calColor;
      var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
      o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), (events[i].getStartTime().getTime() / 1000 / 86400) + 25569, (events[i].getEndTime().getTime() / 1000 / 86400) + 25569, f, ('' + events[i].getVisibility()), (events[i].getDateCreated().getTime() / 1000 / 86400) + 25569, (events[i].getLastUpdated().getTime() / 1000 / 86400) + 25569, events[i].getMyStatus().toString(), events[i].getCreators().join(","), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
      o.c.push([c]);
      return o;
    }, { v: [], c: [] });
    var sheetId = ss.getSheetByName(sheetName).getSheetId();
    var hexToRgb = hex => { // Ref: https://stackoverflow.com/a/11508164
      var bigint = parseInt(hex, 16);
      var red = ((bigint >> 16) & 255) / 255;
      var green = ((bigint >> 8) & 255) / 255;
      var blue = (bigint & 255) / 255;
      return { red, green, blue }
    };
    oo.valuesBatchUpdate.push({ range: `'${sheetName}'!A6`, values: [header, ...v] });
    oo.batchUpdate.push(
      { updateCells: { fields: "*", range: { sheetId } } },
      { repeatCell: { range: { sheetId, startRowIndex: 6, endRowIndex: 6 + v.length, startColumnIndex: 6, endColumnIndex: 7 }, cell: { userEnteredFormat: { numberFormat: { pattern: '.00', type: "NUMBER" } } }, fields: "userEnteredFormat.numberFormat" } },
      { repeatCell: { range: { sheetId, startRowIndex: 6, endRowIndex: 6 + v.length, startColumnIndex: 4, endColumnIndex: 6 }, cell: { userEnteredFormat: { numberFormat: { pattern: 'yyyy/MM/dd', type: "DATE" } } }, fields: "userEnteredFormat.numberFormat" } },
      { repeatCell: { range: { sheetId, startRowIndex: 6, endRowIndex: 6 + v.length, startColumnIndex: 8, endColumnIndex: 10 }, cell: { userEnteredFormat: { numberFormat: { pattern: 'yyyy/MM/dd', type: "DATE" } } }, fields: "userEnteredFormat.numberFormat" } },
      { updateCells: { rows: c.map(([hex]) => ({ values: [{ userEnteredFormat: { backgroundColor: hexToRgb(hex.replace("#", "")) } }] })), range: { sheetId, startRowIndex: 6, endRowIndex: 6 + c.length, startColumnIndex: 14, endColumnIndex: 15 }, fields: "userEnteredFormat.backgroundColor" } }
    );
    return oo;
  }, { valuesBatchUpdate: [], batchUpdate: [] });
  var ssId = ss.getId();
  Sheets.Spreadsheets.batchUpdate({ requests: batchUpdate }, ssId);
  Sheets.Spreadsheets.Values.batchUpdate({ data: valuesBatchUpdate, valueInputOption: "USER_ENTERED" }, ssId);
}

Note:笔记:

  • In this case, when you have no permissions for accessing the Calendar IDs, an error occurs.在这种情况下,当您没有访问日历 ID 的权限时,就会发生错误。 Please be careful about this.请注意这一点。

Both of the following techniques distribute the output to separate sheets and leave most of the original code intact.以下两种技术将 output 分发到单独的工作表中,并完整保留大部分原始代码。

function exportcalenders() {
  const calids = [{ id: "calid", shnam: "Sheet Name"}];
  calids.forEach(obj => {
    var cal = CalendarApp.getCalendarById(obj.id);
    var events = cal.getEvents(new Date(new Date().getFullYear(),newDate().getMonth(),1),new Date());
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(obj.shnam);
    sheet.clearContents();
    var calColor = cal.getColor();
    var colors = Calendar.Colors.get().calendar;
    var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
    var offset = 6;
    var { v, c } = events.reverse().reduce((o, e, i) => {
      var color = e.getColor();
      var row = offset + i + 1;
      var c = colors[color] ? colors[color].background : calColor;
      var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
      o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
      o.c.push([c]);
      return o;
    }, { v: [], c: [] });
    var values = [header, ...v];
    sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
    sheet.getRange(7, 7, v.length - 1).setNumberFormat('.00');
    sheet.getRange(7, 15, c.length).setBackgrounds(c);
  });

}

Here's another way using recursion:这是使用递归的另一种方式:

This version assumes that all of the calendars are shared with you and thus accessible via getAllCalendars.此版本假定所有日历都与您共享,因此可以通过 getAllCalendars 访问。 The inclCals variable allows you to only include certain calendars from getAllCalendars list and snames is a list of sheets that you wish each calendar to be assigned two. inclCals 变量允许您仅包含 getAllCalendars 列表中的某些日历,而 snames 是您希望为每个日历分配两个工作表的列表。 The variable obj transfers all of that information to main cal via cacheService.变量 obj 通过 cacheService 将所有这些信息传输到 main cal。

function xportcals() {
  let inclCals = ["CalName1", "CalName2", "CalName3", "CalName4"];
  let snames = ["Sheet1","Sheet2","Sheet3","Sheet4"]
  let obj = CalendarApp.getAllCalendars().reduce((a, c, i) => {
    let idx = inclCals.indexOf(c.getName());
    if (~idx) {
      a["cal"].push({ id: c.getId(), name: c.getName(),sheetname:snames[idx]});
    }
    return a;
  }, { cal: [], proc: { level: 0, som: 1, sod: 1 } });
  CacheService.getScriptCache().put("cals", JSON.stringify(obj), 300);
  maincals();
}

    function maincals() {
      let obj = JSON.parse(CacheService.getScriptCache().get("cals"));
      var cal = CalendarApp.getCalendarById(obj.cal[obj.proc.level]);
      var events = cal.getEvents(new Date(new Date().getFullYear(), newDate().getMonth() - obj.proc.som , obj.proc.sod), new Date());
      var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(obj.cal.sheetname);
      sheet.clearContents();
      var calColor = cal.getColor();
      var colors = Calendar.Colors.get().calendar;
      var header = ["Calendar Address", "Event Title", "Event Description", "Event Location", "Event Start", "Event End", "Calculated Duration", "Visibility", "Date Created", "Last Updated", "MyStatus", "Created By", "All Day Event", "Recurring Event", "Color"];
      var offset = 6;
      var { v, c } = events.reverse().reduce((o, e, i) => {
        var color = e.getColor();
        var row = offset + i + 1;
        var c = colors[color] ? colors[color].background : calColor;
        var f = `=(HOUR(F${row})+(MINUTE(F${row})/60))-(HOUR(E${row})+(MINUTE(E${row})/60))`;
        o.v.push([mycal, events[i].getTitle(), events[i].getDescription(), events[i].getLocation(), events[i].getStartTime(), events[i].getEndTime(), f, ('' + events[i].getVisibility()), events[i].getDateCreated(), events[i].getLastUpdated(), events[i].getMyStatus(), events[i].getCreators(), events[i].isAllDayEvent(), events[i].isRecurringEvent(), c]);
        o.c.push([c]);
        return o;
      }, { v: [], c: [] });
      var values = [header, ...v];
      sheet.getRange(6, 1, values.length, values[0].length).setValues(values);
      sheet.getRange(7, 7, v.length - 1).setNumberFormat('.00');
      sheet.getRange(7, 15, c.length).setBackgrounds(c);
      obj.proc.level += 1;//increment the level counter
      CacheService.getScriptCache().put("cals", JSON.stringify(obj), 60);//save obj in cacheService
      if (obj.proc.level < obj.cal.length) {
        maincals();
      }
      return;
    }

I did not test this particular version but I did test a simpler version and most of the parts that are not common to what I tested are your original code which presumably works.我没有测试这个特定的版本,但我确实测试了一个更简单的版本,并且我测试的大部分不常见的部分都是你的原始代码,它们可能是有效的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM