Clear cells across two or more sheets - google-apps-script

I have the following simple script which deletes a range of cells from one sheet. How can I amend this so that I can specify cells across more than one sheet? I assume it's something to do with changing getSheetByName? Many thanks.
function clearandover() {
//replace 'Sheet1' with your actual sheet name
var sheet = SpreadsheetApp.getActive().getSheetByName('Andover');
sheet.getRange('B8:G').clearContent();
}

If you are just going to do one command on each sheet, it doesn't help you to define the sheet in a separate value. You can just do it like this:
function clearandover() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getSheetByName('Andover').getRange('B8:G').clearContent();
spreadsheet.getSheetByName('Second sheet name').getRange('B8:G').clearContent();
spreadsheet.getSheetByName('Third sheet name').getRange('B8:G').clearContent();
}
Of course you can change the range per sheet that needs to be cleared.

Related

Is there a getter for an entire worksheet or range including formulas, values, merges, formatting etc. in Apps Script?

I'm trying to make a backup of an entire worksheet, including formulas, values, formatting, row and column size, cell merges, etc. so that when a user is finished editing I can reset the sheet. Currently I'm using a Range.getFormulas() to create a stringified object (that I can then paste into my code as a constant) to reset all of the content of the cells, but if the user changes the row size or deletes a cell, I'd like to be able to quickly rebuild the entire sheet without iterating through rows and columns (Apps Script is too slow for that). My previous method was to create a duplicate of the sheet and simply hide it, but someone can still unhide and edit that.
I've been digging through the documentation, but I haven't found anything useful. To sum up, I'd like to have something like this:
function resetHandler() {
var destinationWorksheet = SpreadsheetApp.getActiveSpreadsheet().getRange("A1:H132"),
backupWorksheet = [...object...];
backupWorksheet.copyTo(destinationWorksheet);
}
where "[...object...]" is the output of a getter that contains the entire sheet as an object. I tried JSON.stringify(SpreadsheetApp.getActive().getSpreadSheetByName("Workorder").getRange("A1:H132")) but it just outputs "{}" since the Range class is all private.
If there isn't a way, I can always fall back on a hidden backup sheet.
Description
I've created an example where a sheet has formulas, conditional format and data validation. Using testCopyTo I copy Sheet1 to a Backup spreadsheet. All attributes are copied. Using testCopyFrom first copy from the Backup spreadsheet then copy the range within the spreadsheet and finally delete the copy of the backup sheet.
Before restore
After restore
Script
function testCopyTo() {
try {
let source = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
let dest = SpreadsheetApp.openById("xxxx.......");
source.copyTo(dest);
}
catch(err) {
console.log(err);
}
}
function testCopyFrom() {
try {
let dest = SpreadsheetApp.getActiveSpreadsheet();
let source = SpreadsheetApp.openById("xxxx.......").getSheetByName("Copy of Sheet1");
source.copyTo(dest);
source = dest.getSheetByName("Copy of Copy of Sheet1");
dest = dest.getSheetByName("Sheet1");
source.getDataRange().copyTo(dest.getRange(dest.getLastRow()+1,1));
SpreadsheetApp.getActiveSpreadsheet().deleteSheet(source);
}
catch(err) {
console.log(err);
}
}
There is no Apps Script method to retrieve a spreadsheet by its name, you need to retrieve it by id or url
Keep in ind that in Google Drive, multiple spreadsheets with the same name can exist within a folder, this is why it would not make any sense to try and retrieve a spreadsheet by its name
Instead, you need to use the method openById(id) or openByUrl(url) (less recommended)
To get a sheet from an external spreadsheet and copy it to the current one, you can do the following:
function resetHandler() {
var destinationWorksheet = SpreadsheetApp.getActiveSpreadsheet();
backupWorksheet = SpreadsheetApp.openById("123456789").getSheetByName("The Name of the Sheet");
backupWorksheet.copyTo(destinationWorksheet);
}
where 123456789 is the id of the backup spreadsheet which you can find among others in the url in the address bar, which looks something like https://docs.google.com/spreadsheets/d/1234456789/edit#gid=1392862199
To copying a range from a sheet from an external spreadsheet into a sheet in the curent spreadsheet with copyTo is not possible, you can only use getValues() and setValues respectively, however this will not copy the formatting. Also for the formulas, you need to perform additoinally getFormulas() and setFormulas(formulas).
UPDATE
If you would like to copy a range from one sheet into another sheet of the same spreadsheet, you can modify your code as following:
function resetHandler() {
var activeSpreadsheet = SpreadsheetApp.getActive();
var destinationSheet = activeSpreadsheet.getSpreadSheetByName("Workorder");
var destinationRange = destinationSheet.getRange("A1:H132");
var backupWorksheet = activeSpreadsheet.getSpreadSheetByName("Backup").getRange("A1:H132");
var backupRange = backupWorksheet.getRange("A1:H132");
backupRange.copyTo(destinationRange);
}
The main problem with your code was that you mixed up the methods copyTo(destination) for ranges with copyTo(spreadsheet).
Both methods have the same name, but the first copies a range into another range (into the same sheet or another sheet of the same spreadsheet; overwriting the previous contents), while the other one inserts a whole (additoinal) sheet from a spreadsheet into the same or different spreadsheet
Have a careful look at the sample in the documentation for appplying the correct syntax in each case
Also: The method getSpreadSheetByName() does not exist, it is getSheetByName()
Careful with the wording: Google talks about sheets and spreadsheets, which are the equivalents of Excel worksheets and workbooks respectively.

