【问题标题】:How to set values for all columns except one?如何为除一列之外的所有列设置值?
【发布时间】:2014-09-10 16:03:34
【问题描述】:

我的代码运行良好,它所做的只是从电子表格中获取事件并在谷歌日历上创建它们。 但是,我的电子表格中的一列包含一个公式。每次我运行代码时,公式都会消失,并被当时该单元格上的任何内容替换。

我知道这就是问题所在:

   // Record all event IDs to spreadsheet except for row 7
   range.setValues(data);

如何编写一个循环来仅将其从第 [0] 行应用到第 [8] 行但跳过第 [7] 行?

但这里是完整的代码供参考:

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{
    name : "Export Events",
    functionName : "exportEvents"
  }];
  sheet.addMenu("Update Calendar", 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 = "calendar_ID";
  var cal = CalendarApp.getCalendarById(calId);
  for (i in data) {
    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 complete = row[6];
    var status = row[7];
    var id = row[8];              // Eight 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:"("+status+") "+desc,location:loc}).getId();
      row[8] = newEvent;  // Update the data array with event ID
    }
    else {
      event.setTitle(title);
      event.setDescription("("+status+") "+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 except for row 7
  range.setValues(data);
}

【问题讨论】:

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


    【解决方案1】:

    没有办法使用 setValues 来“选择性地”编写...我建议您将数组(垂直)拼接到 2 个新数组中,并使用 2 个不同的 setValues 编写它,而让公式的列保持不变。

    请注意,拼接数组方法水平拼接(对于二维数组),因此您必须循环到第一级并为每一行进行拼接,但使用数组非常快,因此不会成为问题.

    示例代码:(我从工作表中取出数据来演示)

    function spliceVertically() {
      var data = SpreadsheetApp.getActive().getActiveSheet().getDataRange().getValues();
      Logger.log('data = '+JSON.stringify(data));
      var data1 = [];
      var data2 = [];
      for(var n in data){
        data2.push(data[n].splice(7,1));// cut the row at col 8 and keep 1
        data1.push(data[n].splice(0,6));// cut at 0 and keep 6 , this method cut the array >> get data2 before data1
      }
      Logger.log('data1 = '+JSON.stringify(data1));
      Logger.log('data2 = '+JSON.stringify(data2));
    }
    


    编辑:

    要将它插入到您的代码中,只需像这样使用它:

      sh.getRange(1,1,data1.length,data1[0].length).setValues(data1);// update col 1 to 6
      sh.getRange(1,8,data2.length,data2[0].length).setValues(data2);// update col 8
    

    顺便说一句,你也可以使用切片方法...下面是一个完整的工作表更新测试:

    function spliceVertically() {
      var sh = SpreadsheetApp.getActive().getActiveSheet();
      var range = sh.getDataRange();
      var data = range.getValues();
      Logger.log('data = '+JSON.stringify(data));
      var data1 = [];
      var data2 = [];
      for(var n in data){
        data1.push(data[n].slice(0,8));
        data2.push(data[n].slice(9,10));
      }
      Logger.log('data1 = '+JSON.stringify(data1));
      Logger.log('data2 = '+JSON.stringify(data2));
      sh.getRange(1,1,data1.length,data1[0].length).setValues(data1);
      sh.getRange(1,10,data2.length,data2[0].length).setValues(data2);
    }
    


    最终编辑:在您的代码中实现的完整代码

    由于您似乎没有得到它的工作,下面是一个完整的实现。测试on this sheet

    function onOpen() {
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      var entries = [{
        name : "Export Events",
        functionName : "exportEvents"
      }];
      sheet.addMenu("Update Calendar", 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 = "h22nevo15tm0nojb6ul4hu7ft8@group.calendar.google.com"; //removed link on purpose
      var cal = CalendarApp.getCalendarById(calId);
      for (i in data) {
        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 complete = row[6];
        var status = row[7];
        var id = row[8];              // Eight 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:"("+status+") "+desc,location:loc}).getId();
          row[8] = newEvent;  // Update the data array with event ID
        }
        else {
          event.setTitle(title);
          event.setDescription("("+status+") "+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);
        }
        data[i]=row;// update data with row values otherwise it is lost !
      }
      Logger.log(data);
      var data1 = [];
      var data2 = [];
      for(var n in data){
        data1.push(data[n].slice(0,8));
        data2.push(data[n].slice(8,9));
      }
      Logger.log('data1 = '+JSON.stringify(data1));
      Logger.log('data2 = '+JSON.stringify(data2));
      sheet.getRange(1,1,data1.length,data1[0].length).setValues(data1); // write below to check where it writes !!!
      sheet.getRange(1,9,data2.length,data2[0].length).setValues(data2); // change row6 to 1 whan copying in real code !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      // Record all event IDs to spreadsheet except for row 7
    }
    

    【讨论】:

    • 我从来没有使用过这个,有什么建议可以适合代码吗?电子表格如下:日期|标题|开始时间|停止时间|位置|描述|完成|状态|事件ID|评论
    • 它有点工作。公式保持不变,这很好,但是,每次我运行脚本时,都会创建重复的事件......运行脚本应该为所有事件创建一个特定的 ID(第 8 行,第 0 行是第一列),这就是重复的方式抓住了,将您的脚本添加到我的脚本似乎会删除该功能。
    • 实际上 H 是需要保持原样的列。其他列将需要重写。但是使用此代码,我仍然看不到在 I 列上自动创建和显示事件 ID
    • 不太确定要为 ID 切换哪些数字 data1.push(data[n].slice(0,7)); data2.push(data[n].slice(8,9));
    • 是的,代码可以工作,但不再创建 EventID...知道为什么,这是一个问题,因为它现在每次运行时都会创建重复项
    猜你喜欢
    • 2018-08-29
    • 2018-12-16
    • 2022-01-16
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    相关资源
    最近更新 更多