简体   繁体   中英

Google sheets - How to get row index of a column, based on the index of edit URL from the same row?

I am coding a room booking system using combination of Google forms and Google calendar.

When there is a new booking order:

  • An event will be automatically created on the selected calendar.
  • An edit response URL will also be generated automatically and put in column 10 of the spreadsheet in the same row where the form answer was inserted.
// This is the function to generate the edit URL (which works perfectly).

function getEditUrl(request) {
    var formRes = FormApp.openById('XXXXXXXXXXXXXXXXXXXXXXXXXXXX');
    var sheetRes = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('YYYYYYYYYY');
    var data = sheetRes.getDataRange().getValues();
    var urlCol = 10;
    var responses = formRes.getResponses();
    var timestamps = [],
        urls = [],
        resultUrls = [];
    for (var i = 0; i < responses.length; i++) {
        timestamps.push(responses[i].getTimestamp().setMilliseconds(0));
        urls.push(responses[i].getEditResponseUrl());
    }
    for (var j = 1; j < data.length; j++) {
        resultUrls.push([data[j][0] ? urls[timestamps.indexOf(data[j][0].setMilliseconds(0))] : '']);
    }
    sheetRes.getRange(2, urlCol, resultUrls.length).setValues(resultUrls);
};

However, problem occurs when there are more than 2 orders; as the next order will delete the calendar event from the previous order.

// This is the function to update the calendar event. 

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('XXXXXXXXXXXXXXXXXXXXXXXX@group.calendar.google.com');
    for (var i = 0; i < responses.length; i++) {
        getConflicts(request);
        if (request.eventConflict == "conflict") {
            sheet.getRange(lastRow, 11).setValue("conflict");
            break;
        } else if (request.eventConflict == "approve") {
            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);
            break;
        }
    }
    for (var j = 1; j < values.length; j++) {
        if (values[j][10] == "approve") {
            var eventEditId = calendar.getEventSeriesById(values[j][11]);
            eventEditId.deleteEventSeries();
            sheet.getRange(j + 2, 11).setValue("");
            getConflicts(request);
            if (request.eventConflict == "approve" && values[j][10].length > 1) {
                var newEvent = calendar.createEvent("booked", request.date, request.endTime);
                var newEventId = newEvent.getId().split('@')[0];
                sheet.getRange(j + 2, 11).setValue("approve");
                sheet.getRange(j + 2, 12).setValue(newEventId);
                break;
            } else {
                sheet.getRange(j + 2, 11).setValue("conflict");
                break;
            }
        }
    }
};

My questions:

  1. How to make sure that when respondent edits his/her own response, it will always update event from the same column as the edit URL? --> I have separate function that will send edit URL to respondents
  2. When there is more than two submission, the 3rd submission will delete event of the 2nd one. (I am sure the issue is on the updateCalendar() function).

I have been struggling so much for the past few days trying to figure out the best way to come up with best loop method. Any help / response is greatly appreciated.

EDIT:

This is the column description of the sheets (separated with |):

Timestamp Email Address name Check-in date Check-out date Room No. of people total day total edit URL Event Conflict Event ID

This is the function to get event conflicts in the calendar:

function getConflicts(request){
  var conflicts = request.calendar.getEvents(request.date, request.endTime);
  if (conflicts.length > 0) {
    request.eventConflict = "conflict";
  } else {
    request.eventConflict = "approve"
  }
  };

And this is the main function that will be triggered on formsubmit:

function main(){
  var request = new Submission(lastRow);
  getEndTime(request);
  draftEmail(request);
  updateCalendar(request);
};

This is the screenshot of the sheet工作表的屏幕截图

Finally I found one way to retrieve the edited row by using e.range method. So basically I created another sheet inside the same spreadsheet. When there is a new submission, it will automatically copy the new submission to the second sheet. And when there is an edited submission, it will go through the copy sheet to find the edited row, and then edit it (as well as the calendar). Credit to Tedinoz

function updateCalendarTwo(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var responsename = "AAAAAAAAAAAAAAA"
  var copyname = "BBBBBBBBBBBB";
  var responsesheet = ss.getSheetByName(responsename);
  var copysheet = ss.getSheetByName(copyname);
  var calendar = CalendarApp.getCalendarById('CCCCCCCCCCCCCCCCCCCC');
  // 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); 
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM