Replace conditonal formating with script, moving rows creates a mess - google-apps-script

I have a set of sheets and move rows back and fourth multiple times. It makes a mess of the conditional formatting ranges. I have spent hours trying to solve the problem by moving rows differently with no luck. The only solution seems to be using script to handle the conditional formatting. I am not sure how to go about this.
I cant post images. Here are links to my current conditional formatting.
https://www.dropbox.com/s/7ptrwifdelzz7zk/Screen%20Shot%202019-08-24%20at%204.13.36%20PM.png?dl=0
https://www.dropbox.com/s/8wlsay0fclsoyil/Screen%20Shot%202019-08-24%20at%204.13.46%20PM.png?dl=0
https://www.dropbox.com/s/04hp2pyq7icdt56/Screen%20Shot%202019-08-24%20at%204.13.52%20PM.png?dl=0
https://www.dropbox.com/s/qozz3dxaephfymq/Screen%20Shot%202019-08-24%20at%204.13.59%20PM.png?dl=0
I would like the script to keep background green until 5 days before date in cell. Then turn yellow. Once it reaches date in cell it turns red and stays until the row is deleted.

Try this:
function bgControl() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var rg=sh.getDataRange();
var vA=rg.getValues();
var bA=rg.getBackgrounds();
var tda=new Date();
var tdav=new Date(tda.getFullYear(),tda.getMonth(),tda.getDate()).valueOf();
var day=86400000;
for(var i=0;i<vA.length;i++) {
var did=tdav-new Date(vA[i][0]).valueOf();
if(did>(5*day) ){
sh.getRange(i+1,1,1,sh.getLastColumn()).setBackground('green');
}
if(did<=(5*day) && did>=0) {
sh.getRange(i+1,1,1,sh.getLastColumn()).setBackground('yellow');
}
if(did<0) {
sh.getRange(i+1,1,1,sh.getLastColumn()).setBackground('red');
}
}
}
Testing:
For AQ8:AQ
function bgControl() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var rg=sh.getRange(8,43,sh.getLastRow(),1);//AQ8:AQ without all the nulls at the bottom
var vA=rg.getValues();
var bA=rg.getBackgrounds();
var tda=new Date();
var tdav=new Date(tda.getFullYear(),tda.getMonth(),tda.getDate()).valueOf();
var day=86400000;
for(var i=0;i<vA.length;i++) {
var did=tdav-new Date(vA[i][0]).valueOf();
var rng=sh.getRange(i+8,43,1,1);
if(did>(5*day) ){
rng.setBackground('green');
}
if(did<=(5*day) && did>=0) {
rng.setBackground('yellow');
}
if(did<0) {
rng.setBackground('red');
}
}
}

Related

Apps Script: Move duplicates to another sheet instead of deleting them

I found this amazing masterpiece of #Cooper to search for duplicates based on values in 1 column. Now instead of removing these duplicates as the code does, I want to move them to another sheet. Any idea how this can be done?
Thanks :).
Here is the code:
function removeDuplicates() {
var sh=SpreadsheetApp.getActiveSheet();
var dt=sh.getDataRange().getValues();
var uA=[];
var d=0;
for(var i=0;i<dt.length;i++) {
if(uA.indexOf(dt[i][0])==-1) {
uA.push(dt[i][0]);
}else{
sh.deleteRow(i+1-d++);
}
}
}
Move row
function removeDuplicates() {
const ss = SpreadsheetApp.getActive();
const dsh = ss.getSheetByName('Destination');
var sh=SpreadsheetApp.getActiveSheet();
var dt=sh.getDataRange().getValues();
var uA=[];
let d = 0;
for(var i=0;i<dt.length;i++) {
if(uA.indexOf(dt[i][0])==-1) {
uA.push(dt[i][0]);
}else{
dsh.appendRow(dt[i]);//append
sh.deleteRow(i+1-d++);//delete
}
}
}

duplicate row based on cell value

I want to duplicate row based on cell value then delete the cell value(in red) so that when rerun the script wont work on the same row again
I've tried script but it has 2 problems
1- the cell value remain so when rerun script it will cause duplication of same row again and again
2- remove the formulas that I wrote from the entire sheet
the script if you want to check it is still exist in appscript
https://docs.google.com/spreadsheets/d/1fJc2ymAADaZ4jtEGRAkUkWRape24Un7OE4jYcgcd9FM/edit#gid=0
Auto Dupe for Single Row
function AutoDuplicate() {
var ss=SpreadsheetApp.getActive()
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getDisplayValues();
var bA=rg.getBackgrounds();
var v=[];
var b=[]
for(var i=0;i<vA.length;i++){
var t1=bA[i][7];
var t2=vA[i][7];
if(bA[i][7]=='#ff0000' && !isNaN(vA[i][7]) && Number(vA[i][7])>0) {
bA[i][7]='#ffffff';
for(var j=0;j<vA[i][7];j++) {
v.push(vA[i]);
}
b.push(bA[i]);
sh.getRange(1,1,v.length,v[0].length).setValues(v);
sh.getRange(1,1,b.length,b[0].length).setBackgrounds(b);
}
}
}
Animation:
Auto Dupe For Multiple Rows
function autoDupeForMultipleRows() {
var ss=SpreadsheetApp.getActive()
var sh=ss.getActiveSheet();
var rg=sh.getDataRange();
var vA=rg.getDisplayValues();
var bA=rg.getBackgrounds();
var v=[];
var b=[];
var a=0;
for(var i=0;i<vA.length;i++){
if(bA[i][7]=='#ff0000' && !isNaN(vA[i][7]) && Number(vA[i][7])>0) {
bA[i][7]='#ffffff';
for(var j=0;j<=vA[i][7];j++) {
v.push(vA[i]);
b.push(bA[i]);
}
}
}
sh.clearContents();
var org=sh.getRange(1,1,v.length,v[0].length).setValues(v);
org.setBackgrounds(b);
}
Animation:

Delete row when cell has text

I want to delete the entire row if the cell in column A has any content.
I'm new to this, but I've tried a couple of scripts online.
Here is the link to my spreadsheet.
function delRowIfColA() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var rg=sh.getRange(4,1,sh.getLastRow(),sh.getLastColumn());
var vA=rg.getValues();
var d=0;
for(var i=0;i<vA.length;i++) {
if(vA[i][0]) {
sh.deleteRow(i+4-d++);
}
}
}

How to delete specific cells with app script?

My intention is to be able to delete for example cell F1 without deleting cell F2.
var sheet = ss.getSheetByName("QuestionĂ¡rio DQSA");
var range = sheet.getRange("B1:U1");
range.clearContent();
Here I clear the content of these cells but I would like to know how to delete them.
You can use Range.deleteCells(Dimension):
var sheet = ss.getSheetByName("QuestionĂ¡rio DQSA");
var range = sheet.getRange("F1");
range.deleteCells(SpreadsheetApp.Dimension.COLUMNS);//F2 becomes the new F1
If you want to roll your own:
function deleteCell(shift) {
var shift=shift || "left"; //left or up
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var cell=ss.getActiveCell();
if(shift=="left") {
var rg=sh.getRange(cell.getRow(),1,1,sh.getLastColumn());
var vA=rg.getValues();
var row=vA[0];
row.splice(cell.getColumn()-1,1);
rg.clearContent();
sh.getRange(cell.getRow(),1,1,row.length).setValues([row]);
}
if(shift=="up") {
var rg=sh.getRange(1,cell.getColumn(),sh.getLastRow(),1);
var vA=rg.getValues();
var row=vA.map(function(r){return r[0]});
row.splice(cell.getRow()-1,1);
var col=[];
row.forEach(function(e){
col.push([e]);
});
rg.clearContent();
sh.getRange(1,cell.getColumn(),col.length,1).setValues(col);
}
}
Of course now that I know about that new method in range it's a lot easier to write. Thanks to #TheMaster
function deleteCell(shift) {
var shift=shift || "left";
var ss=SpreadsheetApp.getActive();
var cell=ss.getActiveCell();
if(shift=="left") {
cell.deleteCells(SpreadsheetApp.Dimension.COLUMNS);
}
if(shift=="up") {
cell.deleteCells(SpreadsheetApp.Dimension.ROWS);
}
}

Set value based on drop down selection using script

Because prices change over time, I don't want to tie in the price permanently to another cell. So I'd like the script to set the price based on drop down selection.
I have Services sheet with Cost column:
I'd like the script to apply the cost based on selection like so (in Selection sheet):
Here's the example spreadsheet:
https://docs.google.com/spreadsheets/d/1O1rZUstDNSXPdUVXvaDfPO4rAQs2cJWHimfGxbddtNU/edit#gid=232108540
How can I set value Cost in Services sheet to Selection sheet with script?
Try this:
function cost() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Services');
var rg=sh.getRange(2,1,sh.getLastRow()-1,2);
var vA=rg.getValues();
var costObj={}
for(var i=0;i<vA.length;i++) {
costObj[vA[i][0]]=vA[i][1];
}
var selsh=ss.getSheetByName('Selection');
var selrg=selsh.getRange(2,1,selsh.getLastRow()-1,2);
var vB=selrg.getValues();
for(var j=0;j<vB.length;j++) {
vB[j][1]=costObj[vB[j][0]];
}
selrg.setValues(vB);
//if you only want to set columnB you can do this instead of the above line
//var vC=vB.map(function(r){return [r[1]]});
//selsh.getRange(2,2,vC.length,1).setValues(vC);
}
As an onEdit():
function cost(e) {//Installable onEdit()
var sh=e.range.getSheet();
var name=sh.getName();
if(name!='Selection')return;
if(e.value && e.range.columnStart==1) {
e.range.offset(0,1).setValue(getCostObj()[e.value]);
}
}
function getCostObj() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Services');
var rg=sh.getRange(2,1,sh.getLastRow()-1,2);
var vA=rg.getValues();
var costObj={}
for(var i=0;i<vA.length;i++) {
costObj[vA[i][0]]=vA[i][1];
}
return costObj;
}