Google sheets - Update date cells based on criteria - google-apps-script

I need to update dates in a sheet once a week.
I would like to manually run a script to do this.
Each date in column "C" will increase by a number of days in column "D" in same row.
Only dates prior to a date in specific cell (F2 in example) will be updated.
See this sheet as an example: https://docs.google.com/spreadsheets/d/11f6G5_vNK5Z8UR2A_MUUXpL8awC2mJ8ozpnznWQ_anM/edit?usp=sharing
Column C - Service Date
Column D - No. of days to advance
12/3/2021
7
12/3/2021
14
12/10/2021
7
12/10/2021
7
12/17/2021
28
Any help or pointing in the right direction would be great!

function updateDates() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
const vs = sh.getRange(2,1,sh.getLastRow() - 1, sh.getLastColumn()).getValues();
const dt = new Date(sh.getRange('F2').getValue());
const dthv = new Date(dt.getFullYear(),dt.getMonth(),dt.getDate()).valueOf();
const oA = [];
vs.forEach(r => {
let d = new Date(r[2]);
let dv = new Date(d.getFullYear(),d.getMonth(),d.getDate()).valueOf();
if(dv < dthv) {
oA.push([new Date(d.getFullYear(),d.getMonth(),d.getDate() + r[3])]);
} else {
oA.push([r[2]]);
}
});
sh.getRange(2,3,oA.length,oA[0].length).setValues(oA);
}
Sheet 0 Before:
COL1
COL2
COL3
COL4
COL5
COL6
11/10/2021
5
11/15/2021
11/11/2021
6
11/12/2021
7
11/13/2021
8
11/14/2021
9
11/15/2021
10
11/16/2021
11
11/17/2021
12
11/18/2021
13
11/19/2021
14
11/20/2021
15
11/21/2021
16
11/22/2021
17
11/23/2021
18
11/24/2021
19
Sheet0 After:
COL1
COL2
COL3
COL4
COL5
COL6
11/15/2021
5
11/15/2021
11/17/2021
6
11/19/2021
7
11/21/2021
8
11/23/2021
9
11/15/2021
10
11/16/2021
11
11/17/2021
12
11/18/2021
13
11/19/2021
14
11/20/2021
15
11/21/2021
16
11/22/2021
17
11/23/2021
18
11/24/2021
19

Related

Google Sheets - Script to move columns given the column header

Given this table schema:
Col_France
Col_Argentina
Col_Croatia
Col_Morocco
x
x
x
x
x
x
x
x
I want to create a Google Script that rearranges the columns so the order is always:
Col_Argentina -> Column 1
Col_France -> Column 2
Col_Croatia -> Column 3
Col_Morocco -> Column 4
Because the original column orders of the given table is not always as described above, I cannot simply use:
var sheet = SpreadsheetApp.getActiveSheet();
// Selects Col_France.
var columnSpec = sheet.getRange("A1");
sheet.moveColumns(columnSpec, 2);
and so on... In other words, the table schema can possibly be:
Col_Morocco
Col_Croatia
Col_France
Col_Argentina
x
x
x
x
x
x
x
x
but the desired outcome should always be the defined above. The script should be scalable. In the future, more than 4 columns should be rearranged.
My approach would be:
Define the range of columns to rearrange (they are all together)
For the first column, get the value of the column header
Depending on the value, move the column to a predefined index
Move to the next column and repeat
Iterate until end of range
Can somebody please point me to the required functions?
In your situation, when moveColumns is used, how about the following sample script?
Sample script:
function myFunction() {
var order = ["Col_Argentina", "Col_France", "Col_Croatia", "Col_Morocco"]; // This is from your question.
var sheet = SpreadsheetApp.getActiveSheet();
var obj = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0].reduce((ar, h, i) => [...ar, { from: i + 1, to: order.indexOf(h) + 1 }], []).sort((a, b) => a.to > b.to ? 1 : -1);
for (var i = 0; i < obj.length; i++) {
if (obj[i].from != obj[i].to) {
sheet.moveColumns(sheet.getRange(1, obj[i].from), obj[i].to);
obj.forEach((e, j) => {
if (e.from < obj[i].from) obj[j].from += 1;
});
}
}
}
When this script is run, the columns are rearranged by order you give. In this case, the text and cell format are also moved.
When moveColumns(columnSpec, destinationIndex) is used, the indexes of columns are changed after moveColumns(columnSpec, destinationIndex) was run. So, please be careful about this. In the above script, the changed indexes are considered.
References:
moveColumns(columnSpec, destinationIndex)
reduce()
forEach()
Order Columns:
function ordercols() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const [h,...vs] = sh.getDataRange().getValues();
const idx = {};
h.forEach((h,i) => idx[h]=i);
const o = vs.map(r => [r[idx['COL4']],r[idx['COL3']],r[idx['COL2']],r[idx['COL1']]]);
sh.clearContents();
o.unshift(['COL4','COL3','COL2','COL1']);
sh.getRange(1,1,o.length,o[0].length).setValues(o);
}
Data:
COL1
COL2
COL3
COL4
24
5
2
9
16
0
13
18
22
24
23
16
12
12
4
17
6
20
17
14
7
13
4
2
2
20
4
22
3
5
3
4
16
5
7
23
ReOrdered:
COL4
COL3
COL2
COL1
9
2
5
24
18
13
0
16
16
23
24
22
17
4
12
12
14
17
20
6
2
4
13
7
22
4
20
2
4
3
5
3
23
7
5
16

