App Script shows variable as not used, but it is? - google-apps-script

The Google Apps Script editor is showing the x variable as grayed out, as though it is not used. Why?
function test2() {
var x = false;
x = true;
};
Obviously, I have code between the two lines but even in this simplest case it indicates that x is not used. Functionally it works, but I don't understand.

Related

GAS Webapp/Dialog returning unexpected results

dialogs seem to use the same interface web wise as the webapps, in other words a front html/javascript and a backend google apps script.
I'm getting some unexpected behavior if I try to return an array made from my spreadsheet rather than a straight up array.
This is my code
function returnRowArray(number){
if (number == null) number = 4;
thisSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TST Project Tracker");
console.log("L4 returnRowArray(): %s", number);
var headerRow = thisSheet.getRange("A1:DC1").getValues();
var resultRow = thisSheet.getRange(number,1,1,20).getValues();
var result = {}
result.info = resultRow[0][1];
result.site = site;
//result.row = resultRow;//LINE IN QUESTION
console.log("L10: %s", JSON.stringify(result));
return result;
}
If I run this function from my dialog WITH the line in question, it returns null to the dialog box, but with the line commented out it returns the object correctly.
the two CLIENT SIDE logged results show up as
L35: null
and
L35: Object
respectively, and I can pull the values out of the object.
If I run a SERVER SIDE test
function test_returnRowArray(){
var o = returnRowArray(4);
console.log("L15: "+o);
console.log("L16: "+ JSON.stringify(o));
}
it provides the correct result for both versions.
So what is going on here? I originally thought it was a size restriction but even when I do what I've done here, make the array just the first 20 columns, this still happens.
Any ideas?
edit: I will note if I make it result.row = ["this","array","works"] it does work, so how is the getrange array making it angry?
Adding per comments:
This is what the front end call looks like
function importInfo(){
google.script.run.withSuccessHandler(function(result){console.log("L35: %s", result);}).returnRowArray(row);
}

"com.au" string is displayed as "(class)" in Script Editor

I need to store an Australian domain as a string. Australian domains end with ".com.au"
Google Scripts seems to be displaying all instances of ".com.au" with "(class)".
To reproduce, create a basic function in Google Apps Scripts as follows:
function myFunction() {
var x = "com.au";
console.log("x: " + x);
var z = 1; //<--create break point here
}
Create a breakpoint at var z = 1, and then debug the script.
Actual Results:
In the console (at breakpoint):
x: (class)
Expected Results:
x: "com.au"
*Note: upon further testing, from a practical perspective, "(class)" seems to still be treated as "com.au" so this is not a blocker to use, but it is odd and does not help when debugging.
This issue was reported as a bug to Google: https://issuetracker.google.com/issues/114358543
This looks to be a bug of the Google Apps Script editor debugger that should be reported to Google. Please follow the directions on https://developers.google.com/apps-script/support#bugs.
I just got around this bug with the use of an Array.
function myFunction() {
var array = new Array();
var text ="email#email.com.br";
array[0] = string;
}
text returns email#email.(class)
array[0] returns email#email.com.br

Function for word count in Google Docs Apps Script

Is there a method in Google Apps Scrips that returns the word count from a Google Document?
Lets say I'm writing a report that have a particular limit on word count. It's quite precise and it states exactly 1.8k - 2k words (yes and it's not just a single case, but many...)
In Microsoft Office Word there was a handy status bar at the bottom of the page which automatically updated the word count for me, so I tried to make one using Google Apps Scrips.
Writing a function that rips out whole text out from a current document and then calculates words again and again several times in a minute feels like a nonsense to me. It's completely inefficient and it makes CPU run for nothing but I couldn't find that function for the word count in Docs Reference.
Ctr+Shift+C opens a pop-up that contains it, which means that a function that returns total word count of a Google Document definitely exists...
But I can't find it!
Sigh... I spent few hours digging through Google, but I simply cannot find it, please help!
Wrote a little snippet that might help.
function myFunction() {
var space = " ";
var text = DocumentApp.getActiveDocument().getBody().getText();
var words = text.replace(/\s+/g, space).split(space);
Logger.log(words.length);
}
I understand the the request is for a built in function, which I looked for as well, but couldn't find anywhere in the documentation. I had to use polling.
I started with a script like Amit's, but found that I was never matching Google's word count. This is what I had to do to get it work. I know this can't be efficient, but it now matches google docs count most of the time. What I had to do was clean/rebuild the string first, then count it.
function countWords() {
var s = DocumentApp.getActiveDocument().getBody().getText();
//this function kept returning "1" when the doc was blank
//so this is how I stopped having it return 1.
if (s.length === 0)
return 0;
//A simple \n replacement didn't work, neither did \s not sure why
s = s.replace(/\r\n|\r|\n/g, " ");
//In cases where you have "...last word.First word..."
//it doesn't count the two words around the period.
//so I replace all punctuation with a space
var punctuationless = s.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()"?“”]/g," ");
//Finally, trim it down to single spaces (not sure this even matters)
var finalString = punctuationless.replace(/\s{2,}/g," ");
//Actually count it
var count = finalString.trim().split(/\s+/).length;
return count;
}
I think this function probably covers most cases for word count with English characters. If I overlooked something, please comment.
function testTheFunction(){
var myDoc = DocumentApp.openByUrl('https://docs.google.com/document/d/?????/edit');
Logger.log(countWordsInDocument(myDoc));
}
function countWordsInDocument(theDoc){
var theText = theDoc.getBody().getText();
var theRegex = new RegExp("[A-Za-z]") // or include other ranges for other languages or numbers
var wordStarted = false;
var theCount = 0;
for(var i=0;i<theText.length;i++){
var theLetter = theText.slice(i,i+1);
if(theRegex.test(theLetter)){
if(!wordStarted){
wordStarted=true;
theCount++;
}
}else if(wordStarted){
wordStarted=false;
}
}
return theCount;
}

Google Apps Script Execution Order

Having trouble getting GAS to execute functions in the order I need. In this code:
function documentUpload(e) {
var app = UiApp.getActiveApplication();
app.getElementById('documentValue').setText('Uploaded');
app.getElementById('documentValueLabel').setStyleAttribute('color', 'black');
checkSubmit(e);
return app;
}
...it always runs checkSubmit before changing the text. Which is useless because one of the things that checkSubmit checks is whether documentValue has text.
I saw this post and tried adding LockService like so:
function documentUpload(e) {
var app = UiApp.getActiveApplication();
app.getElementById('documentValue').setText('Uploaded');
app.getElementById('documentValueLabel').setStyleAttribute('color', 'black');
var lock = LockService.getPrivateLock();
lock.waitLock(10000);
checkSubmit(e);
lock.releaseLock();
return app;
}
...but I'm not getting any different results. Same thing for Utilities.sleep().
Thanks in advance for any suggestions!
the UI is updated when you return app . That means that any function call from inside your function cannot see the changes you made to your UI from inside the same function.
You'll have to think differently, ie probably split your code in 2 functions to allow to return the app (in other words to update the UI) before calling the function that reads its content.
EDIT : when I look at your code it seems that the only thing you want to do before starting the download is to change a text value and a style attribute... if so you can use a clientHandler that will execute immediately (see this other recent post) maybe this can solve your problem... let us know if it does.

Cells containing custom functions return "NaN'" when spreadsheet is not open. (Apps Script webapp accessing google spreadsheet)

As a high school teacher, I record all of my grading in a Google spreadsheet. I have written custom functions within that spreadsheet that are accessed in the spreadsheet. That all works fine.
I also have a simple (but independent) web app written in google apps script that summarizes the grade information for each student that accesses it and returns it in a table. This has operated perfectly for about 8 months. However, students now get a "NaN" error when trying to check their grades. The "NaN" is only returned for cells that use custom functions. By simply opening the source spreadsheet, it fixes the problem temporarily. But soon after closing the spreadsheet the webapp begins returning "NaN" again.
I'm assuming that it has something to do with when/how these cells are recalculated but I can't figure out how to make the cells retain their value while the spreadsheet is closed. Any help would be much appreciated.
With Eric's advice, I implemented the following function (which runs early on in my app):
function refreshSheet(spreadsheet, sheet) {
var dataArrayRange = sheet.getRange(1,1,sheet.getLastRow(),sheet.getLastColumn());
var dataArray = dataArrayRange.getValues(); // necessary to refresh custom functions
var nanFound = true;
while(nanFound) {
for(var i = 0; i < dataArray.length; i++) {
if(dataArray[i].indexOf('#N/A') >= 0) {
nanFound = true;
dataArray = dataArrayRange.getValues();
break;
} // end if
else if(i == dataArray.length - 1) nanFound = false;
} // end for
} // end while
}
It basically keeps refreshing the sheet (using .getValues()) until all of the #N/A's disappear. It works fabulously but does add a small lag.