Reputation: 65
I have 9 tabs within my spreadsheet, and would like to apply a sorting script to only 6 of those tabs. I can't figure out how to make that happen.
///////Auto Sort Phase Sheets
//get sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ['Phase 1','Phase 2', 'Phase 3', 'Phase 4', 'Phase 5', 'Phase 6'];
//get active cell
var editedCell = sheet.getActiveCell();
//get range
var range = sheet.getRange("A2:Z");
//sort by: status, priority, estimated time
range.sort([{column: 2, ascending: true}, {column: 1, ascending: true}, {column:3}]);
I get this error:
TypeError: Cannot find function getActiveCell in object Phase 1,Phase 2,Phase 3,Phase 4,Phase 5,Phase 6
When I remove 'getActiveCell' I get this error: TypeError: Cannot find function getRange in object Phase 1,Phase 2,Phase 3,Phase 4,Phase 5,Phase 6.
When I remove 'getRange' the script just does nothing.
Upvotes: 1
Views: 1867
Reputation: 476
To expand on GEOWill's answer, you are working with an array. GAS (and JavaScript) will not automatically loop through arrays, 2D included, without you telling it to. GAS (Javascript) methods are designed to operate either on arrays as a whole or on a single object in the array; not both. Your errors are coming from the attempted use of an object method on an array.
If you were to use the method .getSheets()
, you would have an array of all your sheet names. This is an array of objects to which you can perform methods on each element as you loop. I have included several alternate methods to looping through each sheet requiring operation.
The first is if the sheets requiring the executed code are the first 6:
function phaseFunction () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < 6; i++) {
var sheet = ss.getSheetByName(sheets[i]);
//further variable definition as usual
//we are now working with a singular sheet object (sheets[i])
//code to perform
}
}
This is similar to GEOWill's strategy but will always do the first 6. This may be useful if you want to change which sheets are used and know that it will always be specifically the first 6.
The below construction operates how GEOWill's did by choosing the sheets based on the name. This is useful if the same sheets are used and the names will not change.
function phaseFunction () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ['Phase 1','Phase 2', 'Phase 3', 'Phase 4', 'Phase 5', 'Phase 6'];
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
//further variable definition as usual
//code to perform
}
}
The next construction loops through all sheets, regardless of order and performs the code if the name matches.
function phaseFunction () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
if (sheet == "Name 1" || sheet == "Name 2" || ...) {
//further variable definition as usual
//the variables defined will only be defined on the desired sheets
//code to perform
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
If you will always have 9 sheets (or less sheets that don't meet the condition than do) you can change the if()
statement to check for the ones to skip. This would shorten the conditional statement and would allow for adding more sheets that you want to process, keeping the ones to always leave alone, left alone.
This last two constructions would involve a standard naming convention. Your question implied that there is a standardization to how you name your sheets and if the sheets to leave alone do not match this criteria, you could use what I've written below. It checks the name to see if it is similar to the convention you've set and if so, performs the code. For example, if it begins with "Phase", perform the code, if not ("Data", "Log", "Formulas", etc.), do not perform the code.
This first one uses a basic string method .includes()
:
function phaseFunction () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
var name = sheet.getName();
if (name.includes("Phase")) { //this returns a boolean
//further variable definition as usual
//the variables defined will only be defined on the desired sheets
//code to perform
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
The following uses Regular Expressions.
function phaseFunction () {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
for (i = 0; i < sheets.length; i++) {
var sheet = ss.getSheetByName(sheets[i]);
var sheetName = sheet.getName();
var nameMatch = sheetName.match(/\b\Phase\b/g);
if (nameMatch[0] != null) {
//further variable definition as usual
//the variables defined will only be defined on the desired sheets
//code to perform
} else {
continue;
//skip over all those that don't meet the condition
}
}
}
This specific RegEx looks for the phrase "Phase"; case-sensitive. It then checks the array returned by .match()
and if it wasn't null, performs the codes. There are hundreds of ways to go about this matching and checking process. References and guides to RegEx (vastly useful) can be found here and here. A tester can be found here.
Upvotes: 3
Reputation: 96
I think that the primary problem was that you need to loop through the specified list of sheet names given in your 'sheet' array. In addition to that, the code you shared should be embedded in a function in order to be run (by the way, I removed the editedCell variable because it is redundant):
///////Auto Sort Phase Sheets
function sortSheets(){
//get sheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//Specify sheets to be sorted
var sheet_name = ['Phase 1','Phase 2', 'Phase 3', 'Phase 4', 'Phase 5', 'Phase 6'];
for (s=0; s<sheet_name.length; s++) {
var sheet = ss.getSheetByName(sheet_name[s]);
//get range
var range = sheet.getRange("A2:Z");
//sort by: status, priority, estimated time
range.sort([{column: 2, ascending: true}, {column: 1, ascending: true}, {column:3}]);
}
}
Here is the sheet I tested it on: https://docs.google.com/spreadsheets/d/1VyhzrYwOWgGWszrRoUrQU2ECGqwN_lfb99fqw7x9P1k/edit#gid=0
Upvotes: 5