Simple Counting Function in Google Scripts - javascript

Just started learning how to write functions in Google Script Editor. Please help me fix my error. I'm also unable to get the Logger.log(var) function to produce anything in the log.
Goal of the function: count attendance based on whether an 'X' was listed next to a name. Currently the range being iterated through is hard coded. Is it possible to pass through a custom range when the function is called?
Thank you.
function attendance() {
var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
var count = 0
for (n=6; n<12;++n){
var cell = values[n][2];
if (cell == "X"){
count = count +1;
}
}
return (count);
}

Yes, you can use the length of the values array to make it more dynamic.
n < values.length

Related

Why is each iteration not being pushed as a row within sheets by Google Apps Script?

I'm learning Google Apps Script and am running some example code to help me understand how code is being interpreted. I'm sorry if these are very basic question but I'm trying to understand two things from the below code:
var sheet = SpreadsheetApp.openByUrl(sheet_url).getSheetByName(sheet_name);
for (var i=0;i<5;i++){
var text = "The number is " + i;
var range = sheet.getRange(1,1,1+i,1);
sheet.clear();
range.setValue(text);
console.log(text);
}
}
why the logger is returning each value whilst i iterates but the complete range in the Google sheet is being populated with "The number is 4" (i.e. the final iteration). I want each iteration to be posted into the sheet to replicate what's seen in the logger.
why range.setValue(text); allows the output to be set to the range but range.setValues(text); returns an error. Am I right in assuming this is because the output is being seen as a single value despite it being sent to multiple cells - i.e. the set function looks at the number of values being sent rather than the number of places the value is being sent to?
Again, apologies for the basic nature of my question. I am reading books and trying to work through practical examples. Any feedback is much appreciated.
Thanks
Nicky
function myfunc() {
var sheet = SpreadsheetApp.openByUrl(sheet_url).getSheetByName(sheet_name);
for (var i = 0; i < 5; i++) {
var text = "The number is " + i;
sheet.getRange(i+1,1).setValue(text);
}
}

How to save WebSql COUNT output as javascript variable?

I am looking for suggestions on how to best complete this task, and have found nothing on the web.
I am wanting to count the number of results that are returned from an SQL SELECT query and output that on my HTML page using JS/Jquery. Feel free to tell me there is a quicker and easier way than what I have done!!
I have found some suggestions using node.js, but I do not want to use that, as this is for a small school project.
This is the function that I am using when the select box is clicked. I am using it in conjunction with the 'onchange' in HTML (I think its HTML) and that works.
function placesLeft(val) {
let time = document.getElementById("placesLeft");
//time.innerHTML = val;
let selected = val;
db.transaction(function(tx) {
tx.executeSql('SELECT COUNT ( * ) FROM Sessions WHERE sessiontime = (?)', [selected], function(x, results) {
for (let i=0; i < 50; i++) {
const u = results.rows.item(i);
let count = 50 - i;
console.log(count);
console.log(i);
console.log(u);
time.innerHTML = count;
console.log(time.innerHTML);
};
});
});
}
Currently, it outputs the correct number of results when the query is run if I console.log 'u'. However, it outputs as this in the console: {COUNT ( * ): 2}.
When I try and add it to the tag I am using, it looks like this on the webpage:
[object, Object].
I am using WebSQL if you haven't realised, JS, and HTML. Fairly proficient in jQuery too, if that helps.
Here is a link to my code:
https://webucate.com.au/project/8sBxh4dPQ42fYB7viODZ/share
To get to the page I am talking about, click: book a session -> Scroll down to 'Choose a time' -> pick something. (10:00am and 1:00pm are the values I have in my database, and they appear 1 and 2 instances in the databases, respectively) In the console, you should see what u, I and count outputs.
The SQL Query uses a COUNT() function. It will return only one row and one column in the results.
As such there is no need to iterate the result set.
Is there a reason why you use an i-loop that iterates 50 times?
I would suggest changing the SQL command to
SELECT COUNT ( * ) AS COUNT FROM Sessions WHERE sessiontime = (?)
So that the column name of the value you need will be set as COUNT.
After that, retrieving the required value from the result set will be easier.
You can simply get the first row with results.rows[0].
Then retrieve the value at the column "COUNT".
var count = results.rows[0]["COUNT"]
time.innerHTML = count;
Hopefully this is solves your problem.

Concatenate tables in one and insert it in Google Spreesheet

I've got this basic script for Google Sheets, in G.Script
var a = [['1','2']];
for (var i = 0; i <5; i++){
var range = sheet.getRange("A"+i+":B"+i);
range.setValues(a);
}
As you can see, I write 5 times the table "a" in the sheet. What I'd like in concatenate all the tables "a" in one table and write this table, once in the sheet.
I've tried with concat(), but it does not work. So maybe I don't use it properly.
Could you please help me ?
Many thanks
B.
I recommend that you create your spreadsheet range based on the size of your array "a". Rather than creating a cell range such as A1:B5, I recommend using number values to define the range that you would like to update.
Also, updates to Google Sheets run much faster if you update an entire range at one time.
function myFunction() {
var data = [];
data.push([1,2]);
data.push([2,3]);
data.push([3,4]);
if (data.length > 0) {
SpreadsheetApp.getActiveSheet()
.getRange(1,1,data.length,data[0].length)
.setValues(data);
}
}

How to index array's in Google Apps Script?

