Macro Google Sheet "Macro action change" - google-apps-script

I would need a change in how this macro works
function getDynamicRow(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('B.Wioski');
var sourceRange = sheet.getRange('A1:F26500');
var data = sourceRange.getValues(); // Array of arrays [[Row1],[Row1],[Row3]]
// add data to next empty row in the static sheet.
var targetSheet = ss.getSheetByName('TW');
targetSheet.getRange(targetSheet.getLastRow() + 1, 1, data.length, data[0].length).setValues(data);
}
currently the macro places the entries one under the other and I would need it to place the entries to the right of the preview image below
additionally, I would need a macro to delete data older than 5-7 days

Suggestion
Perhaps you can try this implementation below:
Script:
function getDynamicRow(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('B.Wioski');
var sourceRange = sheet.getRange('A1:F'+sheet.getLastRow());
var data = sourceRange.getValues(); // Array of arrays [[Row1],[Row1],[Row3]]
data.push(["","","","","",new Date()]); //added a timestamp for reference on deleting older data
// add data to next empty row in the static sheet.
var targetSheet = ss.getSheetByName('TW');
var currentCol = targetSheet.getDataRange().getNumColumns();
if(currentCol != 1)currentCol = currentCol+1;
targetSheet.getRange(1, currentCol, data.length, data[0].length).setValues(data);
}
Sample Result:
After running the script once:
After running it again (so on & so forth) :
As for deleting data older than 5 - 7 days, here's my implementation that you can try:
Since I have added a timestamp on every copied data on sheet TW, you can refer to this sample script below:
UPDATED
Script:
function deleteOlderThan5To7Days(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var targetSheet = ss.getSheetByName('TW');
var row = targetSheet.getDataRange().getLastRow();
var col = targetSheet.getDataRange().getLastColumn();
var data = targetSheet.getRange(row,1,1,col).getValues();
for(x=0; x< data[0].length; x++){
var curCol = x + 1;
if(data[0][x] != ""){
var getDate = Utilities.formatDate(new Date(data[0][x]), SpreadsheetApp.getActive().getSpreadsheetTimeZone(), "dd");
var checkDays = getDate - new Date().getDate();
if(new Date(data[0][x]).getMonth()+1 == new Date().getMonth()+1){ //If data timestamp is within the current month
if(checkDays > 5){ //Check if the timestamp of the data is more than 5 - 7 days
Logger.log("Current row date: "+data[0][x]+"\n"+"Found on column #"+curCol+ " is "+checkDays+" days older");
Logger.log("Delete data column " + curCol);
targetSheet.insertColumnsAfter(targetSheet.getLastColumn(),1); //add a blank column on every deletion
targetSheet.deleteColumn(curCol); //delete the points column data
return;
}else{
//Data timestamp is NOT older than 5-7 days");
}
}else{ //Data was copied last month or older that the current month
Logger.log("Current row date: "+data[0][x]+"\n"+"Found on column #"+curCol+ " is old");
Logger.log("Delete data column "+ curCol);
targetSheet.insertColumnsAfter(targetSheet.getLastColumn(),1); //add a blank column on every deletion
targetSheet.deleteColumn(curCol); //delete the points column data
return;
}
}
}
}
Sample Demonstration:
Let's say the first data was copied on November 2, 2021 or 11/2/2021 as seen here on the sample sheet on TW:
After running the sample function deleteOlderThan5To7Days, here's the result:
The execution logs for review:
NOTE:
Same removal process applies if ever the month is the same as the current month but older than 5-7 days.

Related

Add Timestamp if row is not empty

