duplicate row based on cell value - google-apps-script

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:

Related

How to set up script that will automatically copy a row from sheet 1 to sheet 2 with specified background color

I want to extract rows with bg color yellow from sheet 1 to sheet 2 in google sheets. A script, macro or button would be great so I only have to set it up once and when a row is highlighted it will automatically be copied to sheet 2. Is this possible?
function moveYellow() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var csh=ss.getSheetByName('Sheet2');
var rg=sh.getRange(2,1,sh.getLastRow()-1,sh.getLastColumn());
var v=rg.getValues();
var b=rg.getBackgrounds();
var d=0;//deleted row counter
for(var i=0;i<v.length;i++) {
if(b[i][0]=='#ffff00') {
csh.appendRow(v[i]);
//sh.deleteRow(i+2-d++);
}
}
}
This copies only columns A,C,E
function runOne() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('Sheet1');
var csh=ss.getSheetByName('Sheet2');
var rg=sh.getRange(2,1,sh.getLastRow()-1,sh.getLastColumn());
var v=rg.getValues();
var b=rg.getBackgrounds();
var d=0;//deleted row counter
for(var i=0;i<v.length;i++) {
if(b[i][0]=='#ffff00') {
csh.appendRow(v[i].map(function(c,i){if(i==0 || i==2 || i==4){return c;}}).filter(function(e){return e}));
//sh.deleteRow(i+2-d++);
}
}
}

Copy and paste the data from Sheet1 to Sheet2 and then delete the entered data without deleting the function in Sheet1

Copy the data in Sheet1 from Row 4 to Row 13 and from Column C to Column G and paste it into Sheet2 and clear the entered data without deleting the function in Column d on Sheet1
Example sheet
function runOne() {
var ss=SpreadsheetApp.getActive();
var sh1=ss.getSheetByName('Sheet1');
var sh2=ss.getSheetByName('Sheet2');
var rg=sh1.getRange(4,3,sh1.getLastRow()-3,5);
var v=rg.getDisplayValues();
var lr;
for(var i=0;i<v.length;i++) {
if(v[i].join('').length==0) {
lr=i;
break;
}
}
var rg1=sh1.getRange(4,3,lr,5);
var vA=rg1.getDisplayValues();
var fA=rg1.getFormulas();
rg1.copyTo(sh2.getRange(sh2.getLastRow()+1,1),{contentsOnly:true});
for(var i=0;i<vA.length;i++) {
for(var j=0;j<vA[i].length;j++) {
if(!fA[i][j]=='') {
vA[i][j]='';
}
}
}
rg1.setValues(vA);
rg1.setFormulas(fA);
}

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++);
}
}
}

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;
}

Deleting Cells in Google Sheets without removing a whole row

I have the code as below that currently deletes the entire row if 'delete' is in the 4th cell of that row. Is it posible to just delete the 3 cells to the left as well as the cell I have written 'delete' in, rather than the whole row (I have other content in Cell B16 for example I don't want to delete?
I haven't been able to find a .deleteCell function. Is there another way to do this?
function deleteRows() {
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[4] == 'delete') { // This searches all cells in columns A (change to row[1] for columns B and so on) and deletes row if cell is empty or has value 'delete'.
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
Delete with Shift Up or Shift Left
This will delete a cell and shift the data up or left depending upon the shift parameter.
function delCellAndShift(row,column,shift)
{
if(row && column)
{
var shift=(typeof(shift)!='undefined')?shift:'left';
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getDataRange()
var vA=rg.getValues();
if(shift=='left')
{
var tA=vA[row-1];
tA.splice(column-1,1);
tA.push('');
vA[row-1]=tA;
rg.setValues(vA);
}
if(shift=='up')
{
var vB=Object.keys(vA[0]).map(function (c) { return vA.map(function (r) { return r[c]; }); });
var tA=vB[column-1];
tA.splice(row-1,1);
tA.push('');
vB[column-1]=tA;
vA=Object.keys(vB[0]).map(function (c) { return vB.map(function (r) { return r[c]; }); });
rg.setValues(vA);
}
}
else
{
var s='Invalid Inputs for delCellAndShift.<br /><input type="button" value="Close" onClick="google.script.host.close();" />';
var ui=HtmlService.createHtmlOutput(s);
SpreadsheetApp.getUi().showModalDialog(us, 'Invalid Inputs')
}
}
I tested it using the following functions to setup my data and run the main function.
function testDelCell()
{
delCellAndShift(3,7,'up');
}
function testsetupfordelcell()
{
var rs=10;
var cs=10;
var ss=SpreadsheetApp.getActive();
var sh=ss.getActiveSheet();
var rg=sh.getRange(1,1,rs,cs);
var vA=rg.getValues();
for(var i=0;i<rs;i++)
{
for(var j=0;j<cs;j++)
{
vA[i][j]=Utilities.formatString('%s,%s',i,j)
}
}
rg.setValues(vA);
}
This is a sample of it shifting left:
This is a sample of it shifting up:
So the problem is:
How do I move all the cells beneath a given cell one row up (overwriting the given cell value)?
The code to do this would be:
function deleteCell(sheet, cellx, celly){
var wholeSheet = SpreadsheetApp.openById(sheet).getRange("A1:F").getValues();
for(var i = celly; i<wholeSheet.length; i++){
wholeSheet[cellx][i] = wholeSheet[cellx][i+1];
}
SpreadsheetApp.openById(sheet).setValues(wholeSheet);
}