Set value based on drop down selection using script - google-apps-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;
}

Related

Matching cell values in different Google Sheets

Users input text in cell A1 of sheet1. I want to find an exact match in column G of sheet2, and get the row of that match. I'm new to GAPS and wrote a script to find matches all on one sheet. How do I modify it to look at sheet2?
function rowOfMatch(){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = sheet.getDataRange().getValues();
var inputName = sheet.getRange("A1").getValue();
for(var i = 0; i<data.length;i++){
if(data[i][6] == inputName){ //[6] to search column G
Logger.log((i+1))
return i+1;
}
}
}
function runOne(){
var ss=SpreadsheetApp.getActive();
var sh1=ss.getSheetByName('Sheet1');
var sh2=ss.getSheetByName('Sheet2');
var rg1=sh1.getRange(1,1,sh1.getLastRow(),1);
var rg2=sh2.getRange(1,7,sh2.getLastRow(),1);
var v1=rg1.getValues();
var v2=rg2.getValues().map(function(r){return r[0];});
for(var i=0;i<v1.length;i++) {
var row=v2.indexOf(v1[i][0])+1;
if(row>0) {
sh1.getRange(i+1,2).setValue(row);
}else{
sh1.getRange(i+1,2).setValue('Not Found');
}
}
}
Animation:

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:

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

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

How to find matching values of two ranges and edit the cell next to the common values?

I hire out cameras to film students within a university. To keep track of what I have in stock and which students have a camera, I have created a google sheet.
The extended version of this example includes over a hundred cameras, so to make my life easier, I'd like to enter into the BASKET the name of the cameras being hired, then type the name of the student hiring it out into the NAME cell.
Students may hire out more than one camera at a time, and so, upon clicking the 'Check Out' button which in turn triggers the function 'checkOut', I would like to change the cell next to the cameras referenced from 'Available' to the students name.
I'm new to Google Apps Script but I know the first step to this is listing each variable needed, then find the basket values within the Equipment List and replace the offset cell with the Name value.
Here are my variables:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var basket = ss.getRange("A2:A");
var name = ss.getRange("C2");
var equipmentlist = ss.getRange("E2:E11");
function checkOut() {
}
I hope all this makes sense. I have not been able to find anything online about finding matching values of two different ranges and changing the cell next to those values.
Much appreciated!
Try this:
function checkOut() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var name = sh.getRange("C2").getValue();
if(name && name.length>0 && getColumnHeight(1)>1) {
var basketrg = sh.getRange(2,1,getColumnHeight(1)-1,1);
var basket = basketrg.getValues();
var equipmentlist = sh.getRange(2,5,getColumnHeight(5)-1,1).getValues();
var availabilitylist = sh.getRange(2,6,getColumnHeight(6)-1,1).getValues();
for(var i=0;i<equipmentlist.length;i++) {
for(var j=0;j<basket.length;j++) {
if(equipmentlist[i][0]==basket[j][0]){
availabilitylist[i][0]=name;
}
}
}
sh.getRange(2,6,availabilitylist.length,1).setValues(availabilitylist);
setCameraList();
basketrg.clearContent();
sh.getRange('C2').clearContent()
}else{
SpreadsheetApp.getUi().alert('Invalid Input: No name provided or no cameras selected in checkOut() function.');
}
}
function getColumnHeight(col,sh,ss){
var ss=ss || SpreadsheetApp.getActive();
var sh=sh || ss.getActiveSheet();
var col=col || sh.getActiveCell().getColumn();
var rg=sh.getRange(1,col,sh.getLastRow(),1);
var vA=rg.getValues();
while(vA[vA.length-1][0].length==0){
vA.splice(vA.length-1,1);
}
return vA.length;
}
A Simple CheckOut System
To setup this system you will want to copy all of the scripts bellow into the Code.gs file in the script editor of a Spreadsheet. Name your sheet 'CheckOut'. You will also want to created a named range named "AvailableCameras" and the range will be 'CheckOut!K2:K1000' and a Data Validation for 'CheckOut!A2:A20' or however large you want your basket to be.
You can add as many cameras as you wish (well within reason... the more you add the slower it runs). As you checkout cameras the list of camera choices in your basket gets smaller. When cameras are returned you can clear out the names from the available list and the system will add the available label back for you and it will also increase the number of available cameras.
This is what the Spreadsheet looks like:
Code.gs:
function onOpen() {
makeMenu();
}
function makeMenu(){
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('Check Out', 'checkOut')
.addItem('Set Camera List', 'setCameraList')
.addItem('Set Available List', 'setAvailableList')
.addToUi();
}
function checkOut() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getActiveSheet();
var name = sh.getRange("C2").getValue();
if(name && name.length>0) {
var basketrg = sh.getRange(2,1,getColumnHeight(1)-1,1);
var basket = basketrg.getValues();
var equipmentlist = sh.getRange(2,5,getColumnHeight(5)-1,1).getValues();
var availabilitylist = sh.getRange(2,6,getColumnHeight(6)-1,1).getValues();
for(var i=0;i<equipmentlist.length;i++) {
for(var j=0;j<basket.length;j++) {
if(equipmentlist[i][0]==basket[j][0]){
availabilitylist[i][0]=name;
}
}
}
sh.getRange(2,6,availabilitylist.length,1).setValues(availabilitylist);
setCameraList();
basketrg.clearContent();
sh.getRange('C2').clearContent()
}else{
SpreadsheetApp.getUi().alert('Invalid Input: No name provided in checkOut() function.');
}
}
function setCameraList() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('CheckOut');
var LISTrg=ss.getRangeByName('AvailableCameras');
var rg=sh.getRange(2,5,getColumnHeight(5)-1,2);
var vA=rg.getValues();
LISTrg.clear();
var listA=[];
for(var i=0;i<vA.length;i++) {
if(vA[i][1]=='Available') {
listA.push([vA[i][0]]);
}
}
sh.getRange(2,11,listA.length,1).setValues(listA);
}
function onEdit(e) {
var rg=e.range;
var sh=rg.getSheet();
var name=sh.getName();
if(name!='CheckOut'){return;}
if(rg.columnStart==1 && rg.rowStart>1) {
setCameraList();
}
if(rg.columnStart==6 && rg.rowStart>1) {
setAvailableList();
setCameraList();
}
}
function setAvailableList() {
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('CheckOut');
var rg=sh.getRange(2,6,getColumnHeight(5)-1,1);
var vA=rg.getValues();
for(var i=0;i<vA.length;i++) {
if(!vA[i][0] && vA[i][0].length==0) {
vA[i][0]='Available';
}
}
rg.setValues(vA);
}
function getColumnHeight(col,sh,ss){
var ss=ss || SpreadsheetApp.getActive();
var sh=sh || ss.getActiveSheet();
var col=col || sh.getActiveCell().getColumn();
var rg=sh.getRange(1,col,sh.getLastRow(),1);
var vA=rg.getValues();
while(vA[vA.length-1][0].length==0){
vA.splice(vA.length-1,1);
}
return vA.length;
}