I have a script on a nightly trigger which does the following three things:
copies the contents of one spreadsheet (spreadsheet 1) to another (spreadsheet 2).
adds a timestamp column to column A each time the script is run.
deletes rows if there are certain values in column D.
The first time the script runs, everything works fine (i.e. when the new spreadsheet 2 is still blank). The subsequent times it runs it encounters issues.
With some research I have discovered that is because any blank rows in the source sheet (spreadsheet 1) are copied to the new spreadsheet (spreadsheet2) and a timestamp is placed in the blank rows. This leaves a bunch of rows that only have a timestamp. By the time the script gets to the part where it is supposed to delete rows based on values it gets thrown by these rows that only have a timestamp.
I am new to google script and was unable to find anything in the forum. Is there a way to modify the script so that the timestamp is only placed on rows where there is data?
var sourceSpreadsheetID = "spreadsheet1 ID";
var sourceWorksheetName = "BusinessDetails";
var targetSpreadsheetID = "spreadsheet2 ID";
var targetWorksheetName = "Sheet5";
function importBusinessDetailsData(){
var thisSpreadsheet = SpreadsheetApp.openById("spreadsheet1 ID");
var thisWorksheet = thisSpreadsheet.getSheetByName("BusinessDetails");
var thisData = thisWorksheet.getDataRange();
var toSpreadsheet = SpreadsheetApp.openById("spreadsheet2 ID");
var toWorksheet = toSpreadsheet.getSheetByName("Sheet5");
var toRange = toWorksheet.getRange(1,2, thisData.getNumRows(), thisData.getNumColumns())
toRange.setValues(thisData.getValues());
setTimeStamp()
main()
removeThenSetNewVals()
}
function setTimeStamp() {
SpreadsheetApp.getActive().getSheetByName('Sheet5')
.getRange('A2:A').setValue(new Date())
};
function main() {
var startTime = new Date().getTime();
var deleteSelectedRows = removeThenSetNewVals();
var runTime = (new Date().getTime() - startTime) / 1000;
Logger.log("Runtime is: " + runTime + " seconds");
};
function removeThenSetNewVals(){
var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet5');
var range = sheet.getDataRange();
var pattern = new RegExp("value1|value2|value3");
var columnToSearch = 3;
var newRangeVals = range.getValues().filter(r => r[0] && !pattern.exec(r[columnToSearch]))
range.clearContent();
var numRows = newRangeVals.length;
var newRange = sheet.getRange(1,1, numRows, newRangeVals[0].length).setValues(newRangeVals);
var maxRows = sheet.getMaxRows();
}
As far as I understand, you only want to write entries to the new sheet which fit a particular condition. Basically, you want to filter the records before you write them, therefore consider the following:
var thisData = thisWorksheet.getDataRange();
var rowsWithData = thisData.filter( row => row[3] )
This states that only rows which contain truthy data will be considered, but feel free to fit the condition according to your needs.
References
filter()
truthy

Taking user input to Google Sheets using Apps Script and process with queries

I created a spreadsheet for reporting students attendance that contains 8 sheets (each sheet named as a subject code). After completing a particular class, I go to the specific sheet (subject) and select all the rows of that particular date and press the button AfterClass-->Process Data (sorting, removing duplicates and protecting) using Google Apps Script/Macros. All working fine.
Now I created a DASHBOARD and I want that a teacher can do everything from the dashboard rather than going to individual sheet (subject). S/he can give two inputs - subject (sheetname) and Date from the Dashboard and then automatically process these specific dataset of that Sheet (Not all data of the sheet). Please note that date is in Column A and subject-code in Column F. The code I wrote as follows:
function AfterClass() {
var spreadsheet = SpreadsheetApp.getActive();
//Sorting and removing duplicates
var height = spreadsheet.getActiveSheet().getActiveRange().getHeight();
spreadsheet.getCurrentCell().offset(0, 0, height, 6).activate()
.sort({column: spreadsheet.getActiveRange().getColumn() + 2, ascending: true});
spreadsheet.getActiveRange().removeDuplicates([spreadsheet.getActiveRange().getColumn() + 2]).activate();
//Protecting data finally
//var lastRow = spreadsheet.getLastRow();
var timeZone = Session.getScriptTimeZone();
var stringDate = Utilities.formatDate(new Date(), timeZone, 'dd/MM/yy HH:mm');
var me = Session.getEffectiveUser();
var description = 'Protected on ' + stringDate + ' by ' + me;
var protection = SpreadsheetApp.getActiveSheet().getActiveRange().protect().setDescription(description);
//protection.setDomainEdit(false);
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
//Removing blank spacess in between data
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[1] == '') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
//For Double periods in a class
//var ss = SpreadsheetApp.getActiveSpreadsheet()
//var database = SpreadsheetApp.openById("xxx");
//var source = ss.getSheetByName('yyy');
var dataToCopyRng = SpreadsheetApp.getActiveSheet().getActiveRange(); //Gets range object of all data on source sheet
var dataToCopy = dataToCopyRng.getValues(); //Gets the values of the source range in a 2 dimensional array
var copyToSheet = SpreadsheetApp.getActiveSheet();
var copyData = copyToSheet.getRange(copyToSheet.getLastRow()+1,1,dataToCopy.length,dataToCopy[0].length).setValues(dataToCopy);
//Calculate class attendance and signed
var height2 = spreadsheet.getActiveSheet().getActiveRange().getHeight();
SpreadsheetApp.getActiveSheet().getCurrentCell().offset(2*height2,1).activate();
SpreadsheetApp.getActiveSheet().getCurrentCell().setRichTextValue(SpreadsheetApp.newRichTextValue()
.setText(height2 + ' Students, SIGNED')
.setTextStyle(0, 12, SpreadsheetApp.newTextStyle()
.setBold(true)
.build())
.build());
spreadsheet.getCurrentCell().offset(0, -1, 1, 6).activate();
spreadsheet.getActiveRangeList().setBackground('#e6b8af');
//.setBackground('#d9d9d9')
}
[dashboard][1]
[1]: https://i.stack.imgur.com/cMtHC.png
How to run your script from Dashboard after selecting the specified sheet and time
Modify your function in a way that it takes input from the cells A2 and C2 and D2 from Dashboard
Replace all instances of getActiveSheet() through getSheetByName(name), whereby name is your input from A1
Replace all instances of getActiveRange() through sheet.getRange(), whereby you define the range as as subrange as defined by the dates you retrieved
In order to find the first occurrence of the start date and the last occurrence of the end date - use the methods indexOf() and lastIndexOf()
Make sure that your date notation in Dashboard is the same as in the sheets for correct functionality
Sample:
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('After Class')
.addItem('Process Data', 'AfterClass')
.addToUi();
}
function AfterClass() {
var spreadsheet = SpreadsheetApp.getActive();
var dashboard = spreadsheet.getSheetByName("Dashboard");
var sheetName = dashboard.getRange("A2").getValue();
//retrieve the start date to use as desired
var startDate = dashboard.getRange("C2").getDisplayValue();
var endDate = dashboard.getRange("D2").getDisplayValue();
var sheet = spreadsheet.getSheetByName(sheetName);
//chose the range within the specified dates, for this first locate the date column
var startRow = 2;
var dateColumn = sheet.getRange(startRow,1,sheet.getLastRow(), 1);
var dates = dateColumn.getDisplayValues().flat();
var firstRow = dates.indexOf(startDate)+startRow;
var lastRow = dates.lastIndexOf(endDate)+startRow;
//now get the range between (and including) those rows
var range = sheet.getRange(firstRow, 1, lastRow-firstRow+1, sheet.getLastColumn());
//Sorting and removing duplicates
// You need to specify by which column you want to sort your data, in this sample it it column 3 - that it column C
var column = 3;
range.sort({column: column, ascending:true});
range.removeDuplicates([column]);
//now delete empty rows if any
for (var i = range.getHeight(); i >= 1; i--){
if(range.getCell(i, 1).isBlank()){
sheet.deleteRow(range.getCell(i, 1).getRow());
}
}
//Protecting data
var timeZone = Session.getScriptTimeZone();
var stringDate = Utilities.formatDate(new Date(), timeZone, 'dd/MM/yy HH:mm');
var me = Session.getEffectiveUser();
var description = 'Protected on ' + stringDate + ' by ' + me;
var protection = range.protect().setDescription(description)
//protection.setDomainEdit(false);
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
}
Important
The sample above will work if your sheet is sorted by dates (ascending) - as you specified in the comments. However, once the data is sorted by column C and not dates anymore it might not work as intended.
Sidenote:
From your code I understand that you recorded it as a macro rather than writing it from scratch (visible by the (unnecessary) calls of activate()).
I very much recommend you to take some time to study Apps Script in roder to understand your code in depth and be able to perform modificaitons and adjustments according to your needs.
There is the basic tutorial for Apps Script in general, samples and explanations for Google Sheets in specific and the references for all available Apps Script methods, whereby most methods feature a code sample.

Google Sheets - Script to move rows to different tab depending on a key word

I have been working on a google sheet that that receives a form submission.
Once the submission comes in I need a script to move the rows of data to different tabs depending on the name shown in column C.
I have extensively searched for solutions on stack overflow and I am very close to a solution right now through the code I have found and edited.
I have a script that will move historic dates to a different tab and leave all future dates in the original tab based in the logic of the date being older than today.
All I need to do now is modify this to move the rows with the name "John" in column C to the John tab and ignore the date.
Once I can get one name to work I am confident I can make this work for multiple names and multiple tabs.
Please feel free to create a copy of the following test sheet I have been working on.
link:
https://docs.google.com/spreadsheets/d/1zJpylrD_5hzScW3lIjIQQSKiY0Aan6Wkm_h_IbVrVXM/edit#gid=0
function MovePastDates() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var entrySheet = ss.getSheetByName("Entry Sheet");
var franksSheet = ss.getSheetByName("Franks Sheet");
var lastColumn = entrySheet.getLastColumn();
for(var i = entrySheet.getLastRow(); i > 0; i--){
var dateCell = entrySheet.getRange(i, 1).getValue();
var today = new Date();
var test = new Date(dateCell);
// If the value is a valid date and is a past date, we remove it from the sheet to paste on the other sheet
if(test < today){
var rangeToMove = entrySheet.getRange(i, 1, 1, entrySheet.getLastColumn()).getValues();
franksSheet.getRange(franksSheet.getLastRow() + 1, 1, 1, entrySheet.getLastColumn()).setValues(rangeToMove);
entrySheet.deleteRow(i);
}
}
}
The final result should be a google sheet that receives form entries.
Each entry will be allocated to a specific person who will only have edit permissions to there own tab only where they can approve/decline requests submitted through the form.
All other users of the sheet will have view only access.
I wanted two scripts:
1) Script to move form submission rows to a specific tab dependent on person’s name
(I was going to set up a trigger every minute for this)
2) Script to move past dates into an historic sheet
(I was going to set up a trigger every night for this)
I have been able to modify your code to achieve the desired function, it may not be the most efficient but it appears to work well.
Script One is:
function moveRowsToNamesSheets() { //Name of function
var sObj={John:'Johns Sheet',Frank:'Franks Sheet',David:'Davids Sheet'}; // Put key work and sheet name here in format eg.( keyWord1: 'sheet name to move keyWord1 to')
var ss=SpreadsheetApp.getActive(); // ??
var esh=ss.getSheetByName('Entry Sheet'); //Sheet data is being pulled form
var fsh=ss.getSheetByName('Franks Sheet'); //unsure why one of the sheets is named here
var erg=esh.getDataRange(); // Not sure of function now that I am not using dates
var evA=erg.getValues(); // ??
var d=0; //??
//var today=new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()).valueOf(); // Didnt need this line
for(var i=1;i<evA.length;i++) { //??
if(/*new Date(evA[i][0]).valueOf() < today*/ evA[i][2]=='John' ||evA[i][2]=='Frank' ||evA[i][2]=='David') { //Keywords used go here, what does the [2] mean?
ss.getSheetByName(sObj[evA[i][2]]).appendRow(evA[i]); //??
esh.deleteRow(i+1-d);
d++; //increments d by one
}
}
}
Script Two is:
function HistoricDates() {
// Initialising
var ss = SpreadsheetApp.getActiveSpreadsheet();
//--------------- Franks Sheets --------------------
var franksSheet = ss.getSheetByName("Franks Sheet");
var PastSheet = ss.getSheetByName("Historic Requests");
var lastColumn = franksSheet.getLastColumn();
// Check all values from your "Franks Sheet" sheet
for(var i = franksSheet.getLastRow(); i > 0; i--){
// Check if the value is a valid date
var dateCell = franksSheet.getRange(i, 4).getValue(); //Dates in column 4
if(isValidDate(dateCell)){
var today = new Date();
var test = new Date(dateCell);
// If the value is a valid date and is a past date, we remove it from the sheet to paste on the other sheet
if(test < today){
var rangeToMove = franksSheet.getRange(i, 1, 1, franksSheet.getLastColumn()).getValues();
PastSheet.getRange(PastSheet.getLastRow() + 1, 1, 1, franksSheet.getLastColumn()).setValues(rangeToMove);
franksSheet.deleteRow(i);
}
}
}
//---------------------- Johns Sheets -------------------------
var johnsSheet = ss.getSheetByName("Johns Sheet");
var pastSheet = ss.getSheetByName("Historic Requests");
var lastColumn = johnsSheet.getLastColumn();
// Check all values from your "Johns Sheet" sheet
for(var i = johnsSheet.getLastRow(); i > 0; i--){
// Check if the value is a valid date
var dateCell = johnsSheet.getRange(i, 4).getValue(); //Dates in column 4
if(isValidDate(dateCell)){
var today = new Date();
var test = new Date(dateCell);
// If the value is a valid date and is a past date, we remove it from the sheet to paste on the other sheet
if(test < today){
var rangeToMove = johnsSheet.getRange(i, 1, 1, johnsSheet.getLastColumn()).getValues();
pastSheet.getRange(pastSheet.getLastRow() + 1, 1, 1, johnsSheet.getLastColumn()).setValues(rangeToMove);
johnsSheet.deleteRow(i);
}
}
}
//--------------- Davids Sheets --------------------
var davidsSheet = ss.getSheetByName("Davids Sheet");
var pastSheet = ss.getSheetByName("Historic Requests");
var lastColumn = davidsSheet.getLastColumn();
// Check all values from your "Davids Sheet" sheet
for(var i = davidsSheet.getLastRow(); i > 0; i--){
// Check if the value is a valid date
var dateCell = davidsSheet.getRange(i, 4).getValue();//Dates in column 4
if(isValidDate(dateCell)){
var today = new Date();
var test = new Date(dateCell);
// If the value is a valid date and is a past date, we remove it from the sheet to paste on the other sheet
if(test < today){
var rangeToMove = davidsSheet.getRange(i, 1, 1, davidsSheet.getLastColumn()).getValues();
pastSheet.getRange(pastSheet.getLastRow() + 1, 1, 1, davidsSheet.getLastColumn()).setValues(rangeToMove);
davidsSheet.deleteRow(i);
}
}
}
}
// Check is a valid date
function isValidDate(value) {
var dateWrapper = new Date(value);
return !isNaN(dateWrapper.getDate());
}
The working spreadsheet is located here:
https://docs.google.com/spreadsheets/d/1VCONRkBpkva-KrFDO2bFV8ZTp1U168QWAGavcKCa_uQ/edit?usp=sharing
I think this is what you want:
function movePastDatesOrJohn() {
var sObj={John:'Johns Sheet',Frank:'Franks Sheet',David:'Davids Sheet'};
var ss=SpreadsheetApp.getActive();
var esh=ss.getSheetByName('Entry Sheet');
var fsh=ss.getSheetByName('Franks Sheet');
var erg=esh.getDataRange();
var evA=erg.getValues();
var d=0;
var today=new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()).valueOf();
for(var i=1;i<evA.length;i++) {
if(new Date(evA[i][0]).valueOf() < today || evA[i][2]=='John') {
ss.getSheetByName(sObj[evA[i][2]]).appendRow(evA[i]);
esh.deleteRow(i+1-d);
d++;
}
}
}
So Franks Sheet and Davids Sheet only get the rows that are older than today. But Johns Sheet gets all of the row that are Johns and disregards the date. I think that's what you wanted.
By the way, did you know that if you more that one form attached to your spreadsheet you can tell which response sheet the formSubmit trigger is writing too, with the event object range? Using sheet name = e.range.getSheet().getName();

