#javascript #google-apps-script #google-sheets
Вопрос:
цель
- Создайте систему бронирования с помощью формы Google, таблиц и календаря
- При появлении новой отправки автоматически создается событие календаря.
- Респондент также может отредактировать свое представление (изменить URL-адрес формы).
- При редактировании старое событие будет удалено, а затем будет создано новое событие.
ТЕКУЩАЯ ПРОБЛЕМА
- При редактировании строки функция updateCalendar() также выполнит цикл по всему диапазону данных; событие удаления из первой строки.
Как убедиться, что функция работает только с редактируемой строкой?
Вот как выглядит первая строка листа.
Отметка времени | Эл. адрес | Имя | Дата заезда | Дата отъезда | Комната | Нет. людей | всего за день | весь | изменить URL-адрес | Event Conflict | Event ID |
---|
МЕТОДОМ ПРОБ И ОШИБОК
В настоящее время я борюсь с этим фрагментом кода, который будет:
- Вставьте сгенерированный URL-адрес редактирования (из другой функции) в URL-адреса переменных
- Переместите сгенерированный идентификатор события в переменную ids
- Сопоставив индекс URL-адресов и идентификаторов, назначьте его переменной resultIds и удалите.
Это часть кода, которая будет выполнять вышеуказанные функции
var urls = [], ids = [], resultIds = [];
urls.push(values[i][9]);
ids.push(newEventId);
resultIds.push([values[i][9]?ids[urls.indexOf(values[i][9])]:'']);
Это полная функция, которая обновит календарь: (любая помощь будет очень признательна, заранее спасибо)
function updateCalendar(request) {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = sheet.getRange(2,1,lastRow,13);
var values = range.getDisplayValues();
var calendar = CalendarApp.getCalendarById('c_qsk903qma3b8mp5ensa7bvvg4k@group.calendar.google.com');
var urls = [], ids = [], editIds = [];
getConflicts(request);
for (var i = 0; i < values.length; i ) {
urls.push(values[i][9]);
if (request.eventConflict == "conflict" amp;amp; values[i][12] != "sent") {
sheet.getRange(lastRow,11).setValue("conflict");
break;
} else if (request.eventConflict == "approve" amp;amp; values[i][12] != "sent") {
var newEvent = calendar.createEvent("booked", request.date, request.endTime);
var newEventId = newEvent.getId().split('@')[0];
sheet.getRange(lastRow,11).setValue("approve");
sheet.getRange(lastRow,12).setValue(newEventId);
ids.push(newEventId);
break;
} else if (request.eventConflict == "conflict" amp;amp; values[i][10] == "approve" amp;amp; values[i][12] == "sent") {
editIds.push([values[i][0]?ids[urls.indexOf(values[i][0])]:'']);
var eventEditId = calendar.getEventSeriesById(values[i][11]);
eventEditId.deleteEventSeries();
sheet.getRange(i 2,11).setValue("");
sheet.getRange(i 2,13).setValue("");
getConflicts(request);
if (request.eventConflict == "approve") {
var newEvent = calendar.createEvent("booked", request.date, request.endTime);
var newEventId = newEvent.getId().split('@')[0];
sheet.getRange(i 2,11).setValue("approve");
sheet.getRange(i 2,12).setValue(newEventId);
break;
} else {
sheet.getRange(i 2,11).setValue("conflict");
break;
}
}
}
};
Комментарии:
1. Можете ли вы объяснить, что вы подразумеваете под
How can I make sure that the sheet will delete event from the right row
этим ?2. Привет, Рафа, спасибо за ответ. Что я подразумеваю под этим утверждением, так это то, что в текущей версии следующая отправка также удалит событие из предыдущей отправки (возможно, это как-то связано с циклом for (). Поэтому я пытаюсь выяснить, как получить индекс строки в случае, если респондент редактирует свое собственное представление (через форму редактирования).
3. имейте в виду, что мы не видим здесь полной картины, возможно, для Рафы этого было достаточно, но мне немного непонятно, что такое «предыдущее представление» (я был в процессе написания того же комментария, но остановился, когда увидел, что Рафа опубликовал его). Это несвязанное событие, которое удаляется? Последняя запись в электронной таблице? Можете ли вы предоставить образец набора данных и то, что удаляется, что не должно удаляться.
4. Привет, Витаутас, спасибо за ответ, я только что добавил скриншот: 1) 4 новых представления подряд 2) и что произошло, когда я редактировал представление из 3-й строки.
5. Извините за поздний ответ, у меня не было возможности сесть и просмотреть код. Цикл for кажется немного перегруженным, так как там происходит много такого, что на самом деле невозможно правильно понять, если кто-то другой посмотрит на код. У меня нет возможности узнать, какие операторы if будут выполнены, когда из-за неоднозначного
request.eventConflict
значения, которое нигде не определено в коде. Кроме того, я вижу, что вы пытаетесь изменитьgetRange(i 2, 11)
дважды, один раз на пустое значение, а затем снова наapprove
илиconflict
. Это намеренно или вы неправильно поставили закрывающую скобку?
Ответ №1:
Я использовал два листа в одной электронной таблице, а затем использовал метод e.range для получения индекса отредактированной строки. Это и есть код
function updateCalendarTwo(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var responsename = "Main sheet"
var copyname = "Copy Sheet";
var responsesheet = ss.getSheetByName(responsename);
var copysheet = ss.getSheetByName(copyname);
var calendar = CalendarApp.getCalendarById('Your Calendar ID');
// columns on copysheet
var checkInCol = 4;
var checkOutCol = 5;
var roomNumCol = 6;
var appCol = 11
var eventIDCol = 12;
var revCol = 14;
var response = e.range;
var rRow = response.getRow()
var rLC = responsesheet.getLastColumn();
var cLC = copysheet.getLastColumn();
var rLR = responsesheet.getLastRow();
var cLR = copysheet.getLastRow();
if (rLR > cLR){
var resprange = responsesheet.getRange(rLR,1,1,rLC);
var respdata = resprange.getValues();
copysheet.appendRow(respdata[0]);
var eventTitle = copysheet.getRange(rRow,roomNumCol).getValue();
var startDate = copysheet.getRange(rRow,checkInCol).getValue();
var endDate = copysheet.getRange(rRow,checkOutCol).getValue().getTime() 24 * 60 * 60 * 1000;
var conflicts = calendar.getEvents(new Date(startDate), new Date(endDate));
if (conflicts.length < 1) {
var event = calendar.createAllDayEvent(eventTitle, new Date(startDate), new Date(endDate));
var eventID = event.getId().split('@')[0];
copysheet.getRange(rRow,appCol).setValue("approve");
copysheet.getRange(rRow,eventIDCol).setValue(eventID);
} else {
copysheet.getRange(rRow,appCol).setValue("conflict");
}
} else {
var resprange = responsesheet.getRange(rRow,1,1,9);
var respdata = resprange.getValues();
var copyrespRange = copysheet.getRange(rRow,1,1,9);
copyrespRange.setValues(respdata);
var respAppRange = copysheet.getRange(rRow,appCol);
var respApp = respAppRange.getValue();
if (respApp == 'conflict') {
var eventTitle = copysheet.getRange(rRow,roomNumCol).getValue();
var startDate = copysheet.getRange(rRow,checkInCol).getValue();
var endDate = copysheet.getRange(rRow,checkOutCol).getValue().getTime() 24 * 60 * 60 * 1000;
var conflicts = calendar.getEvents(new Date(startDate), new Date(endDate));
if (conflicts.length < 1) {
var editedEvent = calendar.createAllDayEvent(eventTitle, new Date(startDate), new Date(endDate));
var editedEventID = editedEvent.getId().split('@')[0];;
copysheet.getRange(rRow,appCol).setValue("edited");
copysheet.getRange(rRow,eventIDCol).setValue(editedEventID);
} else {
copysheet.getRange(rRow,appCol).setValue("conflict");
};
} else {
var eventEditId = copysheet.getRange(rRow,eventIDCol).getDisplayValue();
var editedEvent = calendar.getEventSeriesById(eventEditId);
editedEvent.deleteEventSeries();
var eventTitle = copysheet.getRange(rRow,roomNumCol).getValue();
var startDate = copysheet.getRange(rRow,checkInCol).getValue();
var endDate = copysheet.getRange(rRow,checkOutCol).getValue().getTime() 24 * 60 * 60 * 1000;
var conflicts = calendar.getEvents(new Date(startDate), new Date(endDate));
if (conflicts.length < 1) {
var editedEvent = calendar.createAllDayEvent(eventTitle, new Date(startDate), new Date(endDate));
var editedEventID = editedEvent.getId().split('@')[0];;
copysheet.getRange(rRow,appCol).setValue("edited");
copysheet.getRange(rRow,eventIDCol).setValue(editedEventID);
} else {
copysheet.getRange(rRow,appCol).setValue("conflict");
};
};
}
}