How can I build an array of column D where column A = Arg

"Entries" is a sheet that I enter individual tasks with the date, name, start time, end time. It calculates total time per task
"Days" is a generated sheet that gets dates from Entries and calculates total time worked on all tasks for each unique day in Entries
I would like Days to have a column that uses the date from column A, looks in Entries, and returns the earliest start time from any row in Days that is for that date.
function startTime(theDate) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ent = ss.getSheetByName("Entries");
ent.activate();
var rng = ent.getRange(rownumber, 1, 1, numberofcolums)
var rangeArray = rng.getValues();
}
calling using :
=startTime(A1)
where A1 contains the Date that I want the check-in time for.
The array of columnA where A = 'Arg'
function colDWhereAisArg() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet0');
let o = sh.getRange(2,1,sh.getLastRow() - 1,4).getValues().map(r => {
if(r[0] == 'Arg') {
return [r[3]];
}
}).filter(e => e);
Logger.log(JSON.stringify(o));
}
Execution log
4:29:59 PM Notice Execution started
4:30:00 PM Info [[5],[8],[13]]
4:30:00 PM Notice Execution completed
My Data:
COL1
COL2
COL3
COL4
1
2
3
4
Arg
3
4
5
3
4
5
6
4
5
6
7
Arg
6
7
8
6
7
8
9
7
8
9
10
8
9
10
11
9
10
11
12
Arg
11
12
13

Printing rows with certain text in column 2 with app script

I need to print off certain rows in a google sheet depending on what is in column 2 of that row. I know how to find the rows with a for loop but the rest eludes me. Perhaps my googling skills are rusty.
This is what I have.
var app = SpreadsheetApp;
var rows = app.getActive().getSheetByName("Sheet").getMaxRows().toString();
var rows = rows.replace(".0","");
function findRows(){
for (var counter = 1; counter <= rows; counter = counter+1){
if(app.getActive().getSheetByName("Sheet").getRange(counter, 2) == "example" || "example2"){
}
}
Find the correct rows
function findrows() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const osh = sh.getSheetByName("Sheet1");
const vs = sh.getDataRange().getValues();
let s = vs.map(r => {
if(r[1] == "Example" || r[1] == "example2") {
return r;
}
}).filter(e => e);
Logger.log(JSON.stringify(s));
//you can output to a sheet with something like
//sheet.getRange(1,1,s.length,s[0].length).setValues(s);
osh.getRange(1,1,s.length,s[0].length).setValues(s);//put on another sheet
}
Execution log
4:56:34 PM Notice Execution started
4:56:35 PM Info [[2,"Example",4,5],[5,"Example",7,8],[9,"Example",11,12],[12,"Example",14,15]]
4:56:35 PM Notice Execution completed
Data:
COL1
COL2
COL3
COL4
1
2
3
4
2
Example
4
5
3
4
5
6
4
5
6
7
5
Example
7
8
6
7
8
9
7
8
9
10
8
9
10
11
9
Example
11
12
10
11
12
13
11
12
13
14
12
Example
14
15
13
14
15
16
BTW Printing is not easily done from Javascript or Google Apps Script

Google Sheet add increment numbers for duplicates

