query.setquery to current day with Google Apps Script - google-apps-script

I'm trying to create a Google Chart to Google Apps Script using a formula that already exists.
this formula works fine in the spreadsheet:
=query(A:A; "select A where A >= datetime '"&TEXT(today();"yyyy-MM-dd HH:mm:ss")&"'";-1)
this code doesn't work to Google Apps Script as intended:
query.setQuery("select A, B Where A >= toDate( now() )");
var query = new
google.visualization.Query('https://docs.google.com/spreadsheets/d/key');
query.setQuery("select A, B Where A = date '" + nowone + "'");
var nowone = getNowDate();
query.send(handleQueryResponse);
}
function getNowDate(){
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var date = date.getDate();
if (month < 10) {
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
var strDate = String(year + "-" + month + "-" + date + " 00:00:00");
return strDate;
}
I've tried many times without success to replicate the formula to Google Apps Script.
thanks in advance...

I tried the query in the Spreadsheet and was able to get the expected results.
When coming to your code there are two things to be changed.
First one is you are calling the nowone variable before it is set to some value. For that you can just add that statement before the set query.
The second thing I found is that I instead of date in the query you should give datetime.
Please find the below code for reference:
function drawDashboard() {
var query = new google.visualization.Query(
'https://docs.google.com/spreadsheets/d/key/edit#gid=0');
var nowone = getNowDate();
//alert(nowone);
//query.setQuery("select A, B Where A >= toDate( now() )");
query.setQuery("select A,B where A >= datetime '"+nowone+"'");
query.send(handleQueryResponse);
}
In order to set the query using visualization class, you have to
1. Add this code in html file in apps script console.
2. create HTML output from file.
3. Then Deploy this as a webapp.
Tried this code below to get the data from query:
index.html:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
var data ;
// Load the Visualization API and the controls package.
google.load('visualization', '1.0', {'packages':['controls']});
// Set a callback to run when the Google Visualization API is loaded.
google.setOnLoadCallback(drawDashboard);
// Callback that creates and populates a data table,
// passes in the data and draws it.
function drawDashboard() {
var query = new google.visualization.Query(
'https://docs.google.com/spreadsheets/d/key/edit#gid=0');
var nowone = getNowDate();
//alert(nowone);
//query.setQuery("select A, B Where A >= toDate( now() )");
query.setQuery("select A,B where A >= datetime '"+nowone+"'");
query.send(handleQueryResponse);
}
function getNowDate(){
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var date = date.getDate();
if (month < 10) {
month = "0" + month;
}
if (date < 10) {
date = "0" + date;
}
var strDate = String(year + "-" + month + "-" + date + " 00:00:00");
return strDate;
}
function handleQueryResponse(response) {
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
data = response.getDataTable();
// Create a dashboard.
alert(data);
}
</script>
</head>
code.gs:
function doGet() {
var html = HtmlService.createHtmlOutputFromFile('index');
html.setSandboxMode(HtmlService.SandboxMode.IFRAME);
return html;
}
When I access the webapp, I was able to see that the response is returning some object. In the handleQueryResponse(response) function you could add some more code to create a chart or a table for the returned data.
You can refer to this documentation for creating table for the data values. Hope that helps!

Related

Frozzen date After entering data in google sheet

Hello dear community,
I want to froze the date( Now function) when the data has been entred in an other cell.how its possible ??
Many thanks.
I entred this function : If(A1=0,today(),now())
I tried also this script:
function TIMESTAMP() {
var today = new Date();
var date = (today.getMonth()+1)+'-'+today.getDate()+'-'+today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
return dateTime;
}
But date change every time

How do I compare Times in Google Apps Script

I am trying to create a filter on a list based on a given time interval (2 cells in my spreadsheet which will input a timestamp C4 and C5). I have scoured the internet for a while and found out that the Javascript code used in Google Apps Script is different from the usual Javascript, so I haven't found a usable code snippet for my case.
The code is something like this:
var beginningTimeValue = new Date('2020-01-01 ' + ss.getRange("C4").getValue());
var endingTimeValue = new Date('2020-01-01 ' + ss.getRange("C5").getValue());
if(!beginningTimeValue == ""){
Logger.log(beginningDateValue);
unique = unique.filter(function(row)
{
const bTime = Date.parse(row[4]);
Logger.log(bTime);
Logger.log(beginningTimeValue);
return bTime.getTime() >= beginningTimeValue.getTime();
}
);
}
The value in row[4] is of DateTime value ("12/01/2021 00:03:35" for example). How do I filter this row out if I want the time to be between 08:00:00 and 13:00:00?
Three points:
To filter by two conditions instead of one, simply combine the two conditions with an && operator.
So:
return bTime.getTime() >= beginningTimeValue.getTime(); && bTime.getTime() <= endingTimeValue.getTime()
instead of
return bTime.getTime() >= beginningTimeValue.getTime();
Do not use both Date.parse() and getTime() simultaneously, since they both do the same.
const bTime = Date.parse(row[4]);
already returns you a timestamp in ms, if you try to apply
bTime.getTime()
on it - this will result in an error.
Be careful with
Logger.log(beginningDateValue);
given that your variable is called beginningTimeValue and not beginningDateValue.
Sample
Provided that beginningTimeValue, endingTimeValue and unique look like the harcoded values below, the following code snippet will work correctly for you:
function myFunction() {
var beginningTimeValue = new Date('2020-01-01 08:00:00');
var endingTimeValue = new Date('2020-01-01 13:00:00');
var unique = [["value","value","value","value","12/01/2021 00:03:35","value"],["value","value","value","value","01/01/2020 00:03:35","value"], ["value","value","value","value","01/01/2020 08:03:35","value"], ["value","value","value","value","01/01/2020 13:03:35","value"]]
if(!beginningTimeValue == ""){
Logger.log(beginningTimeValue);
unique = unique.filter(function(row)
{
const bTime = Date.parse(row[4]);
Logger.log(bTime);
Logger.log(beginningTimeValue);
return bTime >= beginningTimeValue.getTime() && bTime <= endingTimeValue.getTime();
}
);
console.log("unique: " + unique)
}
}
UPDATE
If you want to compare the times only (not the dates), you need to hardcode the date of row[4] to the same value like in beginningTimeValue and endingTimeValue. For this you can use the methods setDate(), setMonth and setYear.
Also, if your code should only work base don either vlaues are provided by a user in the cells C4 and C5 - you should adapt your code accordingly.
Be careful with your conditional statements: Even if ss.getRange("C4").getValue() is an empty string or an invalid input - beginningTimeValue will still not be an empty string, but rather the beginning of Unix time.
Sample:
function myFunction() {
var beginningTimeValue = new Date('2020-01-01 ' + ss.getRange("C4").getValue());
console.log("beginningTimeValue: " + beginningTimeValue)
var endingTimeValue = new Date('2020-01-01 ' + ss.getRange("C5").getValue());
console.log("endingTimeValue: " + endingTimeValue)
var unique = [["value","value","value","value","12/01/2021 00:03:35","value"],["value","value","value","value","01/01/2020 00:03:35","value"], ["value","value","value","value","01/01/2020 08:03:35","value"], ["value","value","value","value","01/01/2020 13:03:35","value"]]
if(!ss.getRange("C4").getValue() == ""){
Logger.log("beginningTimeValue: " + beginningTimeValue);
unique = unique.filter(function(row)
{
const bTime = new Date(row[4]);
bTime.setYear(2020);
// Be careful - months start in Javascript with 0!
bTime.setMonth(0);
bTime.setDate(1);
Logger.log(bTime);
if(ss.getRange("C5").getValue() != ""){
return bTime >= beginningTimeValue.getTime() && bTime <= endingTimeValue.getTime();
}
else{
return bTime >= beginningTimeValue.getTime();
}
}
);
console.log("unique: " + unique)
}
}
Keep im mind that Stackoverflow is not there to provide you a complete solution, but rather to help you troubleshooting and provide you references and samples that will guide you in the right direction. This will allow to incorporate the necessary modification into your code. You still need to have some basic understanding about coding to apply the sample to your script correctly.

Run a Google Script only weekdays every hour, between certain hours - using time-based trigger?

I have a Google Sheets spreadsheet and a script needs to update it automatically.
Need to run a Google Script only weekdays, every hour, between certain hours - using time-based trigger?
Thus run script Monday to Friday from 8am to 5pm, every hour.
Just add a condition that stops execution if the day is Saturday or Sunday OR the hour is before 8 or after 17.
function myFunction () {
var today = new Date();
var day = today.getDay();
var days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
if(day == 6 || day == 0) {
message.innerHTML = 'Today is ' + days[day] + '. So I\'ll do nothing'
return;
} else {
var hour = today.getHours();
var minute = today.getMinutes();
if(hour < 8 || hour > 17) {
message.innerHTML = 'Today is ' + days[day] + ' but the time is ' + hour + ':' + minute + '. So I\'ll do nothing'
return;
}
message.innerHTML = 'Today is ' + days[day] + ' and the time is ' + hour + ':' + minute + '. So I\'ll do something'
}
}
myFunction()
<span id="message"></span>
With this implementation, you just need to create a trigger to run the function once per hour. The condition in the if statements will make sure that any code written below that will not run if it doesn't meet your runtime criteria.
This is what I was trying but not working...
function setWeekdaysTrigger() {
var startHour = 8;
var endHour = 17;
var daysWeek = []; //put Enums for days of the week here;
//set trigger to specific week days;
daysWeek.forEach(function(day){
//set trigger for 9AM to 13PM;
for(var h=startHour; h<endHour; h++) {
var tg = ScriptApp.newTrigger('TheScriptToRun').timeBased();
tg.onWeekDay(day);
tg.atHour(h).nearMinute(1).create(); //arbitrary precision (minutes);
}
});
}

Create a Unique Sequential ID Generator - Google Scripts

I am attempting to find a way to create a google scripts function that will create unique sequential ID generator after looking through my google sheets document verifying that it will be a unique ID. I found this answer https://stackoverflow.com/a/58515330/14143011 which is exactly what I need however I do not want the ID to be inserted into the google sheet automatically, as I want to be able to use the ID in another function I am working on. When it comes to the date I am using this google scripts function to retrieve the current date:
const timezone = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
function datestamp() {
var datestamp_format = "yyyy-MM-dd";
return Utilities.formatDate(new Date(), timezone, datestamp_format);
}
To clarify what I am attempting to do, I have this function which creates folders for files I am uploading:
function createSubfolder(){
var dropbox = Utilities.formatDate(new Date(), "US/Eastern", "_yyyy-MM-dd");
I want to change the name to also contain the generated ID. I want the 'createSubfolder' function to call the function that generates the ID and return it to a variable such as this:
function createSubfolder(){
var generatedID = idGeneratorFunction()
var dropbox = generatedID + Utilities.formatDate(new Date(), "US/Eastern", "_yyyy-MM-dd");
Thank you!
The solution writes the ID using this statement
sheet.getRange(2, indexId + 1, newId.length).setValues(newId);
Just comment it out and change the customer function to return the ID and then you can use it however you like.
Recommended solution:
Instead of setting the newID value into the sheet via sheet.getRange(2, indexId + 1, newId.length).setValues(newId), you can pass the newID value to the createSubfolder function through a parameter. Just edit last lines of the autoid_(sheet) function and call your createSubfolder(newId) function as seen below:
UPDATED
See this edited full script below from the referenced post:
/**
*
* #param {GoogleAppsScript.Spreadsheet.Sheet} sheet
*/
function autoid_(sheet) {
var data = sheet.getDataRange().getValues();
if (data.length < 2) return;
var indexId = data[0].indexOf('ID');
var indexDate = data[0].indexOf('DATE');
if (indexId < 0 || indexDate < 0) return;
var id = data.reduce(
function(p, row) {
var year =
row[indexDate] && row[indexDate].getTime
? row[indexDate].getFullYear() % 100
: '-';
if (!Object.prototype.hasOwnProperty.call(p.indexByGroup, year)) {
p.indexByGroup[year] = [];
}
var match = ('' + row[indexId]).match(/(\d+)-(\d+)/);
var idVal = row[indexId];
if (match && match.length > 1) {
idVal = match[2];
p.indexByGroup[year].push(+idVal);
}
p.ids.push(idVal);
p.years.push(year);
return p;
},
{ indexByGroup: {}, ids: [], years: [] }
);
// Logger.log(JSON.stringify(id, null, ' '));
var newId = data
.map(function(row, i) {
if (row[indexId] !== '') return [row[indexId]];
if (isNumeric(id.years[i])) {
var lastId = Math.max.apply(
null,
id.indexByGroup[id.years[i]].filter(function(e) {
return isNumeric(e);
})
);
lastId = lastId === -Infinity ? 1 : lastId + 1;
id.indexByGroup[id.years[i]].push(lastId);
return [
Utilities.formatString(
'%s-%s',
id.years[i],
('000000000' + lastId).slice(-3)
)
];
}
return [''];
})
.slice(1);
//Instead of setting the value on sheet, add createSubfolder function below:
createSubfolder(newId);// Pass the newID value to the createSubfolder() parameter (inside the parenthesis) to "generatedID" as seen
}
function createSubfolder(generatedID){ // Edit your createSubfolder function with a parameter named generatedID (inside the parenthesis)
var dropbox = generatedID + Utilities.formatDate(new Date(), "US/Eastern", "_yyyy-MM-dd");
}

Unable to concatenate in google scripts

I am new to writing scripts and I was experimenting.
I want to add time stamp along with the string.
const sheet = SpreadsheetApp.openByUrl(SHEET_URL).getSheetByName(
SHEET_NAME
);
const [header] = sheet.getRange('A1:1').getValues();
const STATUS = header.indexOf('Status');
var rowId = Number(e.parameter.row);
var date = new Date()
sheet.getRange(rowId + 1, STATUS + 1).setValue("Data Sent- " + date);
however, all I am getting the Status Column is Data Sent- and no time stamp.
please help where am i going wrong.
Thanks in advance.
You should convert the date to a string first, like this:
var date = new Date();
var timezone = 'GMC';
var format= 'YYYY-mm-dd';
var formatted_date = Utilities.formatDate(date,timezone , format);
sheet.getRange(rowId + 1, STATUS + 1).setValue("Data Sent- " + formatted_date);
Reference: GAS Utilities Format Date