Google Sheets Scripts, IF date of a cell - if-statement

I ve been getting some issues trying to use IF statement using items on the sheets as answers, mostly i been trying either using as firt statement a string directly or using another cell of the sheets with the statement comparing to the one i ve been trying to detect with out any results. Mostly my objective would be to, with a daly trigger, use an IF statement to detect every day if the date of today is the same as a date marked on a cell, my only current solution is and only thing is to make it detect if a cell is empty or not, so i just been using google Formulas that do the detect of the date, and if True make it empty, and if not make something appear
Here are some of the tests I ve been trying
Test 1:
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SheetName");
else if (Sheet.getRange(1, 1).getValue() == "2/2/2020"){}
(cell A1=2/2/2020)
Test 2:
var Sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("SheetName");
else if (Sheet.getRange(1, 1).getValue() == Sheet.getRange(1, 2).getValue()){}
(cell A1=2/2/2020)
(cell B1=2/2/2020)

Here are two solutions depending on what you are trying to accomplish.
This first one gets the values, formats them to a date format, and then compares them
function myFunction() {
var tz = Session.getScriptTimeZone();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('SheetName');
var data = sheet.getDataRange().getValues();
var aVal = Utilities.formatDate(data[0][0],tz,'MM/dd/YYYY');
var bVal = Utilities.formatDate(data[0][1],tz,'MM/dd/YYYY');
Logger.log([aVal,bVal])
if(aVal == bVal) {
//do something
}
}
This second section gets the display values and compares them. The first solution compares the date values while this second solution compares the dates as a string. Good luck!
function myFunction1() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('SheetName');
var data = sheet.getDataRange().getDisplayValues();
var aVal = data[0][0]
var bVal = data[0][1]
Logger.log([aVal,bVal])
if(aVal == bVal) {
//do something
}
}

Related

deleting sheets with a date older than the past two days

Working in Google Scripts, I'm trying to create a function that will look at the names of all tabs in a Google Sheet, and delete all sheets that meet these conditions: 1) tab name include a date (sheet names that do have a date are prefaced with some other text - the mm/dd/yyyy formatted date is in the string) and 2) the date in that sheet name is older than today's date minus 2 days).
There are two sheet names that include dates: "Leadership Review mm/dd/yyyy" and "Leadership Review w/notes mm/dd/yyyy". I have a script that auto-runs DAILY to create these sheets, so the goal is to automate a one-time clean-up for old sheets and set up a daily trigger to auto-run that function.
So far, I've created an array to capture the names of each sheet name ("tabNameArray") and have a regexp for use in matching for mm/dd/yyyy text that shows up in a sheet name.
My thought on how this would work - not sure how to accomplish 2 and 3:
create that array
parse the array - match each sheetname in the array against the regexp mm/dd/yyyy to identify sheetnames with a date.
A loop through that array... IF that sheetname has a date (create a new array or subarray with just those? doesn't seem necessary, but a thought), AND that date is > 2 days from today(), delete those sheets.
function deleteOldReportSheets() {
var sheetNameArray = new Array();
var sheetWithDatesArray = new Array(); //not sure this is necessary
var dateRegex = new RegExp("[0-3]?[0-9]\/[0-3]?[0-9]\/(?:[0-9]{2})?[0-9]{2}"); //for mm/dd/yyyy match, tested successfully on regex101.com
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
for (var i=0 ; i<sheets.length ; i++) sheetNameArray.push( [ sheets[i].getName() ] ) // populates the sheetNameArray with names of each sheet
(do this: for sheets that have a date that is older than 2 days from today, delete...)
I'd appreciate support to code this - even better if there's a more efficient way than what I started thinking through.
Thanks for your assistance.
Description
The following example will compare the named sheets containing the date to today and indicate which sheets should be deleted. I leave the deletion operation to the OP.
Script
function test() {
try {
let spread = SpreadsheetApp.getActiveSpreadsheet();
let sheets = spread.getSheets();
let dateRegex = new RegExp("[0-3]?[0-9]\/[0-3]?[0-9]\/(?:[0-9]{2})?[0-9]{2}"); //for mm/dd/yyyy match, tested successfully on regex101.com
let today = new Date();
console.log("today = "+Utilities.formatDate(today,"GMT","MM/dd/yyyy"));
today = new Date(today.getFullYear(),today.getMonth(),today.getDate()-2);
for( let i=0; i<sheets.length; i++ ) {
let sheet = sheets[i];
let name = sheet.getName();
console.log("Sheet name = "+name);
let match = name.match(dateRegex);
if( match ) {
match = new Date(match[0]);
if( match.valueOf() <= today.valueOf() ) {
console.log("delete");
}
else {
console.log("keep");
}
}
}
}
catch(err) {
console.log(err);
}
}
Console.log
11:45:16 AM Notice Execution started
11:45:17 AM Info today = 05/01/2022
11:45:17 AM Info Sheet name = Sheet1
11:45:17 AM Info Sheet name = Sheet 04/29/2022
11:45:17 AM Info delete
11:45:17 AM Info Sheet name = Sheet 04/30/2022
11:45:17 AM Info keep
11:45:17 AM Info Sheet name = Sheet 05/01/2022
11:45:17 AM Info keep
11:45:16 AM Notice Execution completed
Reference
Date()
String.match()
I think it can be something like this:
function myFunction() {
const reg = new RegExp(/\d{2}\/\d{2}\/\d{4}/);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const if_two_days_ago = date =>
new Date(date).valueOf() < new Date().valueOf() - 3600000 * 48;
ss.getSheets()
.filter(s => reg.test(s.getName()))
.filter(s => if_two_days_ago(s.getName().match(reg)))
.forEach(s => { console.log('bye-bye -->', s.getName()); ss.deleteSheet(s) });
}
Delete Sheets with dates older than two days
function delSheets() {
const ss = SpreadsheetApp.getActive();
const dt = new Date();
const dtv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate() - 2).valueOf();//date threshold value
ss.getSheets().forEach(sh => {
let m = sh.getName().match(/\d{1,2}\/\d{1,2}\/\d{4}/g);//includes a date
if(m && new Date(m[0]).valueOf() < dtv) {
ss.deleteSheet(sh);
}
});
}

Spreadsheet Script, match with wildcard and different cases

I am having trouble executing the Spreadsheet script below.
I think there are two mistakes but I do not know how to fix.
Could anyone help it to fix it?
1:Wildcard
if(original_date=='....-..-..')
2:if synteax
if(original_date=='....-..-..')
{condition="matched"}
Detail
On the spreadsheet, there are two columns.
The first columns have dates in a format as YYYY-MM-DD such as 2020-04-21.
But sometimes, they have different formats such as 04/21/2020.
The second columns are empty.
Only when the first column cell has the "YYYY-MM-DD" format, I want to copy the cell into the second cell in the second column.
*They have 10 rows.
Here is the script.
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1')
for(let i=1; i<=10; i++)
{
original_date_range = sheet.getRange(i, 1);
original_date = original_date_range.getValue();
cleaned_date_range = sheet.getRange(i, 2);
var condition = "";
if(original_date=='....-..-..')
{condition="matched"}
switch(condition)
{
case "matched":
cleaned_date_range.setValue(original_date);
case "":
cleaned_date_range.setValue("");
break;
}
}
I found the solution by myself.
1.Wildcard
The date "2020-04-25" can be written as /\d{4}.\d{2}.\d{2}/
2.If syntax
(Wildcard).test(string to check) is going to give you true/false output
In summary,
if you want to execute different tasks through the verification of date format such as 2020-04-25,
var sheet1 = SpreadsheetApp.getActive().getSheetByName('Sheet1')
var limit = sheet1.getLastRow()
for(let i=4; i<=10; i++) //You can add more rows if you have
{
var orignal_date_cell = sheet1.getRange(i, 1);
var orignal_date_cell_value = orignal_date_cell.getValue();
var target_date_cell = sheet1.getRange(i,2);
if ((/\d{4}.\d{2}.\d{2}/).test(orignal_date_cell_value))
{
target_date_cell.setValue(orignal_date_cell_value);
}
}

Google Script .getvalue() Not Working With Cells With a Formula In It

I have this google script for google sheets that moves rows of data from "Sheet1" to "Sheet2" when column 15 says "tracking", and it works perfectly fine when I type in "tracking" but I would like that column to be an IF equation something like IF(G:G="tracking not available at this time","","tracking"). But the code does not seem to recognize the formula change from "" to "tracking". Do I need to change the getvalue()? Or is there a different workaround to this issue? I've used =query(importrange) withing the spreadsheet to copy over data with a trigger word, but I really want this to be more of an archive system and add a row to the bottom of "Sheet2" whenever row15 on "sheet1"Thanks! Here is the code:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 14 && r.getValue() == "tracking") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Sheet2");
if(targetSheet.getLastRow() == targetSheet.getMaxRows()) {
targetSheet.insertRowsAfter(targetSheet.getLastRow(), 20);
}
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
I had an issue with this recently
I spent about 3 hours debugging something yesterday and this was the culprit.
try using r.getDisplayValue() instead of r.getValue
I am still new to this myself, and feel free to correct me if I am wrong, because if there is a different reason I would really love to know!!!
It seems that if a value in a cell is not typed in but placed there through a formula such as =query() or a similar method, I don't think it actually sees that there is a value in the cell. (I got null values or the formula itself)
If you use getDisplayValue, it "should" get the value that you actually see in the cell.
The correct way to get formulas, instead of displayed values, is with getFormulas rather than getValues

Google Apps Script Copy a range to another sheet based on the value of a cell

I have a table in a sheet in which I have a vlookup to check against another sheet which contains the same data and identify if there are any missing rows (discrepancy).
I want to copy and paste the missing rows identified with the vlookup formula: column I = "#N/A"
I am stuck with the following code, any help is greatly appreciated:
function CopyMissingRows(e) {
if (e.values[8] == '#N/A') {
// do something
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('A2:G2').activate();
var currentCell = spreadsheet.getCurrentCell();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('Good events'), true);
spreadsheet.getRange('Sales cal').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
}
else {
// do something else
}

google-apps-script multiple criteria writing over headers

I have taken a bit of script from Serge which is great (original link here. I have added in a second criteria to exclude certain rows and it works great except, if there is not header in the sheet being copied to, it will not work (error: "The coordinates or dimensions of the range are invalid.") and if I enter a header or some other data, it overwrites it. Can anyone assist please? I have also found that is there is no match to the criteria I get following message "TypeError: Cannot read property "length" from undefined."
Also, what change would I need to make to change the cell 'dataSheetLog[i][12]' to the status variable, i.e. "COPIED" after I have copied it across. I have tried writing a setValue line but it is obviously the wrong instruction for that syntax.
Code is:
{
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetLog = Spreadsheet.getSheetByName("LOG");
var sheetMaint = Spreadsheet.getSheetByName("MAINTENANCE");
var Alast = sheetLog.getLastRow();
var criteria = "08 - Maintenance"
var status = "COPIED"
var dataSheetLog = sheetLog.getRange(2,1,Alast,sheetLog.getLastColumn()).getValues();
var outData = [];
for (var i in dataSheetLog) {
if (dataSheetLog[i][2]==criteria && dataSheetLog[i][12]!=status){
outData.push(dataSheetLog[i]);
}
}
sheetMaint.getRange(sheetMaint.getLastRow(),1,outData.length,outData[0].length).setValues(outData);
}
In:
sheetMaint.getRange(sheetMaint.getLastRow(),1,outData.length,outData[0].length).setValues(outData);
getLastRow() refers to the last occupied row and should be ,getLastRow() + 1,to keep from overwriting your headers and other problems.
Edited:
{
var Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetLog = Spreadsheet.getSheetByName("LOG");
var sheetMaint = Spreadsheet.getSheetByName("MAINTENANCE");
var Alast = sheetLog.getLastRow(); // Log
var criteria = "08 - Maintenance"
var status = "COPIED"
var dataSheetLog = sheetLog.getRange(2,1,Alast,sheetLog.getLastColumn()).getValues(); //Log
var dataSheetLogStatusRange = sheetLog.getRange(2,13,Alast,1); //Log
var dataSheetLogStatus = dataSheetLogStatusRange.getValues(); //Log
var outData = [];
for (var i =0; i < dataSheetLog.length; i++) {
if (dataSheetLog[i][2]==criteria && dataSheetLog[i][12]!=status){
outData.push(dataSheetLog[i]);
dataSheetLogStatus[i][0] = "COPIED";
}
}
if(outData.length > 0) {
sheetMaint.getRange(sheetMaint.getLastRow() + 1,1,outData.length,outData[0].length).setValues(outData);
dataSheetLogStatusRange.setValues(dataSheetLogStatus);
}
}
}
what change would I need to make to change the cell
'dataSheetLog[i][12]' to the status variable, i.e. "COPIED" after I
have copied it across.
You were trying to update the value in the array that was extracted from the sheet and not the sheet itself. As arrays are zero based and spreadsheets are not, to translate, +1 must be added to array row and column indices. I am assuming status is in column M of your sheet.