Hello how to get a increment numbers for duplicate with array function.
Example in below picture if we search a word in entire A row if there is any duplicates it will add numbers in B.
Try
=arrayformula(if(A1:A="",,
A1:A&if(countif(A1:A,A1:A)=1,,
"-"&text(countifs(A1:A,A1:A,row(A1:A),"<="&row(A1:A)),"00"))))
Or...
=A1&if(countif(A$1:A,A1)=1,,
"-"&text(countif(A$1:A1,A1),"00"))
...and dragdown.
Count duplicates
function countdups() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const vs = sh.getRange(1,1,sh.getLastRow(),2).getValues();
let uA = [];
let obj = {pA:[]};
vs.forEach(r => {
if(!~uA.indexOf(r[0])) {
uA.push(r[0]);
obj[r[0]] = 1;
obj.pA.push(r[0]);
} else {
obj[r[0]] += 1;
}
});
let vo = obj.pA.map(p => [`${p}-${obj[p]}`]);
sh.getRange(1,2,vo.length,1).setValues(vo);
}
COL1
COL1-1
7
7-2
6
6-1
9
9-1
11
11-3
16
16-1
4
4-1
15
15-1
19
19-3
11
2-1
2
10-3
10
18-1
11
5-1
10
0-1
18
19
19
10
5
0
7

This code is supposed to convert data from my spread sheet to a document and then to a pdf, but its only doing the last row

