You are creating calendar events from a sheet="Test Weekend Coverage/Calendar Push - New" and you find that it is consistently re-processing existing entries instead of the last entry.
The calendar sheet is populated by a series of queries sourced from another sheet "Non-Grocery Join Sheet". "Non-Grocery Join Sheet" holds the raw entries for the calendar, but no matter how many rows of data may appear on this sheet, the query will limit the range to 6 rows.
The answer for this topic consists of three elements:
1 - corrections to syntax in the OP script,
2 - enabling the query to display all the entries on "Non-Grocery Join Sheet".
3 - a utility that identifies the last row of content when a query is the source range for a script.
Syntax
There are three syntax errors in OP script.
1 - getRange(lastRow,1,1,7)
.getRange()
is an index-based method. Column A = 1, Column F = 6, Column G = 7. The "Published" column is Column G; so you want a range that will span column A to Column G, you need to declare getRange(lastRow,1,1,7)
.
2 - if(data[0][6]!= 'Published')
.getValues()
returns a zero-based two-dimensional array. In order to test the value in Column F, one must test data[0][6]
. data[6]
will return "undefined" and kill the script.
3 - if... else
and { ... }
block statements.
The script as written does not describe any action in the event that the 'IF" statement is false. The MDN Javascript Web Docs suggests that when executing multiple statements within a clause, use a block statement ({ ... }) to group those statements, and that it is a good practice to always use block statements.
Troubleshooting
Sometimes, logging the value of certain variables will help identify values, and there, errors. In the answer below, I have left Logger.log
statements in the code for your information.
Query statements
=QUERY('Non-Grocery Join Sheet'!L2:L)
By defining a range as the entire column (except the for header row), the query range will always display extra rows added to the source sheet. This should be done for each query statement, or use a single query for the entire calendar sheet.
Last row of Content
When a query is subject of a getLastRow
method, the reported last row might not be the actual last row of content because the query will display as many rows as exist in the source sheet. It is more reliable to analyse the actual data until the last row is found.
In the answer, a utility described by https://yagisanatode.com/ is used to determine the last row.
function wa14198102() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Test Weekend Coverage/Calendar Push - New');
//Select the column we will check for the first blank cell
var columnToCheck = sheet.getRange("A:A").getValues();
// Get the last row based on the data range of a single column.
var AlastRow = getLastRowSpecial(columnToCheck);
//TEST
// Logger.log("DEBUG: the last row in column A = "+AlastRow);
// get the data
var datarange = sheet.getRange(AlastRow,1,1,7);
//Logger.log("DEBUG: the range is "+datarange.getA1Notation())
var data = datarange.getValues();
//Logger.log(data); // DEBUG
//Logger.log("DEBUG: Published value = "+data[0][6]);
if(data[0][6]!= 'Published'){
//Logger.log("DEBUG: the IF is true")
var title = data[0][0];
var eventDesc = data[0][1];
var eventLoca = data[0][2];
var startDate = data[0][3];
var endDate = data[0][4];
var attendees = data[0][5];
var published = data[0][6];
var masterCal = CalendarApp.getCalendarById('<<enter your calendar ID>>');
masterCal.createEvent(title,new Date(startDate),new Date(endDate),{location:eventLoca,description:eventDesc,guests:attendees,sendInvites:true});
sheet.getRange(AlastRow,7).setValue('Published');
//Logger.log("Updated Published status");
}
else{
//Logger.log("DEBUG: the IF is false; do nothing")
}
}
/************************************************************************
*
* Gets the last row number based on a selected column range values
*
* @param {array} range : takes a 2d array of a single column's values
*
* @returns {number} : the last row number with a value.
*
*/
// Google Apps Script: Get the last row of a data range when other columns have content like hidden formulas and check boxes
// Credit: https://yagisanatode.com/2019/05/11/google-apps-script-get-the-last-row-of-a-data-range-when-other-columns-have-content-like-hidden-formulas-and-check-boxes/
function getLastRowSpecial(range){
var rowNum = 0;
var blank = false;
for(var row = 0; row < range.length; row++){
if(range[row][0] === "" && !blank){
rowNum = row;
blank = true;
}else if(range[row][0] !== ""){
blank = false;
};
};
return rowNum;
};
if(data[6]!= 'Published')
as well assheet.getRange(lastRow,7).setValue('Published');