#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";
.