I have a script which is supposed to export data from a google sheet, enter it into a document and store that in the proper folder, then take that new document and turn it into a PDF, and then store it into it's own folder.
When I run both functions independently, they executer right and go until all documents have been created.
With them put together as shown below, they only do it to the last row of data and not the other 13...
Any ideas why it isn't looping?
function createDoc() {
console.log("first");
// To pull the headers of each column - insert spreadsheet URL and header array
var headers = Sheets.Spreadsheets.Values.get('1846CxmPdoc2VBW6GxaybCPW1_u2swO1jooIBiF2Yl90', 'A2:AA2');
// To pull the variables for each header - insert spreadsheet URL and variable array
var variables = Sheets.Spreadsheets.Values.get('1846CxmPdoc2VBW6GxaybCPW1_u2swO1jooIBiF2Yl90', 'A3:AA14');
// To pull the template document for the header and variables to be input by the program
var templateId = '1ONhT3n4Pr49BL6xEM_ykO9UVi8xZriA2fVAZjoFi2qI';
//Loop to run through all variables in spreadsheet
for(var i = 0; i < variables.values.length; i++) {
//Create the variables which will be used to transfer the data from the spreadsheet to the document. The first cell in the row is 0 and then from left to right, increases in its number. Only change variable name and the number.
var client = variables.values[i][0];
var agent = variables.values[i][1];
var aaddress = variables.values[i][2];
var acity = variables.values[i][3];
var caddress = variables.values[i][4];
var ccity = variables.values[i][5];
var suopen = variables.values[i][6];
var suclose = variables.values[i][7];
var moopen = variables.values[i][8];
var moclose = variables.values[i][9];
var tuopen = variables.values[i][10];
var tuclose = variables.values[i][11];
var weopen = variables.values[i][12];
var weclose = variables.values[i][13];
var thopen = variables.values[i][14];
var thclose = variables.values[i][15];
var fropen = variables.values[i][16];
var frclose = variables.values[i][17];
var saopen = variables.values[i][18];
var saclose = variables.values[i][19];
var price = variables.values[i][20];
var appayment = variables.values[i][21];
var mpayment = variables.values[i][22];
var junepayment = variables.values[i][23];
var julypayment = variables.values[i][24];
var aupayment = variables.values[i][25];
var sepayment = variables.values[i][26];
}
// Make a copy of the template file
const documentId = DriveApp.getFileById('1ONhT3n4Pr49BL6xEM_ykO9UVi8xZriA2fVAZjoFi2qI').makeCopy().getId();
// Rename the copied file
DriveApp.getFileById(documentId).setName('2022' + " " + client + " " + 'Pool Management Proposal');
// Set copied file's destination variable;
var folderId = DriveApp.getFolderById('1YVhLzwZ9CI5-iTR1SKHF5ykNVqZQvQY9');
// Send copied file to this folder
var fileId = DriveApp.getFileById(documentId);
fileId.moveTo(folderId);
// Get the document body as a variable
const OpenDoc = DocumentApp.openById(documentId);
const body = OpenDoc.getBody();
// Insert Data from sheet to document. ##info## is the placeholder text in the document, and the second variable is the variable we set above to codify the column's data in the sheet.
body.replaceText('##Agent Name##', agent);
body.replaceText('##Agent Address##', aaddress);
body.replaceText('##Agent City/Zip##', acity);
body.replaceText('##Client Name##', client)
body.replaceText('##Client Address##', caddress);
body.replaceText('##Client City/Zip##', ccity);
body.replaceText('##Contract Price##', price);
body.replaceText('##April Payment##', appayment);
body.replaceText('##May Payment##', mpayment);
body.replaceText('##June Payment##', junepayment);
body.replaceText('##July Payment##', julypayment);
body.replaceText('##August Payment##', aupayment);
body.replaceText('##September Payment##', sepayment);
body.replaceText('##Sunday Open##', suopen);
body.replaceText('##Sunday Close##', suclose);
body.replaceText('##Monday Open##', moopen);
body.replaceText('##Monday Close##', moclose);
body.replaceText('##Tuesday Open##', tuopen);
body.replaceText('##Tuesday Close##', tuclose);
body.replaceText('##Wednesday Open##', weopen);
body.replaceText('##Wednesday Close##', weclose);
body.replaceText('##Thursday Open##', thopen);
body.replaceText('##Thursday Close##', thclose);
body.replaceText('##Friday Open##', fropen);
body.replaceText('##Friday Close##', frclose);
body.replaceText('##Saturday Open##', saopen);
body.replaceText('##Saturday Close##', saclose);
OpenDoc.saveAndClose();
var pdfFolder = DriveApp.getFolderById("1_idXGdZo0l_U1IxuaLDUqrk0HjdfZvsg");
var templateFile = DriveApp.getFileById(documentId);
var theBlob = templateFile.getBlob().getAs('application/pdf');
var newPDFFile = folderId.createFile(theBlob);
newPDFFile.moveTo(pdfFolder);
var fileName = templateFile.getName().replace(".", "");
// otherwise filename will be shortened after full stop
newPDFFile.setName(fileName + ".pdf").getId();
}
function myfunk() {
const vs = Sheets.Spreadsheets.Values.get("ssid",'Sheet0!A1:J21');
SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange(1,1,vs.values.length,vs.values[0].length).setValues(vs.values);
}
I thought about what you were saying and you're right it doesn't seem to act like and array so I tried this:
function myfunk() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
let vs = Array.from(Sheets.Spreadsheets.Values.get("ssid",'Sheet0!A1:J21').values);
let va = vs.filter((r,i) => i % 2 == 0);
SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange(1,1,va.length,va[0].length).setValues(va);
}
My Sheet0:
COL1
COL2
COL3
COL4
COL5
COL6
COL7
COL8
COL9
COL10
3
14
5
10
17
1
15
10
2
6
12
10
2
19
2
1
19
6
10
7
4
7
17
11
17
3
8
7
2
5
10
17
14
13
2
6
18
6
1
11
15
3
1
1
1
19
9
1
4
14
1
6
8
8
7
10
5
5
17
12
15
1
8
4
5
7
13
19
0
7
14
18
9
10
13
3
9
9
19
14
11
1
5
17
17
15
2
6
8
16
0
14
6
4
18
12
8
8
17
4
10
15
13
7
3
17
13
17
9
3
3
16
2
2
4
7
6
3
17
3
17
18
12
13
13
10
9
14
16
11
8
6
2
10
14
7
6
0
17
12
13
12
19
9
12
11
19
14
0
18
18
17
0
0
18
9
19
14
2
1
7
9
17
12
19
0
3
17
17
16
15
11
0
6
4
18
8
16
8
15
10
4
5
10
13
8
7
3
13
9
10
2
9
11
10
0
17
2
19
7
My Sheet1:
COL1
COL2
COL3
COL4
COL5
COL6
COL7
COL8
COL9
COL10
12
10
2
19
2
1
19
6
10
7
10
17
14
13
2
6
18
6
1
11
1
6
8
8
7
10
5
5
17
12
14
18
9
10
13
3
9
9
19
14
0
14
6
4
18
12
8
8
17
4
3
16
2
2
4
7
6
3
17
3
8
6
2
10
14
7
6
0
17
12
18
17
0
0
18
9
19
14
2
1
15
11
0
6
4
18
8
16
8
15
10
2
9
11
10
0
17
2
19
7
Clearly this is now behaving as an array.
Then I realized that it must be returning JSON because this also worked.
function myfunk() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
let vs = JSON.parse(Sheets.Spreadsheets.Values.get("ssid",'Sheet0!A1:J21')).values;
let va = vs.filter((r,i) => i % 2 == 0);
SpreadsheetApp.getActive().getSheetByName('Sheet1').getRange(1,1,va.length,va[0].length).setValues(va);
}
You know... I have only been coding for like.. 5 days.
I solved my problem however, and its odd that out of all the responses, no one simply said to "turn them all into one function", lol.
All i had to do was turn it into one function, and it pulls the data for one row, creates the document, saves the document into whatever folder I tell it to, then creates the PDF, then stores it into a folder I tell it to. Next I will make it auto email that PDF with a template document as the body. If anyone wants the code, here it is...
function createDoc() {
console.log("pulling data and template");
var headers = Sheets.Spreadsheets.Values.get('1846CxmPdoc2VBW6GxaybCPW1_u2swO1jooIBiF2Yl90', 'log!A2:AA2');
var variables = Sheets.Spreadsheets.Values.get('1846CxmPdoc2VBW6GxaybCPW1_u2swO1jooIBiF2Yl90', 'log!A3:AA14');
var templateId = '1ONhT3n4Pr49BL6xEM_ykO9UVi8xZriA2fVAZjoFi2qI';
console.log("creating loop");
for (var i = 0; i < variables.values.length; i++) {
var client = variables.values[i][0];
var agent = variables.values[i][1];
var aaddress = variables.values[i][2];
var acity = variables.values[i][3];
var caddress = variables.values[i][4];
var ccity = variables.values[i][5];
var suopen = variables.values[i][6];
var suclose = variables.values[i][7];
var moopen = variables.values[i][8];
var moclose = variables.values[i][9];
var tuopen = variables.values[i][10];
var tuclose = variables.values[i][11];
var weopen = variables.values[i][12];
var weclose = variables.values[i][13];
var thopen = variables.values[i][14];
var thclose = variables.values[i][15];
var fropen = variables.values[i][16];
var frclose = variables.values[i][17];
var saopen = variables.values[i][18];
var saclose = variables.values[i][19];
var price = variables.values[i][20];
var appayment = variables.values[i][21];
var mpayment = variables.values[i][22];
var junepayment = variables.values[i][23];
var julypayment = variables.values[i][24];
var aupayment = variables.values[i][25];
var sepayment = variables.values[i][26];
console.log("setting document Id");
var documentId = DriveApp.getFileById('1ONhT3n4Pr49BL6xEM_ykO9UVi8xZriA2fVAZjoFi2qI').makeCopy().getId();
console.log("setting destinations")
var documentDestination = DriveApp.getFolderById('1YVhLzwZ9CI5-iTR1SKHF5ykNVqZQvQY9');
var pdfDestination = DriveApp.getFolderById("1_idXGdZo0l_U1IxuaLDUqrk0HjdfZvsg");
console.log("creating document");
DriveApp.getFileById(documentId).setName('2022' + " " + client + " " + 'Pool Management Proposal');
var document = DocumentApp.openById(documentId);
var body = document.getBody();
body.replaceText('##Agent Name##', agent);
body.replaceText('##Agent Address##', aaddress);
body.replaceText('##Agent City/Zip##', acity);
body.replaceText('##Client Name##', client)
body.replaceText('##Client Address##', caddress);
body.replaceText('##Client City/Zip##', ccity);
body.replaceText('##Contract Price##', price);
body.replaceText('##April Payment##', appayment);
body.replaceText('##May Payment##', mpayment);
body.replaceText('##June Payment##', junepayment);
body.replaceText('##July Payment##', julypayment);
body.replaceText('##August Payment##', aupayment);
body.replaceText('##September Payment##', sepayment);
body.replaceText('##Sunday Open##', suopen);
body.replaceText('##Sunday Close##', suclose);
body.replaceText('##Monday Open##', moopen);
body.replaceText('##Monday Close##', moclose);
body.replaceText('##Tuesday Open##', tuopen);
body.replaceText('##Tuesday Close##', tuclose);
body.replaceText('##Wednesday Open##', weopen);
body.replaceText('##Wednesday Close##', weclose);
body.replaceText('##Thursday Open##', thopen);
body.replaceText('##Thursday Close##', thclose);
body.replaceText('##Friday Open##', fropen);
body.replaceText('##Friday Close##', frclose);
body.replaceText('##Saturday Open##', saopen);
body.replaceText('##Saturday Close##', saclose);
console.log("moving document");
var docFile = DriveApp.getFileById(documentId);
docFile.moveTo(documentDestination);
console.log("document creation complete");
document.saveAndClose();
console.log("converting document to PDF");
var templateFile = DriveApp.getFileById(documentId);
var folder =
DriveApp.getFolderById('1_idXGdZo0l_U1IxuaLDUqrk0HjdfZvsg');
var theBlob = templateFile.getBlob().getAs('application/pdf');
var newPDFFile = folder.createFile(theBlob);
console.log("naming PDF");
var fileName = templateFile.getName().replace(".", ""); //otherwise filename will be shortened after full stop
newPDFFile.setName(fileName + ".pdf");
console.log("PDF creation complete");
}
}