Trying to copy a row from one sheet to another based on the value in the first column of each row

I'm trying to move yesterday's data off of one sheet onto another sheet(from one tab at the bottom to another tab at the bottom), then delete it off of the first sheet(while preserving the equations).
Here's an example spreadsheet.
I have a google script running every night just after midnight, and I've tried to iterate through every single row, check if the first column has yesterday's date, then copy the row to the other sheet and delete the original row.
function moveDataNewSheet() {
var DATA_SPREADSHEET_ID = "16cy4ClKYEN_w5_c6KiR2zSjRsUD9ijxQD9DGffNRXtI";
var Sheet1 = SpreadsheetApp.openById(DATA_SPREADSHEET_ID).getSheetByName("Sheet1");
// create sheet with yesterdays date
// if col1 has yesterdays date,
// then copy it to yesterdays sheet
// delete row
//get dateString
var today = new Date();
var yesterday = new Date();
yesterday.setDate(today.getDate()-1);
var dateString = Utilities.formatDate(yesterday, 'EDT', 'yyyy-MM-dd');
// create new sheet with yesterdays date
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var yourNewSheet = activeSpreadsheet.getSheetByName(dateString);
if (yourNewSheet != null) {
activeSpreadsheet.deleteSheet(yourNewSheet);
}
yourNewSheet = activeSpreadsheet.insertSheet();
yourNewSheet.setName(dateString);
//set active sheet to Sheet1
SpreadsheetApp.setActiveSheet(Sheet1);
SpreadsheetApp.getActiveSpreadsheet().moveActiveSheet(1);
// if col1 has yesterdays date copy it to dateString's sheet
// delete row
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source_sheet = SpreadsheetApp.getActiveSpreadsheet();
var target_sheet = activeSpreadsheet.getSheetByName(dateString);
for (var i = 0; i < Sheet1.getLastRow(); i++) {
if (Sheet1.getRange(i,1).getValue() == Sheet1.getRange(i,1).substring(0,10)) {
var last_row = target_sheet.getLastRow();
target_sheet.insertRowAfter(last_row);
source_sheet.getRange(i,1).clear();
}
}
The OP is trying to backup previous day data to a specific sheet and then delete that data from the source. The code is overly complicated lacks clarity and does not delete the rows from the source.
The processing sequence follows the OP's method:
Identify the source spreadsheet and sourcesheet.
Create a variable for to identify "yesterday's date".
Establish whether a sheet by that name exists in the source spreadsheet; if not, then create and rename a sheet.
Assign the new sheet as the targetsheet
get the number of rows of data. Normally getLastRow could be used, but this identified empty 'phantom' rows.
get all the data from the Sourcesheet prior to the loop
loop through the source data
build a header row and then evaluate each timestamp against the variable for "yesterday's date"
where the row date is a match, push values for each column onto a "rowarray", push the "row" array onto a "targetarray", clear the "rowarray" for the next row; increment a row counter.
when finished with the loop, update the target sheet with the "targetarray".
delete the rows from the sourcesheet.
function so_55537340_03() {
// NOTE: code assumes that data is always in contiguous rows in date order
// setup external sheet
var ss = SpreadsheetApp.openById("<insert spreadsheet ID>");
// Logger.log("DEBUG: ss = "+ss.getName());//DEBUG
var sourceSheet = ss.getSheetByName("Sheet1");
//Logger.log("DEBUG: source sheet: "+sourceSheet.getName());//DEBUG
//get dateString
var today = new Date();
var yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
//Logger.log("DEBUG: yesterday: "+yesterday);//DEBUG
var dateString = Utilities.formatDate(yesterday, 'EDT', 'yyyy-MM-dd');
// Logger.log("DEBUG: datestring: "+dateString);//DEBUG
// create new sheet with yesterdays date
// get the sheet, returns null if not exist
var yourNewSheet = ss.getSheetByName(dateString);
// Logger.log("DEBUG: yournewsheet: "+yourNewSheet);//DEBUG
// test if sheet exists
if (yourNewSheet != null) {
// Logger.log("DEBUG: the spreadsheet is NOT null");//DEBUG
// the sheet exists, so what??
//ss.deleteSheet(yourNewSheet);
} else {
// Logger.log("DEBUG: the spreadsheet is null");//DEBUG
// the sheet doesn't exist, so create and rename the sheet
yourNewSheet = ss.insertSheet();
yourNewSheet.setName(dateString);
}
// assign a variable to the target sheet
var targetSheet = ss.getSheetByName(dateString);
// Logger.log("DEBUG: target sheet: "+targetSheet.getName());// DEBUG
// get the number of rows of data in column A for a loop (getLastrow was unreliable)
var Avals = sourceSheet.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
// Logger.log("DEBUG: source last row: "+Alast);//DEBUG
// define the source range and get the data
var sourceRange = sourceSheet.getDataRange();
var sourceData = sourceRange.getValues();
// Logger.log("DEBUG: sourcerange = "+sourceRange.getA1Notation()+", and number of rows of data: "+Alast);//DEBUG
// establish arrays for pasting row results and total results to target sheet
var targetData = [];
var rowData = [];
// create variable to count rows to delete
var rowcounter = 0;
// loop through the source data
for (var i = 0; i < Alast; i++) {
// clear rowData before each new row
rowData = [];
// test for row 1/headers
if (i == 0) {
// build the header row in the target
rowData.push(sourceData[i][0]);
rowData.push(sourceData[i][1]);
rowData.push(sourceData[i][2]);
rowData.push(sourceData[i][3]);
rowData.push(sourceData[i][4]);
rowData.push(sourceData[i][5]);
rowData.push(sourceData[i][6]);
rowData.push(sourceData[i][7]);
// push row data on targetData
targetData.push(rowData);
}
// process for rows other than header
if (i > 0) {
//Logger.log("DEBUG: rowdate: "+sourceData[i][0]);//DEBUG
// get the substring
var sourcecelldate = sourceData[i][0].substring(0, 10);
//Logger.log("DEBUG: data substring: "+sourcecelldate);//DEBUG
// if the data substring equals the datestring for yesterday
if (sourcecelldate == dateString) {
//Logger.log("DEBUG: dates align, do something");//DEBUG
// build the data for the row
rowData.push(sourceData[i][0]);
rowData.push(sourceData[i][1]);
rowData.push(sourceData[i][2]);
rowData.push(sourceData[i][3]);
rowData.push(sourceData[i][4]);
rowData.push(sourceData[i][5]);
rowData.push(sourceData[i][6]);
rowData.push(sourceData[i][7]);
// push row data on targetData
targetData.push(rowData);
rowcounter++
Logger.log("Row counter: " + rowcounter);
} else {
//Logger.log("DEBUG: dates DO NOT align, do nothing");//DEBUG
}
}
} // end of loop
// get number of rows of targetdata
//Logger.log("DEBUG: length of targetdata"+targetData.length);//DEBUG
// define the data range for the target sheet
var targetrows = targetSheet.getRange(1, 1, targetData.length, 8);
// paste the data onto the targetsheet
targetrows.setValues(targetData);
// delete the old rows from the source sheet
//Logger.log("DEBUG: number of rows to delete = "+rowcounter);
sourceSheet.deleteRows(2, rowcounter);
}
I have left "Logger" statements in the following code to troubleshoot values at various stages in the process.

Q: Google Sheets Script "InternalError: Cannot convert to (class)"

I wrote a Google Script for my spreadsheet (a lot of copy/paste online) that is intended to transfer a row of data from one sheet to another sheet if a date matches to the current date (it runs once per day). The code works, with one exception of row 24 where I get an error of "Cannot conver XXX to (class)" with XXX representing the data in that row. It seems it may be something with how I'm defining the variable source_range but I just can't get it to work! Any help is much appreciated. The goal is that within the for loop it copies the "current" row of data based on variable i. If I change the source_range parameters to something static (like row 3, for example) it works perfectly.... but of course then it only pastes row 3 every time which is not what I desire. Any suggestions help!
function AutomationEnroll() {
try{
var spreadsheet = SpreadsheetApp.openById("XXXHIDDENXXX");
var source_sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets() [2]);
var target_sheet = SpreadsheetApp.setActiveSheet(spreadsheet.getSheets()[3]);
var startRow = 2; // First row of data to process
var numRows = source_sheet.getLastRow()-1; // Number of rows to process
var dataRange = source_sheet.getRange(startRow, 1, numRows, source_sheet.getLastColumn());
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
//Logger.log(sheetDate);
var TodayDate = Utilities.formatDate(new Date(),'GMT','EEE, d MMM yyyy')
var SurgeryDate = Utilities.formatDate(new Date(row[1]),'GMT', 'EEE, d MMM yyyy')
if (TodayDate == SurgeryDate){
//I now need it to copy row[i] in sheet[2] over to the last_row in sheet[3] ;
var source_range = source_sheet.getRange(data[i], 1, 1, 12) //error converting to (class)
var last_row = target_sheet.getLastRow();
target_sheet.insertRowAfter(last_row);
var target_range = target_sheet.getRange("A"+(last_row+1)+":L"+(last_row+1));
source_range.copyTo(target_range);
}
}
}catch(err){
Logger.log(err.lineNumber + ' - ' + err);
}
}`