2

We are trying to create an online form using Google Forms to take requests for appointments. This is what the process should look like:

  1. User fills form and submits their information (this works)
  2. An email gets sent to our Gmail to notify us of a new incoming request (this works)
  3. We go into the Google spreadsheet. There are 3 sheets. One sheet called Requests. Another called Accepted. And another called Rejected (these were created)
  4. Last column in the Requests sheet has a dropdown menu with values of Accepted or Rejected. Depending on what we select, it will move the entire row into the appropriate sheet -- either Accepted or Rejected. (This works up until step 5 below)
  5. If the row gets moved into Accepted, it should create a new calendar event. This is the part that doesn't work. The row gets moved properly into the Accepted sheet but doesn't create the new Google calendar event.

The weird thing is if we run the function manually, it works. It takes the last row and creates an event. If we try to run the function directly via our code by calling the function directly, it doesn't create an event. This is our code for the moverow.gs

(please note that all confidential, identifying information has been removed such as the calendar id's):

function onEdit(e) {
  try { moveRow(e) } catch (error) { Browser.msgBox(error) }
}

function moveRow(e) {

  var rowStart = e.range.rowStart;
  var colStart = e.range.columnStart;

  var calendarStaff1Id = "<link to calendar>";
  var calendarStaff2Id = "<link to calendar>"
  var calendarStaff3Id = "<link to calendar>"
  var calendarStaff4Id = "<link to calendar>"

  if ( rowStart == e.range.rowEnd && colStart == e.range.columnEnd ) {
    var active = e.source.getActiveSheet();
    var name = active.getName();

    if ( name == "Requests" && colStart == 10 ) { 
  var value = e.value;

  if ( value == "ACCEPTED (S1)" ) {
    var rowValues = active.getRange( rowStart + ':' + rowStart ).getValues();
    e.source.getSheetByName("Accepted").appendRow(rowValues[0])
    active.deleteRow(rowStart);
    var calendarId = calendarStaff1Id;
    addEvent();

  }

  if ( value == "ACCEPTED (S2)" ) {
    var rowValues = active.getRange( rowStart + ':' + rowStart ).getValues();
    e.source.getSheetByName("Accepted").appendRow(rowValues[0])
    active.deleteRow(rowStart);
    var id = calendarStaff2Id;
    addEvent();

  }

  if ( value == "ACCEPTED (S3)" ) {
    var rowValues = active.getRange( rowStart + ':' + rowStart ).getValues();
    e.source.getSheetByName("Accepted").appendRow(rowValues[0])
    active.deleteRow(rowStart);
    var calendarId = calendarStaff3Id;
    addEvent();

  }

  if ( value == "ACCEPTED (S4)" ) {
    var rowValues = active.getRange( rowStart + ':' + rowStart ).getValues();
    e.source.getSheetByName("Accepted").appendRow(rowValues[0])
    active.deleteRow(rowStart);
    var calendarId = calendarStaff4Id;
    addEvent(calendarId);

  }

  if ( value == "REJECTED" ) {  // Change to the value that will trigger the move
    var rowValues = active.getRange( rowStart + ':' + rowStart ).getValues();  // Entire row
    e.source.getSheetByName("Rejected").appendRow(rowValues[0])  // Change to your "move to" sheet name
    active.deleteRow(rowStart);
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Rejected").activate();

    Browser.msgBox("Please contact client to let them know that their request cannot be fulfilled");

      }
    }
  }
}

function addEvent(calendarId) {

    var startDtId = 7;
    var titleId = 2;
    var titleId2 = 6;
    var descId = 8;
    var formTimeStampId = 1;

    SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Accepted").activate();

    // Switch to sheet Accepted and start the calendar event creation
    var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Accepted");
    var rows = sheet.getDataRange();
    var numRows = rows.getNumRows();
    var values = rows.getValues();
    var lr = rows.getLastRow();
    var startDt = sheet.getRange(lr,startDtId,1,1).getValue();
    var subOn = "Added :"+sheet.getRange(lr,formTimeStampId,1,1).getValue()+" by: "+sheet.getRange(lr,titleId,1,1).getValue();
    var desc = "Comments :"+sheet.getRange(lr,8,1,1);
    var title = sheet.getRange(lr,titleId,1,1).getValue()+" - "+sheet.getRange(lr,titleId2,1,1).getValue();
    var start = new Date(startDt);
    var end = new Date(startDt.valueOf()+60*60*1000);
    var loc = 'Central Library';

    var cal = CalendarApp.getCalendarById(calendarId);

    //Browser.msgBox("Please add the following event into your calendar: " + title + " Start Time: " + start + " End Time: " + end);

    var event = cal.createEvent(title, start, end);

};

Please help!! We are at our wits end. Thanks in advance.

  • I'm not at my PC to write a full response, but at a glance it could be the OnEdit trigger, which ONLY works when the sheet is edited manually, and NOT by a script. Are you expecting it to run when the sheet is edited manually or by a script? – HDCerberus Nov 27 '14 at 20:04
  • Thanks for the reply. As mentioned, the row gets moved properly from the Requests sheet over to the Accepted sheet once I choose a value from a dropdown menu. The weird thing is if I comment out the calendar code block and re-enable the Browser.msgbox line, I get a pop-up box with the values properly being passed. For whatever reason, no matter what code I use to create a calendar event, it doesn't create the event. I even copied and pasted Google's calendar template code when starting a new Apps Script file. Nothing works. If we run the function manually in the editor, it works. weird –  Nov 27 '14 at 20:24
  • We want the code to ultimately work by using the above script. We want it to be as automated as possible. We don't want to have to go into the Script Editor and run the function manually. Running the function manually would also create duplicates. In theory, if the code runs only when we select from a dropdown, it should only pick up the very last line and create an event with no duplicates. –  Nov 27 '14 at 20:29
  • Cool, that's good to know. If no-ones answered this by the time i get home I'll take a closer look. Btw, there's a discrepancy in your 'if' statements, only the "ACCEPTED (S4)" if statement is actually passing a calendarId as ' addEvent(calendarId);', the rest seem to pass no calendarId value like 'addEvent();'. Might be part of the issue at a glance. – HDCerberus Nov 27 '14 at 20:35
  • yeah, just noticed that. My manager was playing with the code as well as me. Initially all of the If statements were identical (with the calendarid in the addEvent), but still no calendar events were being created. Thanks for noticing that however. I'm going to fix the code now. I almost get the gut feeling it is a permissions issue with the calendars themselves, but the calendars are set to "Make changes AND manage sharing" for the Google account that is being used. Thanks for taking the time. any help is greatly appreciated. –  Nov 27 '14 at 20:45

1 Answers1

3

A simple onEdit() trigger cannot do anything that requires authorization. It doesn't matter who owns the document the script is in; if it's a simple trigger, then it's anonymous.

Instead, use an installable trigger. (You can simply rename your function, then go through the instructions in Managing Triggers Manually to set it up.)

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
  • Mogsdad, thanks for the reply. I just Googled "programmed trigger" and nothing really came up in the search. How do we do what you suggest? Sorry, we're new to programming Apps Script. Thanks –  Nov 28 '14 at 02:27
  • Mogsdad. Question. Which function should I rename? I'd rather try to do the trigger programmatically, but nothing I do seems to work. I am getting very frustrated as we have been at this for almost two weeks. I tried this and it didn't work `function createSpreadsheetEditTrigger() { var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Accepted"); ScriptApp.newTrigger('addEvent').forSpreadsheet(ss).onEdit().create(); }` –  Nov 28 '14 at 03:53