Google sheet buttons don't work on mobile

I noticed recently that buttons created in the google worksheet don't work on mobile. I found the resolution, however now I wonder how could I point the code presented in the article to the specific tab in my worksheet, for instance, "sheet 1" and "sheet 2". As I'd like the code to work on both tabs "sheet 1" and "sheet 2", in parallel. So that two different users, can work on two different tabs at the same time.
Would anyone know how to overcome this issue?
https://medium.com/macadamscripts/create-button-in-google-sheets-mobile-2979579025ef#:~:text=Luckily%2C%20there%20is%20a%20workaround,serve%20as%20the%20%E2%80%9Cbutton%E2%80%9D
function onEdit(e) {
if (e.range.getA1Notation() == 'D4') {
if (/^\w+$/.test(e.value)) {
eval(e.value)();
e.range.clear();
}
}
}
Best,
D
Try to use activeSheet.getName in handling/checking a specific sheet on your spreadsheet. See sample code below on how to achieve it:
function onEdit(e) {
//Set a comment on the edited cell to indicate when it is changing.
var range = e.range;
var activeSheet = e.source.getActiveSheet();
if (activeSheet.getName() == "Sheet1") { //Sheet1 is just a sample name of the sheet. Modify it according to the name of your sheet.
range.setNote("Last Modified:" + new Date());
}
}
Reference:
use onedit() trigger on a specific sheet within google scripts for google sheets
Just for anyone else who may read this, Google defines:
Spreadsheet = the actual Sheet Document containing the sub sheets.
Sheet = the "tabs" as Ducatia uses.
Anyway, to answer the question, you could try using this which will set the tab to whatever is specified. You can select a sheet based on index of the array but sheet orders can be moved and unfortunately names can be changed too, but not accidentally like simple sheet reorder, so just need to be careful. You can get the sheet's ID but I can't see a way to select a sheet by ID. If I do I'll update this.
I used something like this:
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName("TEST"));
If you run the above, with a proper name, you can watch your spreadsheet change the UI view to the specified sheet.

Can i have a simple script on sheet1 and sheet2?

