Get last value from an array using Google Apps Script - javascript

I need to get last value from an array and I keep getting this error when I use slice
TypeError: Cannot find function slice in object Sun Jul 23 2017 00:00:00 GMT+0100 (BST). (line 15, file
If I use length -1 I get NaN.
This is the code I am using it.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Data");
var range = sheet.getDataRange();
var values = range.getValues();
var today = new Date(Date.now());
today.setHours(0,0,0,0);
Logger.log(today);
var setTotal;
var getToday = values[4].map(Number).indexOf(+today);
Logger.log(getToday);
for (i = 0; i < values.length; i++) {
var getTotal = values[i][getToday];
Logger.log(getTotal.slice(-1)[0]);
}
}
... and this is the table
full table
So I need when it match the current day (today) to retrieve last value from that array (column) which is the Total for that day.
Thank you!
Kind regards,

getTotal is always already a singular value.
Also the way you find your column is brittle due to timezones because you normalize only one date.
If you do it with both dates (which needs to be handled safely unless you want to do index constraints) your column finding approach works.
function getTodaysTotal() {
function toUtcMidnight(date) {
try {return date.setHours(0,0,0,0);}
catch(e) {return;}
}
var values = SpreadsheetApp
.getActiveSpreadsheet()
.getSheetByName("Data")
.getDataRange()
.getValues();
var today = toUtcMidnight(new Date());
var todaysColumn = values[4].map(toUtcMidnight).map(Number).indexOf(+today);
var output = values[values.length - 1][todaysColumn];
return values[values.length - 1][todaysColumn];
}

You can use the method .pop() that returns and removes the last element from an array.
Make a copy of the original array first and use .pop() method and assign it to a new value.
var myArray = myArrayCopy
var lastArrayObject = myArrayCopy.pop()

Related

App Script COUNTIF for maximum date in column

I have a list of dates in column A:
Column A
2022-02-28
2022-02-28
2022-02-28
2022-02-14
2022-02-14
2022-02-07
I'm trying to write a script that counts the number of times the largest date occures. I wrote the below script
function maxcount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var devdeploy = ss.getSheetByName("Sheet1")
var Avals = devdeploy.getRange("A2:A").getValues();
var Alength = Avals.filter(String).length;
var max = Avals[0][0]
var unique_count = 0
for (i=0; i < Alength; i++){
if (Avals[i][0] == max){
unique_count++;
}
}
Logger.log(unique_count)
}
This script works if I use integer values and have the maximum value in cell A2. However, when I use dates instead of integers it always returns a value of 1. Any ideas on why the if loop does not work on dates, but works on integers/strings? Also is there a way to improve the script to look for the maximum value in column A then find how many times it occurs?
If your date in the column "A" is the date object, how about the following modification? I thought that in your script, by var max = Avals[0][0], only 1st element is compared. And, if the values of column "A" are the date object, the date object is compared. I thought that this might be the reason for your issue.
Modified script:
function maxcount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var devdeploy = ss.getSheetByName("Sheet1")
var Avals = devdeploy.getRange("A2:A" + devdeploy.getLastRow()).getValues().filter(([a]) => a.toString() != "");
var values = Avals.map(([a]) => a.getTime());
var max = Math.max(...values);
var unique_count = values.filter(v => v == max).length;
console.log(unique_count)
}
In this modification, the values are converted to the unix time, and retrieved the maximum value. And, the number of the maximum value can be retrieved.
References:
map()
filter()

Jump to current date cell (dates are in one row) Google Sheets

I have a google sheets spreadsheet. Row 2 contains dates e.g. 25/08/2020, 26/08/2020 going across many columns. Is there a script I can run to make it jump to the cell containing the current date when the document is first opened?
I know there is OnOpen() method which you define and it runs on opening the document, however, it is getting the code that actually works that's proving difficult.
Note: I have looked at Google spreadsheet / docs , jump to current date cell on Open but the solutions don't work (I assume due to me having my dates all in one row).
I don't know javascript really well, I understand a little of the basics. Any help would be much appreciated.
Thanks
The code you found at Google spreadsheet / docs , jump to current date cell on Open does not work for you as it only checks the first column.
I modified this code a little to search for dates on a row. Change rowWithDates variable as needed.
function onOpen() { // runs automatically
var rowWithDates = 2; // change as needed
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var range = sh.getDataRange()
var data = range.getValues();
var today = new Date().setHours(0,0,0,0);
var diffref = today;
var diff;
var idx;
for(var n=0;n<range.getWidth();n++){
var date = new Date(data[rowWithDates-1][n]).setHours(0,0,0,0);
diff=today-date;
if(diff==0){break}
Logger.log("diffref = "+diffref+" today-date = diff = "+diff);
if(diff < diffref && diff > 0){idx=n ; diffref=diff}
}
if(n==data.length){n=idx}
n++;
sh.getRange(rowWithDates, n).activate();
}
You can use the code that was provided in the answer you cited in your question, you just need to change a couple of things:
Make it look in a row, rather than a column (note that the data array is changing the second array dimension, rather than the first); and
Make it look in a specific row, rather than just hardcoded to the first (you could just, instead of 0, have the array use a variable "row"; instead, I just had the code pull the data for only the row with dates - this is faster for very large spreadsheets).
function onOpen() {
var row = 8; //set this to be the row with the dates
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getActiveSheet();
var data = sh.getDataRange();
var datesrow = sh.getRange(row,data.getColumn(),row,data.getWidth()).getValues();
var today = new Date().setHours(0,0,0,0);
for(var n=0;n<datesrow[0].length;n++){
var date = new Date(datesrow[0][n]).setHours(0,0,0,0);
if(date==today){break};
}
console.log(n);
n++;
sh.getRange(row,n).activate();
}
Solution:
While the other solutions might work for now, when working with Dates is recommended to consider display values instead. It is also highly recommended to get rid of old for loops and var declarations.
This will be a more futureproof solution:
function onOpen() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh =ss.getActiveSheet();
const today = new Date();
const today_year= today.getFullYear();
const today_month = addZero(today.getMonth()+1);
const today_day = addZero(today.getDate());
const today_date = today_day.toString() + "/" + today_month.toString() + "/" + today_year.toString();
function addZero(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
const dates = sh.getRange(2,1,1,sh.getLastColumn()).getDisplayValues().flat(1);
dates.forEach((d,index)=>{
if (d===today_date){
sh.getRange(2,index+1).activate();}});
}
References:
getDisplayValues()

