I have a range of dates in plain text format (must stay this way) and I need to clear them at 1am if the date in each range cell is less than the current date. I can set up the run schedule later, but can anyone tell me why this isn't working?
I'm using =TEXT(TODAY(),"m/dd") to insert the current date in the correct format in cell AE3.
Thank you!
function clearOldDate()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Loads");
var cells = sheet.getRange('AC9:AE33').getValues();
var data = [cells];
var date = sheet.getRange('AE3').getValues();
//var Sdate = Utilities.formatDate(date,'GMT+0900','MM/dd');
for(i=0; i<76; i++)
{
if (date > data[i])
{
data[i].clear();
};
};
};
This should do the trick
function clearOldDate()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("LogSheet");
//getValues gives a 2D array.
var data = sheet.getRange('AC9:AE33').getValues();
var date = sheet.getRange('AE3').getValues();
//var Sdate = Utilities.formatDate(date,'GMT+0900','MM/dd');
//This for loop with loop through each row
for(i=0; i<data.length; i++)
{
//This for loop with loop through each column
for (var j = 0; j < data[i].length ; j ++){
//This assumes Column AC has the dates you are comparing aganist
if (date > data[i][j])
{
//sets that the Row with index i to empty
data[i] = ["","",""]
};
}
};
//finally set the value back into sheet
sheet.getRange('AC9:AE33').setValues(data)
};
Basically, you need to setValues once data array is modified.
Note: This Statement (date > data[i][0]) doesn't work as expected when the values are stored as text.
Edit: Modified the code and added a new for loop to go through each column, based on comments
Related
This question already has answers here:
Compare two dates with JavaScript
(43 answers)
Closed 2 years ago.
What this code does is to identify the row of the array based on the input (Date) and return the values associated with the input date.
However, this for loop is not working as it does not respect the if condition and always returns the last row of the array.
function viewData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Overall Cashflow"); //Data entry Sheet
var datasheet = ss.getSheetByName("Cashflow Tracker Data"); //Data Sheet
var data = datasheet.getDataRange().getValues();
var date = formSS.getRange("H5").getDisplayValue();
for (var i = 0; i < data.length; i++){
if (data[i][0] == date) {
break;
}
var oldinflow = data[i][1];
var oldoutflow = data[i][2];
}
formSS.getRange("H8").setValue(oldinflow);
formSS.getRange("H11").setValue(oldoutflow);
}
You need to get the valueOf() of the date object instead.
Try this:
function viewData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var formSS = ss.getSheetByName("Overall Cashflow"); //Data entry Sheet
var datasheet = ss.getSheetByName("Cashflow Tracker Data"); //Data Sheet
var data = datasheet.getDataRange().getValues();
var date = formSS.getRange("H5").getValue().valueOf();
for (var i = 0; i < data.length; i++){
if (data[i][0].valueOf() == date) {
break;
}
var oldinflow = data[i][1];
var oldoutflow = data[i][2];
}
formSS.getRange("H8").setValue(oldinflow);
formSS.getRange("H11").setValue(oldoutflow);
}
getValues() might return Date object for cells holding "dates", by the other hand getDisplayValue() will return a string. This might explain why (data[i][0] == date is no working.
To prevent on quick and dirty solution that might be good enough is instead of using getValues(), to use getDisplayValues().
I am writing a code that targets a column with dates and I would like to get the dates and compare it to the current date so that I can get the difference between the two.
I ran into a problem I am having trouble solving. It seems that when I used .getValues in my range, it placed each timestamp in an array then those arrays in another array. Like this: [[(new Date(1539619200000))], [(new Date(1540396800000))], [(new Date(1540828800000))]]
I would like to place all the values in 1 array only so I can start solving how to convert the timestamps in to normal dates. I am also a beginner with this so I am sorry if this seems like an basic question.
function datesincolumn() //collects only the date values in range
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow(); //will identify last row with any data
entered
var range = sheet.getRange('D2:D' + lastRow); //will get range of cells
with data present
var dates = range.getValues();//gets all values in the range
var CurrentDate = new Date();
var timestamps = [];
for (i = 0; i <= dates.length; i++)
{
if (dates[i] >= i)
{
timestamps.push(dates[i]);
}
}
Logger.log(dates);
}
When you use .getValues(), you will always get a 2-dimensional array. The outer array represents the row, and the inner array represents the columns. Since you're only getting one column, you can simply append [0] to your dates[i].
function datesincolumn() { //collects only the date values in range
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow(); //will identify last row with any data entered
var range = sheet.getRange('D2:D' + lastRow); //will get range of cells with data present
var dates = range.getValues();//gets all values in the range
var CurrentDate = new Date();
var timestamps = [];
for (var i = 0; i <= dates.length; i++) {
var date = dates[i][0];
if (date >= i)
timestamps.push(date);
}
Logger.log(dates);
}
I'm trying to run an IF function to match the date in the first column to "last month" and the date in the last column to "newest date" and copy and paste all of the rows matching this criteria (excluding the first and last column) to the bottom of the list.
This is the script I'm running and it isn't finding any matches when I know for a fact there are at least 100 rows matching this criteria:
function myFunction() {
var MCS = SpreadsheetApp.openById('[ID REMOVED FOR THIS Q]');
var MRB = MCS.getSheetByName('Media Rates Back');
var MRBrange = MRB.getRange(1,1,MRB.getLastRow(),1).getValues();
var dest = MRBrange.filter(String).length + 1;
var LM = new Date();
LM.setDate(1);
LM.setMonth(LM.getMonth()-1);
var LMs = Date.parse(LM);
var Datenew = MRB.getRange(MRB.getLastRow(),MRB.getLastColumn()).getValue();
var Datecol = MRB.getRange(1,6,MRB.getLastRow(),1).getValues();
var Datenews = Date.parse(Datenew);
for(var i=0; i<MRBrange.length; i++) {
if(Date.parse(MRBrange[i])==LMs && Date.parse(Datecol[i])==Datenews ) {
var NewRange = MRB.getRange(i,2,(MRB.getLastRow()-i),5);
var NewRangeV = NewRange.getValues();
var destination = MRB.getRange(MRB.getLastRow()+1,2);
Logger.log(NewRange);
NewRange.copyTo(destination);
}else{
Logger.log(i);
}
}}
Any help would be appreciated!
Rather than get the columns as separate ranges, I would get the entire range as one array, then loop over that and check the two columns.
I'm also assuming your values are formatted as dates in the Sheet, in which case you don't need to use Date.parse(), and that your actual date logic is correct.
You can try using the debugger and set a breakpoint at the IF, so you can check the values it is comparing. or put a Logger.log call to list your comparisons.
var last_month_column = 1;
var newest_date_column = MRB.getLastColumn();
var MRBrange = MRB.getRange(1,1,MRB.getLastRow(),newest_date_column).getValues();
for(var row in MRBrange) {
if(MRBrange[row][last_month_column]==LMs && Datecol[row][newest_date_column] ==Datenews ) {
/* your copy logic here */
}else{
Logger.log(i);
}
}
I think the problem may be that MRBrange is a 2d Array. So I used another loop to convert it to a 1d array.
function myFunction() {
var MCS = SpreadsheetApp.openById('[ID REMOVED FOR THIS Q]');
var MRB = MCS.getSheetByName('Media Rates Back');
var MRBrangeA = MRB.getRange(1,1,MRB.getLastRow(),1).getValues();//2d array
var MRBrange=[];
for(var i=0;i<MRBrangeA.length;i++)
{
MRBrange.push(MRBrangA[i][0]);//1d array
}
var dest = MRBrange.filter(String).length + 1;
var LM = new Date();//current day
LM.setDate(1);//first day of month
LM.setMonth(LM.getMonth()-1);//first day of last month
var LMs = Date.parse(LM);
var Datenew = MRB.getRange(MRB.getLastRow(),MRB.getLastColumn()).getValue();
var Datecol = MRB.getRange(1,6,MRB.getLastRow(),1).getValues();
var Datenews = Date.parse(Datenew);
for(var i=0; i<MRBrange.length; i++) {
if(Date.parse(MRBrange[i])==LMs && Date.parse(Datecol[i])==Datenews ) {
var NewRange = MRB.getRange(i,2,(MRB.getLastRow()-i),5);
var NewRangeV = NewRange.getValues();
var destination = MRB.getRange(MRB.getLastRow()+1,2);
Logger.log(NewRange);
NewRange.copyTo(destination);
}else{
Logger.log(i);
}
}}
I'm trying to make a function to look over a list of days (a year school calendar), and, compare with a date from a user prompt and, until the date (all the days "lower" than the user date) set in the B column a string (in this case "Summer holidays", only if there's not another value in the B column corresponding to cell.
What I have:
What I expect, if I set Sept 12th in the input:
function setTrimesters() {
var sheet =
SpreadsheetApp.getActive().getSheetByName("calendar2017");
// Start of 1st trimester
var input = ui.prompt("Set first day of trimester (DD/MM)");
var value = input.getResponseText();
var allStartEndTrimesters = [valorInici1rTri]
// Get dataRange
var dataRange = sheet.getRange('A1:B'+sheet.getLastRow());
// Get dataRange values
var data = dataRange.getDisplayValues();
for (var i = 0 ; i < data.length ; i++) {
if (data[i][0] < value) {
if (data[i][1] == '') {
data[i][1] = "Summer holidays";
}
}
}
dataRange.setValues(data);
}
The script is working only with the day value of the date. Then, in October, from 1st to 11th the script assign too the value "Summer holidays".
I don't know how to get day and month values before comparing. I've tried to setNumberFormat to miliseconds, or days (similar to 42895 or so)... but there are some limitations with SpreadsheetApp and App Scripts working with dates.
Thanks in advance for helping
The problem is that you work with dates as strings, so they get compared in lexicographic order. With day being first, 4/9 precedes 5/7, which is not what you wanted. I suggest to
Use getValues instead of getDisplayValues. It will retrieve JavaScript date object instead of a string. Then the comparison < works correctly, but you also need the beginning date to be a Date object: see below.
Do not overwrite input data in column A. Separate input and output ranges.
Here is an example, with user-interface part removed:
function testSummer() {
var sheet = SpreadsheetApp.getActiveSheet();
var userEnteredDate = "26/07"; // what you get from user
var dateParts = userEnteredDate.split("/");
var beginning = new Date();
beginning.setMonth(dateParts[1] - 1, dateParts[0]);
beginning.setHours(0, 0, 0, 0); // so it's 0 hour of the day entered, in the current year
var inputData = sheet.getRange('A1:A'+sheet.getLastRow()).getValues();
var outputRange = sheet.getRange('B1:B'+sheet.getLastRow());
var outputData = outputRange.getValues();
for (var i = 0; i < inputData.length; i++) {
if (inputData[i][0] < beginning && outputData[i][0] == "") {
outputData[i][0] = "summer vacation";
}
}
outputRange.setValues(outputData); // not overwriting input
}
I'm attempting to grab the values from a data range, loop over the data, match a value in that data, then based on a matching value, update cell located a few columns over.
I'm able to locate value to match, but I'm having a hard time understanding how to update the cell a few columns over. Below is the code I've gotten so far minus the .setValue piece.
var trackingSS = 'Spreadsheet 1';
var decisionSS = 'Spreadsheet 2';
function grabRequestID() {
var ss = SpreadsheetApp.openById(decissionSS);
var range = ss.getActiveSheet().getRange(ss.getLastRow(), 2, 1, 1)
var requestID = range.getValue();
return requestID;
}
function managersDecision() {
var ss = SpreadsheetApp.openById(trackingSS)
var sheet = ss.getSheetByName('Requests');
var data = sheet.getDataRange().getValues();
var requestID = grabRequestID();
for (var i=0; i < data.length; i++) {
for (var j=0; j < data[i].length; j++) {
if (data[i][j] == requestID) {
Logger.log('found it');
}
}
}
}
As you can see there are two functions. managersDecision() reads in all the data from spreadsheet 1. It then calls grabRequestID() and uses this value (from spreadsheet 2) as the matching criteria as it loops over the data from spreadsheet 1. Currently it will locate and find the match.
What I want to have happen now, is based on the match, go over two columns in the same row and update the cell value to "approved" or "denied" based on successfully finding a match.
I'm a bit lost on how to get it to write to the cell. Should I try and identify the row its in and then work to set the value? Maybe grab the entire row the match is in (into an array) and then rewrite the row?
Any assistance would be appreciated..
To set a value you just need to take in count that you are working with an array that start at zero, but in the spreadsheet we start counting at one. You'll also need to be sure that you are trying to write in an existing cell. So prior writing, add the necessary column.
I didn't wrote the "denied" part as it was going through all the cell of the spreadsheet, but I wrote a second version of the managersDecision function where I only go through one column and here I took care of that denied part.
here the code:
var trackingSS = 'Spreadsheet1';
var decisionSS = 'Spreadsheet2';
function grabRequestID() {
var ss = SpreadsheetApp.openById(decisionSS);
var range = ss.getActiveSheet().getRange(ss.getLastRow(), 2, 1, 1)
var requestID = range.getValue();
Logger.log("requestID= "+requestID);
return requestID;
}
function managersDecision() {
var ss = SpreadsheetApp.openById(trackingSS)
var sheet = ss.getSheetByName('Requests');
var data = sheet.getDataRange().getValues();
var requestID = grabRequestID();
for (var i=0; i < data.length; i++) { // going through all the rows
for (var j=0; j < data[i].length; j++) { // this is going through all the cell of a row
if (data[i][j] == requestID) {
Logger.log('found it');
var row = Number(i)+1;
var col = Number(j)+1+2;
while(sheet.getMaxColumns()<col){
sheet.insertColumnsAfter(sheet.getMaxColumns(),col-sheet.getMaxColumns());
}
sheet.getRange(row, col).setValue("approved");
}
}
}
}
function managersDecision2() {
var ss = SpreadsheetApp.openById(trackingSS)
var sheet = ss.getSheetByName('Requests');
var data = sheet.getRange("A:A").getValues()
var requestID = grabRequestID();
var col = 1+2;
while(sheet.getMaxColumns()<col){
sheet.insertColumnsAfter(sheet.getMaxColumns(),col-sheet.getMaxColumns());
}
for (var i=0; i < data.length; i++) { // going through all the rows
var row = 1+i;
if (data[i][0] == requestID) {
Logger.log('found it');
sheet.getRange(row, col).setValue("approved");
}
else if(data[i][0] !=""){
Logger.log(row)
sheet.getRange(row, col).setValue("denied");
}
}
}