First - I'm a teacher and self-teaching myself apps script, so please forgive my sloppy code. The results of my district's frequent standardized tests are often delivered with all the tests combined into one sheet. They would be much easier to manage if each test were in their own sheets.
I modified a function that I found on this site to create one new tab for each unique value in the test column (M). That takes care of having tabs to copy the rows into. It uses an array and I honestly don't understand it completely.
function createNewSheets() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = spreadsheet.getSheetByName('Sheet1');
var source_range = masterSheet.getRange("A1:AD1"); //header row
// Retrieve 2d array for column M
var colA = masterSheet.getRange('M2:M').getValues();
// Create a 1d array of unique values
var uniqueValues = {};
colA.forEach(function(row) {
row[0] ? uniqueValues[row[0]] = true : null;
});
var newSheetNames = Object.keys(uniqueValues);
newSheetNames.forEach(function(sheetName) {
// Check to see whether the sheet already exists
var sheet = spreadsheet.getSheetByName(sheetName);
if (!sheet) {
spreadsheet.insertSheet(sheetName); //inserts new sheet
source_range.copyTo(spreadsheet.getSheetByName(sheetName).getRange("A1:AD1")); //writes header row to newly created sheet
}
});
}
In order to get the correct rows into the corresponding tabs I ended up using else if statements. However, it means that I have to anticipate all the different tabs that will be created by the first function and then modify my code before running it. It's also quite slow, but tolerable. While this works there has to be a better way. If anyone has any suggestions I'd really appreciate it.
function copyRows() {
var sSheet = SpreadsheetApp.getActiveSpreadsheet();
var srcSheet = sSheet.getSheetByName("Sheet1");
var lastRow = srcSheet.getLastRow();
for (var i = 2; i <= lastRow; i++) {
var srcRange = srcSheet.getRange("A" + i + ":AD" + i);
var cell = srcSheet.getRange("M" + i);
var val = cell.getValue();
//sets the target sheet depending on the exam in column M
if (val == "Growth: Language 2-12 KS 2017") {
var tarSheet = sSheet.getSheetByName("Growth: Language 2-12 KS 2017");
}
else if (val == "Growth: Math 2-5 KS 2017") {
var tarSheet = sSheet.getSheetByName("Growth: Math 2-5 KS 2017");
}
else if (val == "Growth: Reading 2-5 KS 2017") {
var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
}
else if (val == "Growth: Reading K-2 KS 2017") {
var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
}
else if (val == "Growth: Math K-2 KS 2017") {
var tarSheet = sSheet.getSheetByName("Growth: Reading 2-5 KS 2017");
}
else {
}
//insets the row in the correct target worksheet
var tarRow = tarSheet.getLastRow()+1;
tarSheet.insertRows(tarRow);
var tarRange = tarSheet.getRange("A" + (tarRow) + ":AD" + (tarRow));
srcRange.copyTo(tarRange);
}
};
Here is a link to a sheet with dummy data. My actual sheets can have upwards of 1500 to 2000 rows with 8 or more tests.
row[0] ? uniqueValues[row[0]] = true : null;It looks like a ternary but I don't know what the second argument is doing. - Coopershared with me- Cooper