I have made a script that automatically sorts data when i make a change. It workds fine on the one sheet but i cannot find a way to apply it on sheet2 too.
So i need it to sort both sheet1 and 2 (the sheets are simular so the same sort range and everything needs to be the same - i just need it to apply on sheet2 also-
I have tried to make a copy of the code and change sheet_name to sheet2.
I Insert picture of the code. I would be very happy if you could help.
Explanation:
Take advantage of the event object. This will give you very important information regarding the edit/event which took place.
The idea is to use the script for multiple sheets. One way to do that is to construct an array of the sheet names you want to include:
const sheet_names = ["Management Associate","Finance Associate"];
and check if the name of the active sheet is included in this list:
if(sheet_names.includes(sheet.getName())){
// the rest of the code here
}
As a more complete implementation, I modified the last line of your code to include the name of the sheet that was edited. To do that, I used template literals but of course this approach is optional:
ss.toast(`Sort complete in ${sheet.getName()}`);
Solution:
function onEdit(e) {
const sheet_names = ["Management Associate","Finance Associate"]; // add sheets here
const sort_data_range = "A2:H999";
const sort_order = [{column:6, ascending:true}];
const ss = e.source;
const sheet = ss.getActiveSheet();
if(sheet_names.includes(sheet.getName())){
const range = sheet.getRange(sort_data_range);
range.sort(sort_order);
}
ss.toast(`Sort complete in ${sheet.getName()}`);
}

Google Sheets script to copy/paste from one sheet to another

Could someone help me with creating a script that does the following:
Function: Upon adding a new sheet to my already existing workbook, I would like it to copy Column "E" from Sheet 1 and (Paste Special > Conditional formatting only) to the newly introduced Sheet "X"
Where can I learn more on how to write code? I have never used Stackoverflow by the way someone just recommended me to come here. I believe I just answered my own question somehow on the post, which I am sure was wrong to do but I couldn't comment on an already existing answer without exceeding the limit.
// Adds custom menu
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('CustomMenu').addItem('Copy format', 'copyFormat') //Add function to menu.'GIVE NAME HERE', 'functionName'
.addToUi();
}
function copyFormat() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh1 = ss.getSheets()[0]; //Gets the first sheet of the workbook. Can use ss.getSheetByName('Name of sheet here'); If it is not the first sheet
var activeSh = ss.getActiveSheet(); //Get the active sheet, you should be on the sheet just added
var rowEnd = activeSh.getLastRow(); //Last row of active sheet
sh1.getRange("E1:E").copyFormatToRange(activeSh, 5, 5, 1, rowEnd); //Copy format, including conditional, to column E of active sheet
}
This just adds a button that allows you to select a cell and give it the same conditions has in the original sheet.
Example: Sheet 1: Column E1:E100 has a given condition.. which needs to apply in the exact same way to any new incoming sheets since they all come in the same format. Right now its at a point of which when a new sheet arrives in the workbook: I can enter the new sheet > Select the cell which requires the conditions > Select the custom menu > Cell gets conditioned. So the next step would be automate the process I just mentioned since there is several sheets added daily to the workbook.

copy cell values of named range in one sheet to same cell address of another named range in another sheet

Is it possible to copy the values of a named range in one sheet and paste them in the same cell location of another sheet?
For example, I have named range "old_desk_1" in sheet1!A24:A25 and named range "desk_1" in sheet2!A24:A25. Is it possible to copy the values in the cells of old_desk_1 to desk_1 without just doing the standard copy/paste?
Yes it is, first I suggest looking at the following documentations.
Google Class SpreadsheetApp
Google Class Spreadsheet
Google Class Sheet
Google Class Range
The above links will tell you about all the methods available for all the classes you will need to do this. Here is a basic example of what you're hoping to acheive.
function copyCells(){
var thisSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var theRange = thisSpreadsheet.getRangeByName("YOUR RANGE");
var destinationSheet = thisSpreadsheet.getSheetByName("SHEET TO COPY TO");
var destinationRange = destinationSheet.getRangeByName("YOUR OTHER RANGE");
theRange.copyTo(destinationRange);
}