I'm trying to display a graph with Flot. My data array does not have a date set if there is no value for that date. I've followed the accepted answer in this question to 'fill in the gaps', but I now want the value to be the last value, and not 0. I can't get my head around how to get the previous date's value. I've tried getting the previous value with var previousTotal = date[i][1];, but I can't seem to get the right part of the array no matter what I try.
Can anyone help please?
function fillInGapsAdding(data) {
var startDay = data[0][0],
newData = [data[0]];
// Loop through all items in array
for (i = 1; i < data.length; i++) {
var diff = dateDiff(data[i - 1][0], data[i][0]);
var startDate = new Date(data[i - 1][0]);
if (diff > 1)
{
for (j = 0; j < diff - 1; j++)
{
var fillDate = new Date(startDate).setDate(startDate.getDate() + (j + 1));
var previousTotal = date[i][1];
newData.push([fillDate, 0]);
}
}
newData.push(data[i]);
}
return newData;
}
After a bit more work, I figured it out....
var previousTotal = data[i][1];
Related
I am trying to create a counter that counts the cells that include in their content the date before today as a date. However the result in cell 16,1 is always zero as it seems that my loop does not work. I know I can do it with a formula in spreadsheets but I want to use javascript. Also I am trying to find out what is wrong in MY code.
I have wrirtten the following lines of code:
function job_counter() {
var yesterday_jobs=0;
var ss=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var e = new Date(new Date().getFullYear(),new Date().getMonth() , new Date().getDate())
var yesterday = new Date(new Date().getFullYear(),new Date().getMonth() , new Date().getDate())
yesterday.setDate(yesterday.getDate() - 1);
var range_unformated=ss.getRange(2,3,25).getValues()
var date;
for (var i=1; i<25; i++){
date=Date.parse(range_unformated[i])
Logger.log(date[3])
if ( date[i] - yesterday.getTime() >= 0 && date[i] != "" ){
yesterday_jobs = yesterday_jobs + 1
ss.getRange(16,2).setValue(yesterday_jobs)
}}
// check yesterday_jobs
}
This will solve your problem, it uses getValues getting a range of 24x24 cells and iterating it to compare every cell value to see if it is equal to yesterday:
function isYesterday(){
var yesterday_jobs=0;
var ss=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var row=0;
var col=0;
var date;
var yesterday = new Date(new Date().getFullYear(),new Date().getMonth() , new Date().getDate())
yesterday.setDate(yesterday.getDate() - 1);
range = ss.getRange(1,1,25,25).getValues()
for (var i = 0; i < 25; i++){
for ( var j = 0; j < 25; j++) {
date = Date.parse(range[i][j]);
if ( date - yesterday.getTime() <= (24 * 60 * 60 *1000) ){
yesterday_jobs = yesterday_jobs + 1;
}
}
}
ss.getRange(16,2).setValue(yesterday_jobs);
}
Things that were wrong...
This is wrong and it is the reason it's not working:
yesterday_jobs === yesterday_jobs + 1;
You should be doing:
yesterday_jobs = yesterday_jobs + 1
Why?
Because == and === are Comparison operators, and = is an assignment operator.
What you are trying to do is to set a new value to yesterday_jobs, not to compare it, so you have to use =.
This will solve your problems with the loop assignations.
When doing a = 2 you are assigning a value to a variable:
a value is now equal to 2 value
When doing a == 2 you are asking:
Is a equal to 2 in value?
When doing a === 2 you are asking
Is a equal to 2 in value and type?
The example below shows how to retrieve and log the items names and items numbers.
function logItemstInfo() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
Logger.log('Items name: ' + data[i][0]);
Logger.log('Items number: ' + data[i][1]);
}
}
I have problem with this code. If I print item of daysArray in for loop (console.log(daysArray[i]);) it returns right date, but after for loop returns last date at all daysArray items.
Please some could help me.
public getFullMonth(date: Date): Array<Date> {
var firstDay = this.getSunday(date);
var daysArray: Array<Date> = Array<Date>();
for (var i = 0; i < 43; i++) {
firstDay.setDate(firstDay.getDate() + 1);
daysArray[i] = firstDay;
console.log(daysArray[i]);
}
console.log(daysArray.length);
console.log(daysArray[0]);
console.log(daysArray[30]);
return daysArray;
}
The problem is that you always use the same instance of Date, you never create a new one, so all of the items in daysArray are the same exact instance.
Because of that, when you do:
firstDay.setDate(firstDay.getDate() + 1);
Then you actually change the value for all items.
You should create a new instance for every item:
public getFullMonth(date: Date): Array<Date> {
var firstDay = this.getSunday(date);
var daysArray: Array<Date> = Array<Date>();
for (var i = 0; i < 43; i++) {
firstDay = new Date(firstDay.getTime());
firstDay.setDate(firstDay.getDate() + 1);
daysArray[i] = firstDay;
console.log(daysArray[i]);
}
console.log(daysArray.length);
console.log(daysArray[0]);
console.log(daysArray[30]);
return daysArray;
}
Notice that each iteration now does:
firstDay = new Date(firstDay.getTime());
Which creates a new instance of Date which is a "clone" of the previous one.
Your problem is easy to solve. You are just copying the same item in each position of the array. These means you are overriding the value you set in each step of the for loop.
Just create a new object for each position of the array and you won't have the error any more. Something like this
for (var i =0; i < 43; i++) {
var nDay = new Date();
nDay.setDate(firstDay.getDate() + i + 1);
daysArray[i] = nDay;
console.log(daysArray[i]);
}
So I need to take a date and convert it into one single number by adding up each digit, and when the sum exceeds 10, I need to add up the two digits. For the code below, I have 12/5/2000, which is 12+5+2000 = 2017. So 2+0+1+7 = 10 & 1+0 = 1. I get it down to one number and it works in Firebug (output of 1). However, it is not working in a coding test environment I am trying to use, so I suspect something is wrong. I know the code below is sloppy, so any ideas or help reformatting the code would be helpful! (Note: I am thinking it has to be a function embedded in a function, but haven't been able to get it to work yet.)
var array = [];
var total = 0;
function solution(date) {
var arrayDate = new Date(date);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
array.push(d,m+1,y);
for(var i = array.length - 1; i >= 0; i--) {
total += array[i];
};
if(total%9 == 0) {
return 9;
} else
return total%9;
};
solution("2000, December 5");
You can just use a recursive function call
function numReduce(numArr){
//Just outputting to div for demostration
document.getElementById("log").insertAdjacentHTML("beforeend","Reducing: "+numArr.join(","));
//Using the array's reduce method to add up each number
var total = numArr.reduce(function(a,b){return (+a)+(+b);});
//Just outputting to div for demostration
document.getElementById("log").insertAdjacentHTML("beforeend",": Total: "+total+"<br>");
if(total >= 10){
//Recursive call to numReduce if needed,
//convert the number to a string and then split so
//we will have an array of numbers
return numReduce((""+total).split(""));
}
return total;
}
function reduceDate(dateStr){
var arrayDate = new Date(dateStr);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
return numReduce([d,m+1,y]);
}
alert( reduceDate("2000, December 5") );
<div id="log"></div>
If this is your final code your function is not outputting anything. Try this:
var array = [];
var total = 0;
function solution(date) {
var arrayDate = new Date(date);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
array.push(d,m+1,y);
for(var i = array.length - 1; i >= 0; i--) {
total += array[i];
};
if(total%9 == 0) {
return 9;
} else
return total%9;
};
alert(solution("2000, December 5"));
It will alert the result in a dialog.
Let's say I have an array of N dates:
var dates = ['2013-01-01', '2013-01-02', '2013-01-05' ...]
What is the quickest way to find all the missing dates between the first date and the last? (let's assume that the dates are sorted from earliest to latest).
The gap is not consistent and could be at any size.
I rather not use any libraries, just pure javascript.
Generally if you have two sorted arrays and want to find the items in one missing from the other you would iterate over both in paralel. My solution is similar to that one, but uses a generator over the date array:
function DateIterator(date){
this.current = date;
}
DateIterator.prototype.next = function() {
this.current.setDate(this.current.getDate() + 1);
return this.current.getFullYear() + '-' +
(this.current.getMonth()+1) + '-' +
this.current.getDate();
};
var dates = ['2013-1-1', '2013-1-2', '2013-1-5' ,'2013-2-2'];
var di = new DateIterator(new Date(dates[0]));
var date, missing = [];
for (var i=1; i<dates.length; i++) {
while ((date = di.next()) !== dates[i]) {
missing.push(date);
}
}
console.log(missing);
Note that the check for dates is made by comparing the string values. The dates returned by next are not 0-padded so a comparison between 2013-01-01 and 2013-1-1 would fail. This can be solved by making a smarter comparison function, but i consider it beyond the scope of the question.
I would do a date diff, and generate new dates for any missing ones, like this:
var dates = [new Date(2013,1,1), new Date(2013,1,2), new Date(2013,1,5)];
var missingDates = [];
for (var i = 1; i < dates.length; i++)
{
var daysDiff = ((dates[i] - dates[i - 1]) / 86400000) - 1;
for (var j = 1; j <= daysDiff; j++)
{
var missingDate = new Date(dates[i - 1]);
missingDate.setDate(dates[i - 1].getDate() + j);
missingDates.push(missingDate);
}
}
console.log(missingDates);
JSFiddle
First of all thank you for the efforts made in this site. As an individual and a beginner i have learnt from my errors made. Thanks for all who have contributed & extended their support.
Thanks for this.
Here is a small program written which is not working (no output)seen , i have tried it in many ways but in vain. please help me to find a solution for this.
the aim of this program was to filter the data from 4 sheets and paste into current sheet (master). this filter is based on date values.
Conditions of dates are taken from the master sheet in columns in (b2 & d2)dates. this are to be filtered out based in column no.18 which has dates in client sheets.
function myFunction3() {
var source = ['0AjkkHlm3kCphdGhSWnlxWmFsakZ2aFhMSHl6SlF3M1E',
'0AjkkHlm3kCphdHY2aXpjTVJEMlFRYVBST0ZPYzNwRFE',
'0AjkkHlm3kCphdEc5ZHFpeHVlc241SlFKWGJDeXFKLXc',
'0AjkkHlm3kCphdG9WVjVRRnQ3RlFlcllhd1JGallXVmc'];
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get start date from sheet
var sDate = ss.getSheetByName('123').getRange("B2").getValue();
// get end date from sheet
var eDate = ss.getSheetByName('123').getRange("D2").getValue();
// days between
var Dura = ss.getSheetByName('123').getRange("E1").getValue();
var codes = new Array();
for (var k = 0; k < Dura; k++){
var d = new Date(sDate);
d.setDate(d.getDate()+ k);
codes[k] = d;
}
var numCodes = codes.length;
var copied = [];
for (var k = 0; k < numCodes; k++) {
copied[k] = [];
}
//get data from external sheets for comparision
for (var i = 0; i < source.length; i++) {
var tempCopy = SpreadsheetApp.openById(source[i]).getSheetByName('Footfall-Format').getDataRange().getValues();
// comparision starts
for (var j = 0; j < tempCopy.length; j++) {
var codeIndex = codes.indexOf(tempCopy[j][5]);
if (codeIndex > -1) copied[codeIndex].push(tempCopy[j]);
}
}
var sheets = SpreadsheetApp.getActive().getSheets();
for (var m = 0; m < numCodes; m++) {
if (copied[m][0] != undefined) {
var gensheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('123');
gensheet.getRange(5, 1, 1500, 18).clear({contentsOnly:true});
gensheet.getRange(5, 1, copied[m].length, copied[m][0].length).setValues(copied[m]);
}
}
}
The fundamental problem is that you are comparing objects for equality - in this case, you're comparing Date objects. Even when the date represented by two of these objects is the same, the object comparison comes up false unless you're actually referencing the same object. You can read more about this in Compare two dates with JavaScript.
Here's a simple change to your script, using toDateString(), that will ensure your codes[] array contains string values that can be compared with values in tempCopy[j][5].
function myFunction3() {
var source = ['0AjkkHlm3kCphdGhSWnlxWmFsakZ2aFhMSHl6SlF3M1E',
'0AjkkHlm3kCphdHY2aXpjTVJEMlFRYVBST0ZPYzNwRFE',
'0AjkkHlm3kCphdEc5ZHFpeHVlc241SlFKWGJDeXFKLXc',
'0AjkkHlm3kCphdG9WVjVRRnQ3RlFlcllhd1JGallXVmc'];
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get start date from sheet
var sDate = ss.getSheetByName('123').getRange("B2").getValue();
// get end date from sheet
var eDate = ss.getSheetByName('123').getRange("D2").getValue();
// days between
var Dura = ss.getSheetByName('123').getRange("E1").getValue();
var codes = new Array();
for (var k = 0; k < Dura; k++){
var d = new Date(sDate);
d.setDate(d.getDate()+ k);
codes[k] = d.toDateString(); //***** Make array of Strings, not Dates
}
var numCodes = codes.length;
var copied = [];
for (var k = 0; k < numCodes; k++) {
copied[k] = [];
}
//get data from external sheets for comparision
for (var i = 0; i < source.length; i++) {
var tempCopy = SpreadsheetApp.openById(source[i]).getSheetByName('Footfall-Format').getDataRange().getValues();
// comparision starts
for (var j = 4; j < tempCopy.length; j++) { // start at 4 to skip headers
if (typeof tempCopy[j][5] != "object") break; // skips strings, but could improve
// Search for String match of date from input record
var codeIndex = codes.indexOf(tempCopy[j][5].toDateString());
if (codeIndex > -1) copied[codeIndex].push(tempCopy[j]);
}
}
// This part has bugs... each day overwrites the previous
var sheets = SpreadsheetApp.getActive().getSheets();
for (var m = 0; m < numCodes; m++) {
if (copied[m][0] != undefined) {
var gensheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('123');
gensheet.getRange(5, 1, 1500, 18).clear({contentsOnly:true});
gensheet.getRange(5, 1, copied[m].length, copied[m][0].length).setValues(copied[m]);
}
}
}
As #Serge points out, there are other problems in this code.
d.getDate()+ k does not handle month-end, so you need to do that yourself.
The last part of your script that handles the output via setValues() needs to be debugged. As it is, each day overwrites the previous day's values from the copied[] array. I'm not sure what requirement you were trying to meet with this, so I left it alone, but it needs attention.