Как установить значения для всех столбцов, кроме одного?

Мой код отлично работает, все, что он делает, это берет события из электронной таблицы и создает их в календаре Google. Однако один из столбцов в моей электронной таблице содержит формулу. Каждый раз, когда я запускаю код, формула исчезает и заменяется тем, что находится в этой ячейке в данный момент.

Я знаю, что здесь проблема:

   // 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);
}

person Arsene de Conde    schedule 10.09.2014    source источник


Ответы (1)


Невозможно написать «выборочно», используя setValues... Я предлагаю вам соединить ваш массив (по вертикали) с двумя новыми массивами и записать его с двумя разными 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);
}

введите здесь описание изображения


окончательное редактирование: полный код реализован в вашем

поскольку кажется, что вы не заработали, ниже приведена полная реализация. проверено на этом листе

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 = "[email protected]"; //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
}
person Serge insas    schedule 10.09.2014
comment
Я никогда не работал с этим, есть предложения, как это впишется в код? Электронная таблица выглядит следующим образом: дата|название|время начала|время окончания|местоположение|описание|завершено|статус|идентификатор события|комментарии - person Arsene de Conde; 10.09.2014
comment
это несколько работает. Формула остается прежней, и это здорово, однако каждый раз, когда я запускаю скрипт, создаются повторяющиеся события... запуск скрипта должен создавать определенный идентификатор (строка 8, строка 0 является первым столбцом) для всех событий, вот как дублируются поймал, добавление вашего скрипта к моему, похоже, удаляет эту функцию. - person Arsene de Conde; 10.09.2014
comment
на самом деле H - это столбец, который необходимо сохранить как есть. другие столбцы необходимо будет переписать. Но с этим кодом я все еще не вижу, чтобы идентификатор события автоматически создавался и отображался в столбце I. - person Arsene de Conde; 10.09.2014
comment
не слишком уверен, какие числа переключать для идентификатора data1.push(data[n].slice(0,7)); data2.push(данные[n].slice(8,9)); - person Arsene de Conde; 10.09.2014
comment
да, код работает, но EventID больше не создается... не знаю, почему, это проблема, потому что теперь он создает дубликаты каждый раз, когда я его запускаю - person Arsene de Conde; 11.09.2014
comment
да, формула не перезаписывается, но события все еще дублируются... идентификатор события не создается в столбце I - person Arsene de Conde; 11.09.2014
comment
Вот что в логгере для data2: [14-09-10 15:53:38:258 CDT] data2 = [[Comments],[Test 1],[Test 2],[Test 3]] - person Arsene de Conde; 11.09.2014
comment
электронная таблица имеет столбцы A - J (Дата|Название|Время начала|Время окончания| Местоположение|Описание|Завершено?|Статус|Идентификатор события|Комментарии| комментарий относительно идентификатора находится в: [14-09-10 16:02:48 :153 CDT] data = [[Дата,Название,Время начала,Время окончания,Местоположение,Описание,Завершено?,Статус,Идентификатор события,Комментарии] - person Arsene de Conde; 11.09.2014
comment
идентификатор события еще не создан, вот что у меня есть: docs.google .com/spreadsheets/d/ - person Arsene de Conde; 11.09.2014