I was working on this project and I wanted to make a function that displays an element of a specific column.
Now with javascript I can call any element of an array with
Array[i]
But for some reason this doesn't seem to work in Google Spreadsheets.
var MyFunction(A) {
return A[1];
}
This function yields me nothing.
EDIt: I solved it.
I used this loop with a sort of double indexing:
for (var i=0; i < 37; i++) {
if (A[0][i] < max && A[0][i] != 0) {
var max = A[0][i];
};
};
A[0][0] is the first element if I select a row vector in spreadsheet.
For example, If I select A2:A5 as A, A[0][0] will give me the value of cell A2!
Thanks for the help!
Try this instead:
var MyFunction(A) {
return A[0];
}
The assumption I making here is you are trying to return the first element in the index. In javascript Array index starts at 0 and not 1.
It doesn't work that way. You have to first allow access to the spreadsheet then tell Apps Script which Spreadsheet you're working on through openById. After that you can now access the data. Here's a simple code snippet for you. I'm using the standalone mode. There maybe other ways of doing this.
We're going to access this sheet. I've included the index numbers so you can easily understand:
Then we create a function named fetchValue which accepts 2 parameters- the row and the column.
We execute main function which makes calls to fetchValue.
function main(){
Logger.log("the value returned was "+ fetchValue(1,1) ); //returns las vegas
}
function fetchValue(row,col) {
var sheet = SpreadsheetApp.openById("SPREADSHEET_ID_HERE");
var data = sheet.getDataRange().getValues();
return data[row][col];
}
We then view the Logs if it returned the value of index 1,1 which is las vegas.
Make sure the row and column you pass to fetchValue is within range else it will return errors.

keeping localStorage objects that iterate whilst using clear() within the same function

I'm trying to clear all local storage when the user either completes the game loop or starts a new game, but also keep some values.
I can do this already with my sound values for volume:
// inside a conditional statement that fires when the user chooses to start a new game.
if (newGameBool === '1') {
var tst = myAu;
//myAu is the stored value that the user sets as sound using a range type input
localStorage.clear();
localStorage.setItem("Au", tst);//A newly cleared localStorage just got a new value, and it's the same as it was before.
UI.myLoad();//reload the function that uses LS to do things.
}
How do I do this for key's that have an iterating number attached to them?
Here is how I save them:
var i = +v + +1;
localStorage.setItem("v", i);
var vv = localStorage.getItem("v");
localStorage.setItem("LdrBrd_" + vv, JSON.stringify(LdrBrd));//saves all data with the iterating key name.
Calling them the way i did the sound function:
var gv = v + 1;//v calls the value from LS and adjusted for off-by-one error. gv is a local variable.
if (newGameBool === '1') {
var ldd, vg;
for (var ii = 0; ii < gv; ii++) {
var ld = localStorage.getItem("LdrBrd_" + ii);
if (ld != null) {
//these are the values that i want to pass beyond the clear point
ldd = JSON.parse(ld);//JSON string of data saved
vg = ii;//how many of them.
}
}
localStorage.clear();
for (var xx = 0; xx < vg; xx++) {
var nld = localStorage.getItem("LdrBrd_" + xx);
if (nld != null) {
localStorage.setItem("LdrBrd_" + ii, JSON.stringify(ldd));
}
}
localStorage.setItem("v", vg);
UI.myLoad();
}
I have been using console.log() in various spots to see what is going on. I comment-out the clear function just to see if the values were wrong and they don't save all all. I tried to make a fiddle, but the local storage wasn't working at all there. In visual studio, it works fine but the script to this file is almost 2000 lines long, so i tried to dress it up the best i knew how.
Thanks in advance for any help or guidance.
I was stuck on this for a few days, but i think i found something that will work, so i'll answer my own question in case there is value in posterity.
locatStorage.clear();
/* ^LS clear() function is above all new setItem codes, some variables are declared globally and some are declared at the top of the functional scope or as param^ */
var itemClass = document.querySelectorAll(".itemClass");//the strings are here
if (itemClass) {//make sure some exist
for (var p = 0; p < itemClass.length; p++) {//count them
mdd = JSON.parse(itemClass[p].innerText);//parse the data for saving
localStorage.setItem("v", v);//this is the LS item that saves the amount of items i have, it's declared at the top of the functions timeline.
localStorage.setItem("LdrBrd_" + p, JSON.stringify(mdd));//this setItem function will repeat and increment with 'p' and assign the right string back to the key name it had before.
}
}
The key is to keep the strings physically attached to an element, then call the class name. The i ran a loop counting them. 'mdd' will spit back each item i want. So then all that is left to do is re-set the item back to it's original status.
This has allowed me to create a way for my users to collect trophies and keep them even after clearing the localStorage when the he/she decides to start a new game.
I use CSS to hide the text from the string.
color:transparent;
In my gameLoop, i have a function that will read the saved strings and show them as cards just below the hidden strings.
Since you want to keep some values I recommend one of two things:
Don't call localStorage.clear() and instead only wipe out the values that you want using localStorage.removeItem('itemName'). Since you said the item names have a numeric component, maybe you can do this in a loop to reduce code.
Pull item(s) that you want saved first and restore them after calling clear(). This option is best if there are way more items that you want removed rather than saved (see below)
function mostlyClear() {
var saveMe = {};
saveMe['value1'] = localStorage.getItem('value1');
saveMe['anotherValue'] = localStorage.getItem('anotherValue');
localStorage.clear();
for(var prop in saveMe) {
if(!saveMe.hasOwnProperty(prop)) continue;
localStorage.setItem(prop, saveMe[prop]);
}
}

Categories