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().
Related
I know this has been asked before but none of the answers seem to be working for me. I need to get the values of cells that are clicked on. As a very basic prototype, I created a script tied to my spreadsheet with the following:
function getVal() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
Logger.log(sheet.getActiveCell().getValue());
}
I then go into my spreadsheet and select a cell with a value and run the function in the script window. No value is displayed in the log.
Next I tried:
function getVal() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
Logger.log(sheet.getActiveCell().getRow() + ',' + sheet.getActiveCell().getColumn());
}
I then go into my spreadsheet and select a cell with a value (G6) and run the function in the script window. The log displays 1,1.
And finally I tried
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
Browser.msgBox(sheet.getActiveCell().getRow() + ',' + sheet.getActiveCell().getColumn());
}
I then go into my spreadsheet and select a cell with a value (G6) and make a change to it. When I hit enter, the popup dialog displays 1,1.
This seems like it should be really simple but for the life of me cannot figure it out. Can anyone help?
I tested this in a spreadsheet and I found that using var sheet = ss.getActiveSheet(); yielded the correct results whereas using the .getSheets()[] method did not.
This is a bit late, but I was researching this today, and wanted to share: My issue was similar, in that sheet.getActiveRange().getRow(), sheet.getActiveCell().getRow(), etc., all returned row 1, regardless of what cell or range was active.
In this case, I was opening the script from a previous bookmark I created. Opening the script from a bookmark apparently doesn't re-establish the active relationship with the sheet.
Once I opened the script from the spreadsheet instead, my code returned the correct row reference.
I have tried following code and works fine. getRow() method is of Range class not Sheet class.
var ActSpSheet = SpreadsheetApp.getActiveSpreadsheet();
var ActSheet = ActSpSheet.getActiveSheet();
var GetCell = ActSheet.getCurrentCell();
var GetCurRow = GetCell.getRow();
Logger.log(GetCurRow);
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 have the following app script associated with a Google Spreadsheet that is accepting data from a Google Form:
function writePatientData() {
var spreadsheet = SpreadsheetApp.openById("<spreadsheet id>");
var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
//get last row in active/main sheet
var numRows = sheet.getLastRow();
//get last row of data
var last_row = sheet.getSheetValues(numRows, 1, 1, 23);
//get patientID (column V) in last row of sheet
var lastPatientID = sheet.getRange(numRows,3).getValue();
//find patient sheet based on patientID and make it active, then write to it
var patientSheet = SpreadsheetApp.getActive().getSheetByName(lastPatientID);
var activePatientSheet = SpreadsheetApp.getActive().getSheetByName(lastPatientID);
activePatientSheet.getRange(activePatientSheet.getLastRow()+1, 1,1,23).setValues(last_row);
}
What this script is doing is writing data (a row) to another sheet within this spreadsheet based on the the patientID (column V). This works as it should when I manually run the script. However, when I set a trigger to run this script (either onSubmit or edit) nothing happens. I created another function that just writes a message to the logs and set a trigger for that function and it works, so I think there is something in the script that is causing it to fail. Any ideas appreciated.
There are a few issues with your code. I tried to fix it while commenting each line I changed. Hopefully that is clear enough, please comment if you have any questions and I'll try to clarify.
function writePatientData() {
var spreadsheet = SpreadsheetApp.getActive(); //no need for id if the script is on the same spreadsheet
//var sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[0]);
//setActiveSheet will not work from a trigger like on-form-submit (what if no-one has the sheet open, or multiple have)
var sheet = spreadsheet.getSheets()[0]; //if you want the first sheet, just get it, no need to "activate"
var numRows = sheet.getLastRow();
var last_row = sheet.getSheetValues(numRows, 1, 1, 23)[0]; //added [0] since it is just one row
//var lastPatientID = sheet.getRange(numRows,3).getValue(); //you already have this in memory
var lastPatientID = last_row[2]; //arrays are zero based, that's why 2 instead of 3
//btw, you mention column V, but this is actually C
//var patientSheet = SpreadsheetApp.getActive().getSheetByName(lastPatientID);
//you already have the spreadsheet, no need to get it again
var patientSheet = spreadsheet.getSheetByName(lastPatientID);
//var activePatientSheet = spreadsheet.getSheetByName(lastPatientID); //this is the exact same as above, why?
patientSheet.appendRow(last_row); //appendRow is just simpler than getRange(getLastRow).setValues
}
At the moment this is the function I'm using but I have no way of testing if it will work in the spreadsheet until I publish the application.
function readSelection() {
//The commented lines aren't needed if the sheet is open already
//var sheetid = "sheet id here";
//var spreadsheet = SpreadsheetApp.openById(sheetid);
//SpreadsheetApp.setActiveSpreadsheet(spreadsheet);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
//sheet.setActiveSelection("B2:B22");
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
return activecells;
};
I assume you mean highlighted == selected
The result depends on whether the cells are contiguous or not (non contiguous cell selection is available in the new spreadsheets features http://googleblog.blogspot.co.nz/2013/12/new-google-sheets-faster-more-powerful.html
For contiguous cells selected your code returns the values of the selection as an array, for non-contiguous cells your code will return the an array with the single value of the LAST selected item.
I suggest that this is a bug in the implementation of the new spreadsheet. If it is important to you, I suggest you raise an issue. For the old spreadsheets, you can only select contiguous cells (eg B2:B22) so it will work as you expect.
The easiest way to answer this Q is to run the code you have written! You don't have to publish anything just run the code in the script editor of the spreadsheet you are examining
and look at the log.
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activerange = sheet.getActiveRange();
var activecells = activerange.getValues();
Logger.log(activecells)
return
};
There is no way to do this at the moment or to obtain the selected ranges from a script.
A request is pending and you can support it here : https://code.google.com/p/google-apps-script-issues/issues/detail?id=4056
by adding a star to the request.
If/when this function is implemented your code would look as follows:
function readSelection() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var activeranges = sheet.getSelectedRanges();
var activecells = [] ;'
for (var ar in activeranges)
activecells = activecells.concat(activeranges[ar].getValues()) ;
Logger.log(activecells)
return ;
}
note that selected ranges may overlap, so some cell contents could be added twice.
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.