Unable to sort array of dates pulled from innerText

I’m currently trying to pull dates from the DOM (formatted as 1563595200) into an array in Javascript. The next step is to sort the array properly from closest date to farthest away and cannot figure it out.
Example of element:
<span class="meta-item date">1563595200</span>
Javascript:
var className = document.getElementsByClassName('date');
var classnameCount = className.length;
var IdStore = new Array();
for(var j = 0; j < classnameCount; j++){
var dateString = className[j].innerText;
IdStore.push(dateString);
}
console.log(IdStore);
var IdStore = IdStore.sort(function(a,b){
// Turn your strings into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(b.date) - new Date(a.date);
});
console.log(IdStore);
}
storeid();
I expect it to be sorted from nearest date to farthest away but the sorting function isn't doing anything.
You should not be re-declaring a variable here. Remove the var keyword when you are assigning the sort function to IdStore
IdStore = IdStore.sort(function(a,b){

Can't convert Array to Object[][] error

I'm trying to make a simple script in google doc, but when I run it stops at line 15 with error as in the title. It works if only I remove that line. Can you help me please?
function influencer_update() {
var sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Influencer');
var dzis = sheet1.getRange('O1').getValue(); //today date
var lista = sheet1.getRange('Q2:Q').getValues(); //list of values
var lista_st = sheet1.getRange('D2:D').getValues(); //list of values to update
var daty = sheet1.getRange('O2:O').getValues(); //list of dates, when value was last update
for (i in lista) {
if (lista[i]>0) {
lista_st[i]=lista[i]
daty[i] = dzis
}
}
sheet1.getRange('D2:D').setValues(lista_st);
sheet1.getRange('O2:O').setValues(daty);
Browser.msgBox('daend');
}
I believe setValues() and getValues() always uses 2d array. When you do daty[i] = dzis, it converts daty to 1d array. Hence it gives you the error message Can't convert Array to Object[][]. If you change the line
daty[i] = dzis
to
daty[i][0] = dzis
or
daty[i] = [dzis]
should fix the problem.

Sorting an array in javascript based on date

I'm trying to parse multiple subreddit feeds in a Google Script. I can call this Google Script (redditFeeds()) and it returns the title, link, and date to my spreadsheet. However, I want to sort the posts by date so I can see the most recent posts first. I've tried using sort() on the array in various ways and can't get anything sort by descending date. I've even tried converting the date to a Date object and that didn't fix it.
function redditFeeds() {
var entries_array = [];
var subreddit_array = ['https://www.reddit.com/r/funny/top/.rss','https://www.reddit.com/r/news/top/.rss']
for (var s = 0; s < subreddit_array.length; s++) {
var xml = UrlFetchApp.fetch(subreddit_array[s]).getContentText();
var document = XmlService.parse(xml);
var root = document.getRootElement();
var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
var entries = document.getRootElement().getChildren('entry', atom);
for (var i = 0; i < entries.length; i++) {
var title = entries[i].getChild('title', atom).getText();
var title = entries[i].getChild('link', atom).getText();
var link = entries[i].getChild('link', atom).getAttribute('href').getValue();
var date = entries[i].getChild('updated', atom).getValue();
entries_array.push([title, link, date]);
}
}
//return entries_array;
//doesn't work
//entries_array.sort(function(a,b) {
// return a.date - b.date;
//});
//also not working
return entries_array.sort(function(a,b) {
new Date(a.date).getTime() - new Date(b.date).getTime();
});
}
I think you want the below, assuming entries_array looks like I think it does. I have no idea what start was supposed to be in your code... I think each entry in entries_array is an array with three members in it, the third being some sort of representation of a date. If it's one that can be parsed by new Date, then this code should work:
return entries_array.sort(function (a, b) {
return new Date(a[2]) - new Date(b[2]);
});
If that's not right, please share what entries_array looks like.
I see a return missing, in the inner sort function and you should not need the getTime()
return entries_array.sort(function(a,b) {
return new Date(a.start) - new Date(b.start);
});
An easy way of sorting date objects is by converting them into UNIX time stamps using dateObj.getTime(). This creates an integer of the seconds since midnight on New Years day 1970. It's very useful if you are working in multiple time zones.

Categories

Resources