Reputation: 91
I used the expense report tutorial to generate most of my code.
The main thing I changed is that instead of the expense report ID being the row number, I made it into a random number (ll-nnnn). I would like to use the report ID as the identifier between the expense report sheet and the expense approvals sheet, so I added a report ID column to the report sheet. I want the script to take the report ID from the approvals form, and search the report sheet ID column for the row with that ID in it, then enter in whether it was approved or denied and whatever comments the manager had in the corresponding row in column M and N. In VBA the the code I would use would be and If statement with a match condition. I am new to java script so I am not sure how to do this. ***I have edited my code using what fooby provided. When I run it, I get the error "The coordinates or dimensions of the range are invalid." on the line: " poSheet.getRange(rowToUpdate, 2, 1, 13).setValues(updateInfo);" Any suggestions would be greatly appreciated!
var PO_SPREADSHEET_ID= "0At0Io3p64FeddFVCV2lJdEpLY09MYWNkVS05NDhzWkE";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var poSs = SpreadsheetApp.openById(PO_SPREADSHEET_ID);
var poSheet = poSs.getSheets()[0];
function updatePOSheet() {
// Get IDs from Approval Sheet
var row = sheet.getRange(2, 1, sheet.getLastRow()-1,sheet.getLastColumn()).getValues();
// Get IDs from Report Sheet, flatten it into a 1D array
var poId = poSheet.getRange(2,1,poSheet.getLastRow()-1,1).getValues().reduce(flatten_);
// For each row in the Approval Sheet update the coresponding report row
// reportIds is passed a "this" in the forEach function, see below
row.forEach(updateReportRow_,poId);
}
// Checks to see if the status of a row is either "Approved" or "Denied
// then updated the correct row in the reports sheet with manager's comments
function updateReportRow_(row) {
var id = row[2];
var status = row[3];
var comments = row[4];
// Get row in reports sheet from reportIds (it was passed as 'this')
var rowToUpdate = this.indexOf(id) + 1;
// Put info into spreadsheet friendly array
var updateInfo = [[status,comments]];
if (status == "Approved" || status == "Denied") {
poSheet.getRange(rowToUpdate, 2, 1, 13).setValues(updateInfo);
}
}
// Returns a piece of an array concatenated with the element on to it's right
// will make [[0],[1],[2]...]] into [0,1,2,...]
function flatten_(a,b) {
return a.concat(b);
}
Upvotes: 0
Views: 668
Reputation: 849
I used this kind of technique all the time, and I tried to just explain it here, but it wasn't going very well. So, I put together, as best I could, a demo sheet of how you can accomplish what you desire. Before I get to that, here is the general gist of the approach and the uncommented code.
onFormSubmit()
trigger.reduce()
and a helper function called flatten_(a,b)
A few notes about the demo sheets:
Here is the uncommented code:
function updateReportRow(approvalInfo) {
var id = approvalInfo.namedValues.ID;
var status = approvalInfo.namedValues.Status;
var comments = approvalInfo.namedValues.Comments;
var reportSheet = SpreadsheetApp.openById("SheetID").getSheetByName("Report Sheet");
var reportIds = reportSheet.getRange(1,1,reportSheet.getLastRow(),1).getValues().reduce(flatten_);
var rowToUpdate = reportIds.indexOf(id.toString())+1;
if (rowToUpdate < 2) {
// Something went wrong...email someone!
} else {
if (status == "Approved") {
var updateInfo = [[status,comments,"STATE_APPROVED"]];
reportSheet.getRange(rowToUpdate, 5, 1, updateInfo[0].length).setValues(updateInfo);
} else if (status == "Denied") {
var updateInfo = [[status,comments,"STATE_DENIED"]];
reportSheet.getRange(rowToUpdate, 5, 1, updateInfo[0].length).setValues(updateInfo);
}
}
}
function flatten_(a,b) {
return a.concat(b);
}
Upvotes: 1