Changing the active range to a newly generated sheet causing error - google-apps-script

Receiving the error,
ReferenceError: "setActiveSelection" is not defined.
Using Google Apps Script on Google Sheets. With this function, I'm wanting to create a new sheet tab on the same workbook using a template from another workbook. Once the new sheet is created, I'd like to change the actively selected cell to cell 'B1'. The template is copying fine, but the error is coming from the line changing the active selection. I've also tried setActiveRange and even just setActiveSheet but they return the same error.
function newReception() {
var templateSpreadsheet = SpreadsheetApp.openById("ID Redacted");
var template = templateSpreadsheet.getSheets()[1];
var currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var newSheet = template.copyTo(currentSpreadsheet).setName("Untitled
Reception");
setActiveSelection(currentSpreadsheet.getSheetbyName("Untitled
Reception").getRange('B1'));
}
Please advise on a solution. Thanks!

You're getting this issue because you're running .setActiveSelection() on its own. This method is bound to sheets, so you must run it for such. See Class Sheet documentation for more details on this method.
Try defining your sheet as a variable and then running it for your new sheet variable.
var sheet = currentSpreadsheet.getSheetbyName("Untitled Reception");
sheet.setActiveSelection('B1');

Related

How to import data from a different workbook, with a button. getSheetById(id) doesn't work

I want to import data from 3 sheets in a different workbook, in the same drive, to a newer workbook, with the press of a button.
Each workbooks has a sheet called 'Log Wizard' with 2 boxes. The bottom box displays the current spreadsheet key. The top box is an input field to paste an existing sheet key into.
https://docs.google.com/spreadsheets/d/1833-5CnOurssETuZFtohiHRRBx1V3_95_L0S-f9vPLk/edit#gid=187106606
enter image description here
enter image description here
So far, I cannot figure out how to make a script that does the following:
When the button is pressed, get the source sheet id which is provided by the user in cell M11 of the current sheet, and use that to access the referenced spreadsheet
And then copy 3 different ranges from three different sheets (2 of which are hidden) to empty sheets of the same names in the newer workbook (vehicle configuration, budget log and log).
I know that getSheetById has issues with permissions of some sort. I am not very familiar with google scripting so any help is appreciated.
//variables
var id = "123456789abcdefg";
var sheet = "LOG WIZARD";
var cells = "M11:AB13";
var range = SpreadsheetApp.openById(id).getSheetByName(sheet).getRange(cells);
var id = range.getSheet().getParent().getId();
//custom function to import logs
function importlogs() {
//Source sheet from which to import from
var is = SpreadsheetApp.openById(id)
var sheet1i = is.getSheetByName("BUDGET LOG");
var sheet2i = is.getSheetByName("LOG");
//Current sheet from which to export to
var xs = SpreadsheetApp.getActiveSpreadsheet();
var sheet1x = xs.getSheetByName("BUDGET LOG");
var sheet2x = xs.getSheetByName("LOG");
//Copy and paste contents of import Budget Log sheet to export Budget Log sheet
sheet1i.getRange("A3:AO").copyTo(sheet1x.getRange(sheet1x.getLastRow()+1,1,1,7), {contentsOnly:true});
//Copy and paste contents of import Log sheet to export Log sheet
sheet2i.getRange("A3:O").copyTo(sheet2x.getRange(sheet2x.getLastRow()+1,1,1,7), {contentsOnly:true});
}
I am unsure if it is actually passing the key correctly or at all. I tend to get the error Exception: Unexpected error while getting the method or property openById on object SpreadsheetApp. or Exception: You do not have permission to call SpreadsheetApp.openById. Required permissions: https://www.googleapis.com/auth/spreadsheets (line 5).
I assume this is because of some type of permission that doesn't allow a custom function to call another spreadsheet?
I have tried various suggestions here:
You do not have permission to call openById
and here:
How to use an installable trigger to get SpreadsheetApp.openById(id) to work, by calling it from a cell
but so far nothing I have found works.
The //variables section is in the global scope of the script project, so those definitions get evaluated every time any function runs, just before the function executes.
The problem is that those definitions are not compatible with the custom functions you are using. A custom function runs in a limited context where methods that require authorization are not available. When SpreadsheetApp.openById(id) gets called in that context, the custom function errors out, even though the problematic line of code is not within the function itself.
The importlogs() function is run through a button. It will run in an authorized context where SpreadsheetApp.openById(id) is available normally.
To solve the problem, delete the //variables section. The same declarations are repeated within importlogs(), so that should be enough. If you want to improve the importlogs() function, use the code given to you in your previous question.
You may want to add this code to easily call the importLogs_() function through a button:
/**
* Call this function through a button.
* https://developers.google.com/apps-script/guides/menus#clickable_images_and_drawings_in_google_sheets
*/
function runImportLogs() {
const sourceSsId = SpreadsheetApp.getActive()
.getRange('LOG WIZARD!M11')
.getDisplayValue();
importLogs_(sourceSsId);
}

TypeError: Cannot read property 'getSheetByName' of null

Looking for some help with a code in script app. I'm using the below code to get data from one sheet and then put it in the last row of another sheet. Both sheets are in the same workbook. I'm taking a monthly snap shot of a budget, so I have a historical view. The code runs when I manually 'run' it, however when I set up an automatic trigger I get the following error message TypeError: Cannot read property 'getSheetByName' of null at recordVariancesHistory(Variances script:3:19)
I have the same code set up in another spreadsheet and the trigger takes a snap shot each month without issue. I can't figure out what's different in this spreadsheet.
function recordVariancesHistory() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName('ForMaster');
var sheet2 = ss.getSheetByName('Variances History');
var data = sheet1.getRange('z84:Af87').getValues();
var last_row = sheet2.getLastRow();
sheet2.getRange(last_row + 1,1,4,7 ).setValues(data);
}
Any help would be greatly appreciated.
Change getActiveSpreadsheet to openByUrl or openById. If you need dynamical search file, use DriveApp in order to find it.

Google sheets appscript to copy tabs to new sheets

I have a google sheet with around 190 tabs on that i need to split into 190 different files
The files need to be named the same as the tab, the contents of the tab need to be copied as values but i also need to bring the formatting accross (just not the formulas).
I have looked around, and through a combination of previous questions and answers plus using the function list help have formed the following code. It actually works for the first few tabs but then throws up an error about being unable to delete the only sheet.
function copySheetsToSS() {
var ss = SpreadsheetApp.getActive();
for(var n in ss.getSheets()){
var sheet = ss.getSheets()[n];// look at every sheet in spreadsheet
var name = sheet.getName();//get name
if(name != 'master' && name != 'test'){ // exclude some names
var alreadyExist = DriveApp.getFilesByName(name);// check if already there
while(alreadyExist.hasNext()){
alreadyExist.next().setTrashed(true);// delete all files with this name
}
var copy = SpreadsheetApp.create(name);// create the copy
sheet.copyTo(copy);
copy.deleteSheet(copy.getSheets()[0]);// remove original "Sheet1"
copy.getSheets()[0].setName(name);// rename first sheet to same name as SS
var target_sheet = copy.getSheetByName(name);
var source_range = sheet.getRange("A1:M50");
var target_range = target_sheet.getRange("A1:M50");
var values = source_range.getValues();
target_range.setValues(values);
}
}
}
I am hoping someone can tell me what i have done wrong as I cannot figure it out at this point. I am also open to better solutions though please be aware I am very much a beginner on google appscript, nothing too complex please.
thankyou
In principle your script correctly adds a new sheet to the new spreadsheet before removing the preexisting one
However, mind that calls to service such as SpreadsheetApp are asynchronous.
And this becomes the more noticeable, the longer your script runs.
In your case it apparently leads to behavior that the only sheet is being deleted before the new sheet is being created.
To avoid this, you can force the execution to be synchronous by implementing calls to SpreadsheetApp.flush().
This will ensure that the old sheet won't be deleted before the new one gets inserted.
Sample:
copy.deleteSheet(copy.getSheets()[0]);// remove original "Sheet1"
SpreadsheetApp.flush();
copy.getSheets()[0].setName(name);
You might want to introduce call toflush()` also at other positions where it is important for the code to run synchronously.

sheet.getFormUrl() not found

When creating a copy of a spreadsheet that is linked to a form, a newSheets.getFormUrl() not found error occurs. The new spreadsheet is created since I'm able to add a new editor to it and it appears in the appropriate drive folder. Likewise, the expected new form is created and it is indeed linked to the the new spreadsheet. However, when trying to get a handle on the new form via getFormUrl(), the error occurs. I want to rename the new form and move it to a new folder but can't.
Also, although Spreadsheet.getFormURL() exists in the API, it doesn't appear in the typeahead when keying in the function. My Apps Script runtime is V8.
// generate the response sheet into the folder and add editor
var newSheet = DriveApp.getFileById(templateResponseSheetID).makeCopy('Contact Tracing RESPONSES - ' + name, childDocsFolder);
newSheet.addEditor(email);
var newform = newSheet.getFormUrl();
The problem is that newSheet is a File object but getFormUrl() is a method of Class Spreadsheet
instead of
var newform = newSheet.getFormUrl();
use
var spreadsheet = SpreadsheetApp.open(newSheet);
var url = spreadsheet.getFormUrl()

How to duplicate a sheet on a user-selected target spreadsheet and copy data

I’m very new to Google Apps Script, and I’m having trouble trying to accomplish my goal.
I have a Google Sheets Workbook that allows users to:
Select a name from a drop down (each name has a unique/individual
google workbook URL associated with it)
Type in a desired spreadsheet name
Press a “Push Sheet” button
Once the user presses the button, I’m trying to accomplish the following things:
Duplicate the sheet 'Template - Do Not Modify’ that already exists on target workbook (the URL associated with the selected name)
Rename the duplicated sheet to the desired spreadsheet name
Copy the range A7:D150 from the sheet “Tracker” on the original workbook to the range A7:D150 newly created sheet on the target workbook
The original sheet is set up to have the user authorize the workbook connection prior to running the script.
Here's my code:
function cloneGoogleSheet() {
var sheet = SpreadsheetApp.getActiveSheet();
var name = sheet.getRange("B10").getValue();
var url = sheet.getRange("f5").getValue();
var tss = SpreadsheetApp.openByUrl(url);
tss.setActiveSheet(tss.getSheetByName('Template - Do Not Modify'));
tss.duplicateActiveSheet();
var activesheet = tss.getActiveSheet();
activesheet.setName(name);
}
My issues are:
It doesn't seem like utilizing ActiveSheets is a safe way to do all of this and that there's a better way.
When attempting to use the URL variable (the script runs fine with a hardcoded URL value), I get an invalid argument: URL error. The cell F5 updates to a new URL based on what name is selected from the drop down, using a lookup which references names with unique URLs:
=lookup(B4,
{P71,P72,P73,P74,P75,P76,P77},
{Q71,Q72,Q73,Q74,Q75,Q76,Q77}
)
Given the fact that I'm using all these ActiveSheet variables, I'm not sure how to get back to my original sheet to copy the ranges.
I would very much appreciate someone showing me the correct way to do this. Thanks!
Have you tried using "getSheetByName"?
Try Armit Agarwal's tutorial on Duplicate a Sheet in Google Spreadsheets:
function cloneGoogleSheet() {
var name = "labnol";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Template').copyTo(ss);
/* Before cloning the sheet, delete any previous copy */
var old = ss.getSheetByName(name);
if (old) ss.deleteSheet(old); // or old.setName(new Name);
SpreadsheetApp.flush(); // Utilities.sleep(2000);
sheet.setName(company);
/* Make the new sheet active */
ss.setActiveSheet(sheet);
}