Is it possible to close a UI window that has opened in Apps Script?
I think the answer is no per: http://code.google.com/p/google-apps-script-issues/issues/detail?id=474&can=1&q=.close%28%29&colspec=Stars%20Opened%20ID%20Type%20Status%20Summary%20Component%20Owner
but I wanted to see if there were other opinions.
I have a "Waiting window" that pops up, that I want to close when the activity is finished.
var app = UiApp.getActiveApplication();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = getSheetWithSubmissions(ss);
// create UI app, this works fine
app = createWaitPleaseUI(sheet);
ss.show(app);
//simulated activity
Utilities.sleep(5000);
//this doesn't work despite being in the documentation
app.close();
Think this is not possible but wish Google would dump it from their documentation if it can't be done.
As a workaround, I can bring up a second GUI saying "work complete, click OK" and then it works fine.
You have to return the app object for any changes to be updated to it, even closing.
Change your last line to return app.close() instead.
You should read the documentation more thoroughly, it is clearly explained that UI in spreadsheets need to be ended by a return to actually close. Also I would suggest that you might trust the answer coming from a top contributor instead of believing that you are always right against the doc and everybody else ... no offence but a bit of humility is always welcome :-)
here is an piece of code extracted from the documentation to corroborate :
// Close everything return when the close button is clicked
function close() {
var app = UiApp.getActiveApplication();
app.close();
// The following line is REQUIRED for the widget to actually close.
return app;
}
Related
I'm trying to teach myself to use Google Apps Script, but somehow every function I try returns this error immediately. And since I'm a huge beginner, I don't know what I'm doing wrong.
Here's a simple example of a code I tried to run:
function myFunction(){
//application
//file
var ad = DocumentApp.getActiveDocument();
var docBody = ad.getBody () ;
var paragraphs = docBody.getParagraphs();
//paragraphs[0]. setText ("MY NEW TEXT"):
//var attr = paragraphs[0].getAttributes() ;
//Logger.log(attr);
paragraphs[0].setAttributes({FONT_SIZE:40});
}
Yet no matter what I'm running really, I get this:
TypeError: Cannot read property 'getBody' of null
myFunction # Code.gs:5
What am I doing wrong?
I have an open Google Doc, I've allowed permissions to run the script project. What else should I try? Thanks.
In order to get getActiveDocument() working you need to use it in a script that is container-bound:
Create a new Google Document
Go to Extensions > Apps Script
Run your function inside of it.
If your script is not container-bound, you need to use the openById(id) or openByUrl(url) methods, in order to retrieve a Document
Adblock software was preventing the running somehow. Disabled it and runs fine now. Disregard!
I'm trying to create a timer in Google Apps Script, such that when there is a number displayed on a cell, and I start the script, the script will automatically decrement that number once every second, until the value reaches zero.
So I found this answer on a related question, and managed to implement code that does the same thing just fine. My one problem is that the code seems to run slowly - so that a second doesn't actually take a second. At a guess, it's between 1.5 to 2 seconds. This obviously isn't hugely ideal for a timer, and I'm wondering if it's a fixable problem. Is there a code optimization that might make my timer run on time, or something I've not factored in?
Here's a link to a test spreadsheet, with the code in the Script Editor (it's View Only for safety, but the spreadsheet can be copied.) A UI control should initiate the "Start Timer" function if you want to test it.
Here's the full code:
var ss = SpreadsheetApp.getActiveSpreadsheet();
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu("Timer controls")
.addItem("Start Timer", "startTimer")
.addToUi();
}
function startTimer() {
var timer = ss.getRangeByName("Timer");
var timeval = timer.getValue();
while (timeval > 0) {
timeval--;
timer.setValue(timeval);
SpreadsheetApp.flush();
Utilities.sleep(1000);
}
}
Timer
function undertest() {
var start=new Date().getTime();//milliseconds
//all your other code here
Logger.log(Number((new Date().getTime()-start)/1000).toFixed(2));//seconds
}
Tl;Dr There is no fix for your code.
You are missing that there are communications processes between your web browser and Google servers...
and that Google Apps Script methods are slow,
and that editing a cell value triggers the recalculation of the whole spreadsheet.
You should start over and instead of using sever side code and Google Sheets to display a timer, follow the recommendation of Cooper on his answer to the same question of the answer that in linked in the question: Use client-side code.
Today I can't run scripts connected to a specific Google Spreadsheet which contains .next() function calls, which I use to access other Spreadsheets by name. It shows Running script Cancel Dismiss message at the top of spreadsheet until exceeding maximum execution time. The strange thing is that I have similar files for every day with exactly same scripts, and the one for yesterday works fine. I created MWE below. So, when I run it I can get the alerts for the first 2 messages, but not the 3rd one.
function test_script_hanging() {
var ui = SpreadsheetApp.getUi();
ui.alert("before getting files by name");
var getFilefile = DriveApp.getFilesByName("file");
ui.alert("after getting files by name");
var getID = getFilefile.next().getId();
ui.alert("after getting Id");
}
In some situations I notice an error message saying something like "Authorization is needed to perform this action" on the line where the .next() function is being called. I tried to revoke authorization of the file and give authorization again, but that didn't help. I tried to give full access to a given script, but couldn't google the way to do it.
Maybe I can add some more functions in my script to require full access during authorization, and maybe that will help to run my main function.
My questions are:
Why the script hangs?
How to fix this?
Can such kind of things (randomly and without any notice) happen in a free version of Google account?
This works for me:
var fldr = DriveApp.getFolderById(folderID)
var file = fldr.getFilesByName(filename);
while(file.hasNext())
{
var fi = file.next();
if(fi.getName() == filename)
{
var id=fi.getId();
}
}
I am creating some google app scripts for my company to use to generate random tests for employee training. I already have the basic scripts written to grab a list of questions from a google sheet, randomize them, grab the first 10 questions, etc. That all works fine. I decided it might be better to re-do the whole thing using a UiApp instead of just separate scripts. That is where the problem comes in. I did a simple bare bones UiApp to test with, published it and tried to hit the URL and that's where I encounter this error. I searched for this error and all I could find was some discussion about this being part of google apps premiere(which should have been folded into regular google apps around 2010). I've been staring at this so long I've frustrated myself. It should be something very simple and yet it's refusing to work. I'm assuming I am doing something wrong at a basic level but I've reached the point where my brain refuses to see it.
Here is the basic script I started with:
function doGet(e) {
var app = UiApp.createApplication();
var mainPanel = app.createVerticalPanel().setId('mainPanel');
mainPanel.add(app.createLabel('test'));
return app;
}
I save it, publish it and go to the URL and that's when I get the above error message. I know it's something simple but I've reached the point of frustration and simply can't see it.
Update: to reflect comments
Another possibility for WebApps not updating is not publishing a new version and only checking the exec URL. For instant changes to the code, always check the dev URL. The exec will only change after saving a version in Manage Versions and re-publishing the app.
First Answer:
I think your question title says it all.
UIApp is not defined, but Class is UiApp. JS is case sensitive. I copied and pasted the code exactly as it is in your question and received no errors. I did have to add one line to make the label show up.
function doGet(e) {
var app = UiApp.createApplication();
var mainPanel = app.createVerticalPanel().setId('mainPanel');
mainPanel.add(app.createLabel('test'));
app.add(mainPanel); // <-- I added this line to see the label
return app;
}
I'm doing everything as prescribed in the 'Defining Spreadsheet Menus' tutorial. The menu is modified using the onOpen event handler.
I have made this 'Text to Columns' script available publicly in the 'Script Gallery' but I'm concerned that users who download may be confused when it takes a long time for the custom menu to pop up.
Getting the script to load the first time is proving to be a pain. Much of the time the onOpen trigger is missed altogether. It appears that the trigger isn't being set correctly because manually resetting the onOpen trigger will fix it.
For personal use I'd consider this a minor annoyance but for a shared script it becomes a support issue.
Note: Every subsequent load consistently takes about 7 seconds to appear which is OK but far from ideal.
Here's the onOpen handler:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [];
menuEntries.push({ name:"Text to columns", functionName:"textToColumns" });
menuEntries.push({ name:"Text to columns (custom separator)", functionName:"textToColumnsCustom" });
menuEntries.push(null);
menuEntries.push({ name:"Columns to Text", functionName:"columnsToText" });
menuEntries.push({ name:"Columns to Text (custom separator)", functionName:"columnsToTextCustom" });
ss.addMenu("Advanced", menuEntries);
}
Note: This was tested on a new (ie empty) spreadsheet with only one user.
i'm not sure but the user have to log in i guess, if not, i've got this problem once and solved it with making tow or more triggers all of them are on open and the same function,however try to get internet speed more than 30KB/s to make sure that the problem is from the code , not from your devices