Google表单编辑响应提交,自动修改表单数据,以及日历事件
Google form edit response submission, automatically modify data in sheets, as well as calendar event
所以我设法结合了 Google 表格、google 日历以及 google sheets。当人们提交表单(带有开始日期和结束日期)时,它会自动出现在 google sheet 以及 google 日历中。
我修改了脚本以查找冲突(以防止重复预订),但是,我才意识到 即使同一个人正在尝试编辑开始和结束日期(通过编辑响应),它仍然会显示 CONFLICT.
比如某人预定了4月15号到4月17号,他决定改到4月16号到4月18号,因为他之前预定的是15-17号,新的提交和他自己之前的提交。
如何添加一个功能来检测同一封电子邮件以编辑和提交数据? (在空闲的一天内。提前致谢!
这是从sheet数据
创建对象的函数
//Calendars to Output appointments
var cal = CalendarApp.getCalendarById('ID');
// Create an object from user submission
function Submission(){
var row = lastRow;
this.timestamp = sheet.getRange(row, 1).getValue();
this.email = sheet.getRange(row, 2).getValue();
this.name = sheet.getRange(row, 3).getValue();
this.date = sheet.getRange(row, 4).getValue();
this.dateout = sheet.getRange(row, 5).getValue();
this.room = sheet.getRange(row, 6).getValue();
this.day = sheet.getRange(row,8).setFormula("=(R[0]C[-3]-R[0]C[-4])+1").getValue();
var fillDownRange = sheet.getRange(2, 8, lastRow-1);
sheet.getRange(row,8).copyTo(fillDownRange);
// Info not from spreadsheet
this.status;
this.dateString = (this.date.getMonth() + 1) + '/' + this.date.getDate() + '/' + this.date.getYear();
this.dateOutString = (this.dateout.getMonth() + 1) + '/' + this.dateout.getDate() + '/' + this.dateout.getYear();
this.calendar = eval('cal' + String(this.room));
return this;
}
这是检测冲突的函数
function getEndTime(request){
request.endTime = new Date(request.dateout.getTime() + 24 * 60 * 60 * 1000);
}
// Check for appointment conflicts
function getConflicts(request){
var conflicts = request.calendar.getEvents(request.date, request.endTime);
if (conflicts.length < 1) {
request.status = "Approve";
} else {
request.status = "Conflict";
}
}
这是编辑日历的功能
//update calendar (add)
function updateCalendar(request){
var event = request.calendar.createEvent(
"Booked",
request.date,
request.endTime
)
}
您不应总是检索最后一行,而应检索最新提交的实际行
请注意,如果人们更新他们的 Google 表单回复,则传播中的提交行sheet 不会改变 - 只有内容。
- 您可以使用 event object
event.range
检索最新提交/修改的表单响应行(前提是您的函数绑定到 Google Sheets form submit
触发器)
- 您可以将修改后的行与 sheet
中的最后一行进行比较
- 如果表单回复行等于最后一行 - 已提交新回复
样本:
function bindMeOnFormSubmitTrigger(event){
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var lastRow = sheet.getLastRow();
var row = event.range.getRow();
if (row == lastRow){
// insert a new event as done before
...
}
else {
// the submitted response was an edit of a previously submitted one
// identify the already existing event (e.g. if you specified the respondent email address in the event description) and modify the event data to the newly submitted values
var newFormResponseValues = event.values;
this.timestamp = newFormResponseValues[0];
...
}
}
- 如果表单响应行与 sheet 中的最后一行不同(较小)- 这意味着现有的表单响应已被编辑(因此事件数据可能需要在日历)。
- 如果您想访问受访者的电子邮件,您必须事先在 Google 表单 UI 设置中激活此选项:
我使用 e.range 找到了更好的解决方案。使用此方法的更好方法是 在同一个 spreadsheet 中创建两个单独的 sheet。主 sheet 将首先从表单中检索响应,然后自动创建一个副本到第二个 sheet。而如果有被编辑的提交,它会通过第二个sheet找到被编辑的行,然后修改该行(以及日历事件)。感谢 Tedinoz
欢迎补充comment/copy,干杯
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");
};
};
var revRange = copysheet.getRange(rRow,revCol);
var revOldValue = revRange.getValue();
if (revOldValue == null || revOldValue == ""){
revOldValue = 0;
}
var revNewValue = revOldValue+1;
revRange.setValue(revNewValue);
}
}
所以我设法结合了 Google 表格、google 日历以及 google sheets。当人们提交表单(带有开始日期和结束日期)时,它会自动出现在 google sheet 以及 google 日历中。
我修改了脚本以查找冲突(以防止重复预订),但是,我才意识到 即使同一个人正在尝试编辑开始和结束日期(通过编辑响应),它仍然会显示 CONFLICT.
比如某人预定了4月15号到4月17号,他决定改到4月16号到4月18号,因为他之前预定的是15-17号,新的提交和他自己之前的提交。
如何添加一个功能来检测同一封电子邮件以编辑和提交数据? (在空闲的一天内。提前致谢!
这是从sheet数据
创建对象的函数//Calendars to Output appointments
var cal = CalendarApp.getCalendarById('ID');
// Create an object from user submission
function Submission(){
var row = lastRow;
this.timestamp = sheet.getRange(row, 1).getValue();
this.email = sheet.getRange(row, 2).getValue();
this.name = sheet.getRange(row, 3).getValue();
this.date = sheet.getRange(row, 4).getValue();
this.dateout = sheet.getRange(row, 5).getValue();
this.room = sheet.getRange(row, 6).getValue();
this.day = sheet.getRange(row,8).setFormula("=(R[0]C[-3]-R[0]C[-4])+1").getValue();
var fillDownRange = sheet.getRange(2, 8, lastRow-1);
sheet.getRange(row,8).copyTo(fillDownRange);
// Info not from spreadsheet
this.status;
this.dateString = (this.date.getMonth() + 1) + '/' + this.date.getDate() + '/' + this.date.getYear();
this.dateOutString = (this.dateout.getMonth() + 1) + '/' + this.dateout.getDate() + '/' + this.dateout.getYear();
this.calendar = eval('cal' + String(this.room));
return this;
}
这是检测冲突的函数
function getEndTime(request){
request.endTime = new Date(request.dateout.getTime() + 24 * 60 * 60 * 1000);
}
// Check for appointment conflicts
function getConflicts(request){
var conflicts = request.calendar.getEvents(request.date, request.endTime);
if (conflicts.length < 1) {
request.status = "Approve";
} else {
request.status = "Conflict";
}
}
这是编辑日历的功能
//update calendar (add)
function updateCalendar(request){
var event = request.calendar.createEvent(
"Booked",
request.date,
request.endTime
)
}
您不应总是检索最后一行,而应检索最新提交的实际行
请注意,如果人们更新他们的 Google 表单回复,则传播中的提交行sheet 不会改变 - 只有内容。
- 您可以使用 event object
event.range
检索最新提交/修改的表单响应行(前提是您的函数绑定到 Google Sheetsform submit
触发器) - 您可以将修改后的行与 sheet 中的最后一行进行比较
- 如果表单回复行等于最后一行 - 已提交新回复
样本:
function bindMeOnFormSubmitTrigger(event){
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var lastRow = sheet.getLastRow();
var row = event.range.getRow();
if (row == lastRow){
// insert a new event as done before
...
}
else {
// the submitted response was an edit of a previously submitted one
// identify the already existing event (e.g. if you specified the respondent email address in the event description) and modify the event data to the newly submitted values
var newFormResponseValues = event.values;
this.timestamp = newFormResponseValues[0];
...
}
}
- 如果表单响应行与 sheet 中的最后一行不同(较小)- 这意味着现有的表单响应已被编辑(因此事件数据可能需要在日历)。
- 如果您想访问受访者的电子邮件,您必须事先在 Google 表单 UI 设置中激活此选项:
我使用 e.range 找到了更好的解决方案。使用此方法的更好方法是 在同一个 spreadsheet 中创建两个单独的 sheet。主 sheet 将首先从表单中检索响应,然后自动创建一个副本到第二个 sheet。而如果有被编辑的提交,它会通过第二个sheet找到被编辑的行,然后修改该行(以及日历事件)。感谢 Tedinoz
欢迎补充comment/copy,干杯
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");
};
};
var revRange = copysheet.getRange(rRow,revCol);
var revOldValue = revRange.getValue();
if (revOldValue == null || revOldValue == ""){
revOldValue = 0;
}
var revNewValue = revOldValue+1;
revRange.setValue(revNewValue);
}
}