Since you are going to be using a script anyway (for email generation), might as well use one for the rearrangement.
Here's a simplified example of form input data:
+---+------------+-------+---------------+-------+-------+-------+
| | A | B | C | D | E | F |
+---+------------+-------+---------------+-------+-------+-------+
| 1 | Date | Job | Details | cat 1 | cat 2 | cat 3 |
| 2 | 10/2/2015 | Job 1 | some details | 2 | 3 | 1 |
| 3 | 10/10/2015 | Job 2 | other details | 0 | 2 | 3 |
+---+------------+-------+---------------+-------+-------+-------+
This will be rearranged on another sheet, called "Job List" below, by this script (which can be triggered by form submission):
function processJobs() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var values = sheet.getDataRange().getValues();
var output = [];
for (var i = 1; i < values.length; i++) {
for (var j = 0; j < 3; j++) {
output = output.concat(repeat(values[i], values[0][j+3], values[i][j+3]));
}
}
outputSheet = ss.getSheetByName("Job List");
outputSheet.getRange(2, 1, output.length, output[0].length).setValues(output);
}
function repeat(row, category, quantity) {
var arr = [];
for (var i = 0; i < quantity; i++) {
arr.push([row[0], category, quantity].concat(row.slice(1,3)));
}
return arr;
}
Explanation: the line with values[i][j+3]
refers to various category counts within the row; j+3
is set so that j=0,1,2
correspond to 3,4,5 zero-based column indices (which mean the columns D,E,F above). For each count, the function repeat
is called, which produces the necessary number of repetitions.
The function repeat
inserts the date, category name, quantity of workers for that category (not sure why, but you wanted it), and the rest of the job description.
The whole thing is then recorded in sheet "Job List", like so:
+----+------------+----------+----------+-------+---------------+
| | A | B | C | D | E |
+----+------------+----------+----------+-------+---------------+
| 1 | Date | Category | Quantity | Job | Details |
| 2 | 10/2/2015 | cat 1 | 2 | Job 1 | some details |
| 3 | 10/2/2015 | cat 1 | 2 | Job 1 | some details |
| 4 | 10/2/2015 | cat 2 | 3 | Job 1 | some details |
| 5 | 10/2/2015 | cat 2 | 3 | Job 1 | some details |
| 6 | 10/2/2015 | cat 2 | 3 | Job 1 | some details |
| 7 | 10/2/2015 | cat 3 | 1 | Job 1 | some details |
| 8 | 10/10/2015 | cat 2 | 2 | Job 2 | other details |
| 9 | 10/10/2015 | cat 2 | 2 | Job 2 | other details |
| 10 | 10/10/2015 | cat 3 | 3 | Job 2 | other details |
| 11 | 10/10/2015 | cat 3 | 3 | Job 2 | other details |
| 12 | 10/10/2015 | cat 3 | 3 | Job 2 | other details |
+----+------------+----------+----------+-------+---------------+
Column F can be used for student names.
You need onFormSubmit, not onEdit. Open the documentation of classes Spreadsheet, Sheet, and Range, and look up each of the methods used below. To give you a general idea of what is done here:
- ss = active spreadsheet, sheet = active sheet
- values = an array of values in the active sheet. Note that arrays in JavaScript are 0-indexed.
- row = the row added to sheet when the onFormSubmit event happened. This one is 1-based, so the adjustment row-1 is used when addressing arrays.
- values[row-1][1] - the value in column B of this row. [Row number][Column Number] in 0-based indexing.
The script isn't perfect. For one thing, it assumes the target has rows available. You may want to use insertRowAfter() to be safe. Or just create a lot of rows. The logic for other things you mentioned is not here either, but it's essentially the same.
function onFormSubmit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
var row = event.range.getRow();
if (values[row-1][1] == 'Luke') { // column B in 0-based indexing
var targetSheet = ss.getSheetByName('for Luke');
var lastRow = targetSheet.getLastRow();
var targetRange = targetSheet.getRange(lastRow+1, 1, 1, values[0].length);
targetRange.setValues([values[row-1]]);
}
}
Best Answer
I found that this works. Change the form submit button of the html file to:
<input onclick="formSubmit();go();" type="button" name="mysubmit" id="mysubmit" value="Add Row"/>
In the html file, add this:
In code.gs, add this:
These changes have the desired result of updating a div with the newest last row each time a new row is inserted. This makes a nice way of showing users that their form submission is successful, and the form remains open to receive more data.
I worked this out with the answer found here: how to use google.script.run as if it was a function. I will update my example Sheet, in case this will be helpful to someone else.
UPDATE: If you are editing existing rows, then you need to move the call of the go() function to inside the formsubmit function. so that the newly updated row is shown in the confirmation div, and not just the last row.: