I would admit that I'm not a pro at all, I just try to do some app script for my company and I faced a problem I really don't understand.
I can't execute a function I've made with a button nor with a trigger, but only by doing by my own with the execute button in the app script interface.
The issue is always the same :
Error The coordinates of the target range are outside the dimensions of the sheet.
But as I said above, when I execute by myself I don't receive any error message and the code works well.
Here is the code :
function Colle() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var lastRow = spreadsheet.getLastRow()+1;
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Data GC'), true);
spreadsheet.getRange('A1').activate
spreadsheet.getSheetByName("Data GC").getRange('A1:F500').activate(); // I know that my
//data will never exceed more than 400 so just as a security I've put 500
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sauvegarde GC'), true);
spreadsheet.getRange('A' + lastRow).activate();
spreadsheet.getSheetByName("Data GC").getRange('A1:F500').copyTo(spreadsheet.getActiveRange(),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
SuppDoubl(); //Delete the duplicates
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Sauvegarde GC'), true);
spreadsheet.getRange('A1').activate();
};
*Sorry for my English
function SuppDoubl() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A:F').activate();
spreadsheet.getActiveRange().removeDuplicates().activate();
spreadsheet.getRange('A1').activate();
};
Why do you need so many activate()s? If you want just to copy some range from one sheet to other sheet it can be done without activate():
function colle() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source = ss.getSheetByName('Data GC').getRange('A1:F500');
var target = ss.getSheetByName('Sauvegarde GC').getRange('A1'); // or A + last row
source.copyTo(target, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
// SuppDoubl(); // <-- probably the error is here?
ss.setActiveSheet(ss.getSheetByName('Sauvegarde GC'), true);
ss.getRange('A1').activate();
}
It works fine for me (without the SupDoubl()) via button and any way.
Related
This is the code - it works fine. Except i just ran it and it executed on the wrong tab meaning i lost a bunch of data. How can I specify it to only to ever run on the tab called "Form Responses 1"?
/** #OnlyCurrentDoc */
function DragDownRefresh() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('B10:l10').activate();
spreadsheet.getActiveRange().autoFill(spreadsheet.getRange('B10:l2002'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
spreadsheet.getRange('B10:l2002').activate();
};
Thanks
Try this:
function DragDownRefresh() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheetByName("Form Responses 1");
sheet.getRange('B10:l10').activate();
sheet.getActiveRange().autoFill(spreadsheet.getRange('B10:l2002'), SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
sheet.getRange('B10:l2002').activate();
};
My script creates a Google Form programmatically and sets the destination to the current Spreadsheet:
var sheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
var form = FormApp.create(acctName).setTitle(acctName).setDestination(FormApp.DestinationType.SPREADSHEET, sheetId);
// several form items added here
Next, I'd like to rename the destination Sheet and make a few formatting edits. When I do, however, the sheet doesn't seem to exist. For example, getSheets() does not contain the new Sheet! (And yes, ideally I'd like to open the sheet by ID; see function below which also doesn't work.)
var sheets = SpreadsheetApp.openById(form.getDestinationId()).getSheets();
SpreadsheetApp.setActiveSheet(sheets[0]);
The above code opens what I would consider index 1, not index 0, because the sheet isn't indexed. I even tried creating a few second delay (hoping that it was just a matter of time to allow the sync to happen between the client and server) but without any success.
I have also tried something like the following, as suggested elsewhere here on Stack Overflow, but the destination Sheet doesn't come up in getSheets() even when called through a separate function:
function getFormDestinationSheetId(form) {
var destinationId = form.getDestinationId();
if(destinationId) {
var spreadsheet = SpreadsheetApp.openById(destinationId);
spreadsheet.getSheets().forEach(
function(sheet) {
var sheetFormUrl = sheet.getFormUrl();
if(sheetFormUrl) {
var sheetForm = FormApp.openByUrl(sheetFormUrl);
if(sheetForm.getId() == form.getId()) {
return sheet.getSheetId();
}
}
}
);
}
return null;
}
I haven't been able to find anyone have a similar problem on the webs. Any advice would be appreciated. Thanks!
Welcome to Stack!
I assume your script is bound to a sheet? Depending on how you're calling the script you may not see the new sheets because of browser caching.
function myFunction() {
var sheet = SpreadsheetApp.getActive();
var sheetId = sheet.getId();
var form = FormApp.create('acctName').setTitle('acctName').setDestination(FormApp.DestinationType.SPREADSHEET, sheetId);
var ssSheets = sheet.getSheets();
var respSheet = ssSheets[0]
respSheet.getRange('A1').setBackground('RED');
respSheet.getRange('C1').setFormula('=COUNTA($C$2:$C)');
respSheet.setColumnWidth(2, 100);
SpreadsheetApp.flush();
}
I want the sheet displayed to scroll down to a range while a script is still running.
This would let me answer a ui.alert() whilst being able to check the data from the sheet displayed in the background.
Bellow are the scripts I have tried :
function Test() {
var document = SpreadsheetApp.getActive();
var ui = SpreadsheetApp.getUi();
var sheet = document.getActiveSheet();
var range = sheet.getRange(100, 1); // The range I want to be displayed
sheet.setActiveRange(range); // First attempt => works perfectly, but late
// SpreadsheetApp.setActiveRange(range); => attempt 2
// sheet.setActiveSelection(range); => attempt 3
var query = ui.alert("Scroll display" + "The selected cell is displayed", ui.ButtonSet.OK);
}
All the scripts, I have tried works perfectly, i.e., scroll to the wanted (selected) range once the script is finished, but none manage to do it while it is still running, before the ui.alert().
The command needed is : SpreadsheetApp.flush() (thx TheMaster).
function Test() {
var document = SpreadsheetApp.getActive();
var ui = SpreadsheetApp.getUi();
var sheet = document.getActiveSheet();
var range = sheet.getRange(100, 1 ); // The range I want to be displayed
sheet.setActiveRange(range);
SpreadsheetApp.flush();
var query = ui.alert("Display" + "The cell (100,1) is displayed", ui.ButtonSet.OK);
}
I am running this function i made in Google Apps Script for a spreadsheet add-on. It does everything right, but every OTHER execution it doesn't hide the sheet. Any ideas?
function addEmailNew(formObject) {
var newEmail = formObject.addEmailText;
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.getSheetByName("No Touching!").activate();
//find the last string value in a column
var Avals = ss.getRange("J:J").getValues();
var Alast = Avals.filter(String).length + 1;
ss.getSheetByName('No Touching!').getRange("J" + Alast).setValue(newEmail);
//THIS IS THE THING THAT WORKS EVERY OTHER TIME
SpreadsheetApp.getActiveSheet().hideSheet();
openDialog();
return Logger.log("this did stuff");
}
It's fine to get the active sheet, but prior to hide it, activate another sheet. Try something like the following:
var sheetToHide = SpreadsheetApp.getActiveSheet();
ss.getSheetByName("Other sheet").activate();
sheetToHide.hideSheet();
If the problem persists, add SpreadsheetApp.flush(); on a new line after hideSheet().
This should be simple but I'm stuck on this script...
It has a function (createnewsheet) that runs manually AND on a time trigger so I had to choose openById() to access the spreadsheet but when I'm looking at the sheet and run the function manually I want to set the newly created sheet active and that's what is causing me trouble.
When I run the function (createnewsheet) from the script editor everything is fine but when I call it from the spreadsheet menu I get this error message : Specified sheet must be part of the spreadsheet because of the last line of code. AFAIK I'm not addressing a sheet outside my spreadsheet... Any idea what I'm doing wrong in this context ?
Here is a simplified code that shows the problem, a shared copy is available here
var ss = SpreadsheetApp.openById('0AnqSFd3iikE3dGVtYk5hWUZVUFNZMzAteE9DOUZwaVE');
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('master')
var logsheet = ss.getSheetByName('logger')
var FUS1=new Date().toString().substr(25,6)+":00";
function onOpen() {
var menuEntries = [ {name: "Manual test", functionName: "createnewsheet"},
];
sheet.addMenu("Utilities",menuEntries);
SpreadsheetApp.setActiveSheet(logsheet);// this is working fine
}
function createnewsheet(){
var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy")
try{
var newsheet = ss.insertSheet(sheetName,2);// creates the new sheet in 3rd position
}catch(error){
FUS1=new Date().toString().substr(25,6)+":00";
var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);// creates the new sheet with a different name if already there
}
newsheet.getRange(1,1).setValue(sheetName);
SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);// should make 3 rd sheet active but works only when run from script editor
// SpreadsheetApp.setActiveSheet(newsheet);// should have same result but works only when run from script editor
}
I found a practical workaround to solve my use case : I use a different function from the menu (in wich I setActive() the sheet I want) and call the main function from this one.
When called from the trigger there is no use to set any active sheet so I removed this part from the main function.
It goes like this :
function manualTest(){ // from the ss menu
createnewsheet();
var sheet = SpreadsheetApp.getActiveSpreadsheet();
SpreadsheetApp.setActiveSheet(sheet.getSheets()[2]);// this works from the menu when ss is open
}
function createnewsheet(){ // from the trigger and from function manualTest()
var sheetName = "Control on "+ Utilities.formatDate(new Date(), FUS1, "MMM-dd-yy");
try{
var newsheet = ss.insertSheet(sheetName,2);
}catch(error){
FUS1=new Date().toString().substr(25,6)+":00";
var newsheet = ss.insertSheet(sheetName+' - '+Utilities.formatDate(new Date(), FUS1, "HH:mm:ss"),2);
}
newsheet.getRange(1,1).setValue(sheetName);
}
There is a catch here
SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);
When you run it from script editor, It automatically gets the container spreadsheet and makes the said sheet active, but it is not the case when you run it from Custom Menu or triggers.
Modify this statement to:
ss.setActiveSheet(ss.getSheets()[2]);
ss.setActiveSheet(newsheet);
The best solution i have found is to reseed sheet. getActiveSpreadsheet() recognises the Spreadsheet currently in use so no need to openById once more, but
// SpreadsheetApp.setActiveSheet(ss.getSheets()[2]);
// SpreadsheetApp.setActiveSheet(newsheet);
sheet = SpreadsheetApp.getActiveSpreadsheet(); // reloads the active sheet (including changes to the Sheets array)
sheet.setActiveSheet(sheet.getSheets()[2]); // works as expected from editor and custom menu
I think this suggests that the original ss and sheet have cached the Spreadsheet to memory and their pointer isn't refreshed to reflect structural changes. I tried .flush() as a shortcut, but that seems a one way refresh to the sheet from the script, not the other way around.