Создание события календаря Google с помощью скрипта Google Sheets содержит ошибки

#javascript #google-apps-script #google-calendar-api

#javascript #google-apps-script #google-calendar-api

Вопрос:

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

Вот соответствующий код:

 function createCalendarEvent() {
var sheet = SpreadsheetApp.getActiveSheet();
var calendar = CalendarApp.getCalendarById('dentaldigitaldesign.bkp@gmail.com');

var startRow = 100;  // First row of data to process - 100 exempts my header row and adds to the case number count.
var numRows = sheet.getLastRow();   // Number of rows to process
var numColumns = sheet.getLastColumn();

var dataRange = sheet.getRange(startRow, 1, numRows-1, numColumns);
var data = dataRange.getValues();

var complete = "TRUE";

for (var i = 0; i < data.length;   i) {
  var row = data[i];
  var caseID = row[0]; //Case ID Number
  var patient = row[4]; //Patient Name
  var doctor = row[5];  //Doctor
  var contact = row[14]; //Doctor contact info
  var tooth = row[15]; //Tooth number
  var shade = row[10]; //Tooth Shade
  var notes = row[8];  //Notes
  var callNotes = row[7]; //Call notes if there are any
  var timeStamp = new Date (row[2]); //Retrieve the timestamp field
  // year as 4 digits (YYYY)
  var year = timeStamp.getFullYear();
  // month as 2 digits (MM)
  var month = ("0"   (timeStamp.getMonth()   1)).slice(-2);

  // date as 2 digits (DD)
  var day = ("0"   timeStamp.getDate()).slice(-2);
  
  var dueDate = new Date(month   day,   year);  //Due  date
  var rDate = new Date(row[2]-1); //Remind date
  var caseComplete = row[3]; //Case marked as complete
 
  if (caseComplete !== complete amp;amp; caseID !== null) {
    var currentCell = sheet.getRange(startRow   i, numColumns);
    calendar.createEvent(patient, rDate, rDate, {
      description: doctor   'r'   patient   'r'   contact   'r'   dueDate   'r'   tooth   'r'   shade   'r'   notes   'r'   callNotes
    });
  
    currentCell.setValue(complete);
  }
}
}
  

Когда эти события создаются, все они создаются для 8:59 утра. В идеале, я мог бы выполнить проверку в календаре, если событие установлено на это время, новое событие добавляется сразу после. (возможно, через 15 или 30 минут). На данный момент мне хорошо удается получать напоминания о случаях, которые должны быть выполнены, но в конечном итоге приглашение к врачу, чтобы они знали дату выполнения, тоже может хорошо сработать.

Я также могу использовать справку по форматированию поля описания, поскольку оно не вводит возвращаемое значение, и все находится в одной строке.

И, наконец, скрипт продолжает выполняться на многочисленных полях, выходящих за рамки желаемых строк, что в конечном итоге приводит к сбою скрипта, поскольку слишком много попыток создания событий создаются за слишком короткое время. (все попытки с пустыми полями не приводят к созданию каких-либо событий, но это проблема resouce …. и кто знает, может быть, Google в конечном итоге блокирует меня?)

Я ценю любую помощь, которая может быть предложена.

Вот ссылка на Google Sheet. Никакие данные в нем не являются конфиденциальными, поскольку это только тестовые данные: https://docs.google.com/spreadsheets/d/1M9qYzSl1PnRv-GehHEYvpiag15UI_GjnanA0wgA4xmg/edit?usp=sharing

Комментарии:

1. Не могли бы вы предоставить копию электронной таблицы, над которой вы работаете, без конфиденциальной информации?

2. Вот таблица. Он не чувствителен, поскольку находится только в разработке с тестовыми данными. docs.google.com/spreadsheets/d /…

Ответ №1:

В вашем коде есть несколько проблем, из-за которых это выражение всегда возвращается true , так что скрипт пытается создать событие для каждой строки:

 if (caseComplete !== complete amp;amp; caseID !== null) {
  

Пустая строка !== null:

Вы хотите проверить, является ли ячейка в столбце A пустой (то есть, является ли ее значение пустой строкой), и для этого вы сравниваете ее значение с null. null это не то же самое, что пустая строка, поэтому всегда будет следующее выражение true (значение ячейки никогда не возвращается null ):

 caseID !== null
  

Вы должны сравнивать это с пустой строкой. Например, вот так:

 caseID !== ""
  

Таким образом, if утверждение должно быть:

 if (caseComplete !== complete amp;amp; caseID !== "") {
  

Неверно заполненный столбец:

После создания события вы хотите установить соответствующую ячейку в D на TRUE . Вы этого не делаете, поскольку указываете последний столбец в листе ( numColumns ) при настройке currentCell :

 var currentCell = sheet.getRange(startRow   i, numColumns);
  

Из-за этого значение в D никогда не меняется на TRUE , поэтому caseComplete !== complete всегда true .

Вместо D этого вы должны указать правильный индекс столбца, который 4 . Это должно быть так:

 var currentCell = sheet.getRange(startRow   i, 4);
  

Редактировать: Кроме того, полученное значение для ячейки с установленными флажками является логическим true , и вы пытаетесь сравнить его со строкой TRUE . Из-за этого это условие работает некорректно. Пожалуйста, измените:

 var complete = "TRUE";
  

Для

 var complete = true;
  

Неправильное количество строк в исходном диапазоне:

Вы хотите получить значение из строки 100 до последнего на листе. В этом случае общее количество строк в диапазоне должно быть последней строкой ( numRows ) минус первая строка в диапазоне ( startRow ) плюс одна ( numRows - startRow 1 ). dataRange Вместо этого должно быть определено следующим образом:

 var dataRange = sheet.getRange(startRow, 1, numRows - startRow   1, numColumns);
  

Ссылка:

Комментарии:

1. Спасибо. Я вижу ошибки в операторе if. Что касается изменения поля «Завершить», я не хочу делать это программно, но будет введено вручную, когда обращение будет завершено. Коду просто нужно проверить, завершено ли оно (вручную), а затем перейти к следующей строке. Окончательное утверждение ‘complete’ было исходным кодом, который я нашел, и не имело реального негативного эффекта, поэтому я оставил его. Еще раз спасибо за вашу помощь.

2. С учетом сказанного, когда флажок установлен «Завершено» (присваивая значение TRUE), ожидается, что оператор IF / AND окажется ложным, и код будет пропущен для этой строки. Я хочу избежать дублирования событий. И по какой-то причине последняя строка в моей текущей электронной таблице не приводит к новому событию, несмотря на то, что флажок снят.

3. @JeremiahHolder With that said, when the checkbox is checked 'Complete' (giving a value of TRUE), by expectation is that the IF / AND statement would prove false and the code would be skipped for that row. I want to avoid duplicate creations of events. . Итак, это работает так, как ожидалось, верно?

4. @JeremiahHolder And for some reason, the final row in my current spreadsheet does not result in a new event despite being unchecked. : Заполнен ли столбец A в этой последней строке, чтобы код попал в IF блок?

5. @JeremiahHolder только что заметил проблему с флажками. Значение для флажков является логическим true , пока вы сравниваете его со строкой TRUE . Чтобы решить эту проблему, установите var complete = true; вместо var complete = "TRUE"; .