Update replace values from one sheet to another google script - google-apps-script

I'm trying to figure out how to update rows if they are found in sheet1 with data from sheet2 based on a key column. Also if the key is not found then add a new row. I have figured out iterating over the range from sheet2, but not how to lookup the value in sheet1. Any suggestions welcome. (I upddated the post here.)
function getJulaUpdates2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Franco-Jula");
var range1 = sheet1.getDataRange();
var values1 = range1.getValues()
var sheet2 = ss.getSheetByName("Jula-Alternatives");
var range2 = sheet2.getDataRange();
var values2 = range2.getValues()
// Iterate through sheet2
// Start at 1 to avoid header row
for (var i = 1; i < values2.length; i++) {
// Now loop through Values1 sheet
for (var x = 1; x < values1.length; x++) {
logthis = values2[i][0] + "," + values1[x][1];
if (values1[x][1] == values2[i][0]) {
values1[x][2] = values2[i][2]
values1[x][12] = values2[i][12]
values1[x][13] = values2[i][13]
Logger.log(logthis);
}
}
}
range1.setValues(values1)
}

Related

How to loop through cells in Google Sheets and log information if specific variables exist

You will need this link to solve this: - https://docs.google.com/spreadsheets/d/11PjVSWPfqOBPSej3AlQ-_T8Bws66kevR08Q2NRTmVcE/edit?usp=sharing
So this is a tricky one. I am looking to loop through the name in Sheet1 Column A, and also loop through the type in Column C. Then if Column A in Sheet1 matches the name of column A in Sheet2, AND the type is "pickup" I want to log the other information that is in Sheet 1 inside of Column C on Sheet 2. Log the things like "State", "Location", "City" next to the identical name in Sheet 2. I hope that makes sense.
I know I probably need to use a loop within a loop to do all this, but this is as far as I can get as I cannot figure out how to write the loop and then log the rows where the 2 names match.
function myFunction() {
function pullDeliveryNotes()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var dataRange = sheet.getDataRange();
var dataRange2 = sheet2.getDataRange();
var rng = sheet.getRange(2,1, dataRange.getLastRow()-1,dataRange.getLastColumn());
var rng2 = sheet.getRange(2,3, dataRange.getLastRow()-1,dataRange.getLastColumn());
var rng3 = sheet2.getRange(2,1, dataRange2.getLastRow()-1,dataRange2.getLastColumn());
var rngA = rng.getValues().toString()
var rngB = rng2.getValues().toString()
var rngC = rng3.getValues().toString()
for(var i = 0; i < rng.length; i++) {
for (var x = 0; x < rng2.length; x++) {
for (var y = 0; y < rng3.length; y++) {
if (rng[i][x][y].includes(rng3[i][x][y]) && rng2[i][x][y] === "pickUp") {
Logger.log("We got it")
}
}
}
}
}
}
Based on your problem statement.
Try this sample script:-
function checkValues() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const ssSource = ss.getSheetByName('Sheet1')
const ssTarget = ss.getSheetByName('Sheet2')
const sourceRange = ssSource.getDataRange().getValues().filter(r=> r[2] === 'Pickup'); // Filtering only pickup values
const targetRange = ssTarget.getDataRange().getValues();
for(var i = 0 ; i < sourceRange.length ; i++)
{
for(var j = 1 ; j < targetRange.length ; j++)
{
if(sourceRange[i][0] === targetRange[j][0]) // if name matches
{
ssTarget.getRange(`C${j+1}`).setValue(`${sourceRange[i][3]},${sourceRange[i][4]},${sourceRange[i][5]}`) // set values in column C
}
}
}
}

Delete column if all cells after row 1 are blank

I have a sheet with a bunch of headings but in some sheets the cells after the header row are blank. I want to delete the column if all cells are blank except row 1 (header).
I have cobbled together the code below, however, it only retains the last array. Where am I going wrong!!
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
var currentSheet = ss.getActiveSheet();
var currentSheetRange = currentSheet.getDataRange();
var currentSheetVals = currentSheetRange.getValues();
var currentSheetLC = currentSheet.getLastColumn();
var currentSheetLR = currentSheet.getLastRow();
var finalData = [];
let finalDataVal
var c;
var r;
for (r = 1; r < currentSheetLR; r++) {
for (c = 0; c < currentSheetLC; c++) {
if (currentSheetVals[r][c] != "") {
finalData.push(currentSheetVals[r][c]);
}
}
}
Logger.log(finalData);
var finalDataLength = finalData.length;
var finalDataColLength = finalData[0].length;
currentSheet.getRange(5, 1, finalData.length, finalData[0].length).setValues(finalData);
}
Thanks in advance for anyone who has a solution!
To delete all empty columns (headers excluded):
Retrieve the data range without headers
Loop through each of the columns and use join() to verify either all column entries are empty
Use deleteColumn() to delete empty columns
Loop backwards to make sure that the deletion of columns does not mess up your column positions
Sample:
function myFunction() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
var currentSheet = ss.getActiveSheet();
var currentSheetLC = currentSheet.getLastColumn();
var currentSheetLR = currentSheet.getLastRow();
var SheetRangeWithoutHeaders = currentSheet.getRange(2, 1, currentSheetLR- 1, currentSheetLC);
var currentSheetVals = SheetRangeWithoutHeaders.getValues();
var c;
for (c = currentSheetLC; c > 0; c--) {
var columnData = currentSheetVals.map(row=>row[c-1]);
console.log("columnData: " + columnData);
if(columnData.join("") ==""){
console.log("Column is empty");
currentSheet.deleteColumn(c);
}
}
}
References:
Array.prototype.map()
join()
deleteColumn()

Find all empty cells in several columns

Is there an easy way to color the rows containing empty cells in specific columns? So far, I only came up with a solution to highlight the cells themselves, but this script also takes some time to run.
Will appreciate any advice or guidance!
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs')
var columns = ['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK'];
for(var col in columns){ //loop to iterate the desired ranges
var range = sheet.getRange(columns[col]);
//range.activate();
var values = range.getValues();
var formulas = range.getFormulas();
//for each row that data is present
for(var i = 0; i < values.length; i++) { //loop to iterate the rows
for( var j = 0; j< values[i].length ; j++){ //loop to iterate the columns
var cell = range.getCell(i+1, j+1);
if ( values[i][j] == "" )
{
cell.setBackground('red');
cell.activate
}
else
{ cell.setBackground('white')
}
Use ConditionalFormatRuleBuilder instead. This will create a Conditional format rule in your Sheet.
Try this.
Code:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs');
var ranges = sheet.getRangeList(['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK']);
var rule = SpreadsheetApp.newConditionalFormatRule()
.whenCellEmpty()
.setBackground('red')
.setRanges(ranges.getRanges())
.build();
var sheetRules = sheet.getConditionalFormatRules();
sheetRules.push(rule);
sheet.setConditionalFormatRules(sheetRules);
}
Output:
Conditional Formatting:
Highlighting empty cells using rangeList.setBackgroundColor(color) ​
In my code below, I collected the cell name of the empty cells and use it to create a RangeList. Then I used the RangeList to set the background to red. This reduced the Google Sheet Service calls from thousands to 11.
function columnToLetter(column)
{
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
function highlightEmptyCell(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('FRs & NFRs')
var rangeList = sheet.getRangeList(['J17:J','L17:L', 'V17:V', 'AB17:AB','AI17:AI', 'AK17:AK']);
var rangeArray = rangeList.getRanges();
var ranges = [];
rangeArray.forEach(range =>{
var data = range.getValues();
for( var i = 0; i < data.length; i++ ){
for( var j = 0; j < data[0].length; j++ ){
if(data[i][j] == ""){
var cellName = columnToLetter(range.getColumn()) + (i + 17)
ranges.push(cellName);
}
}
}
});
sheet.getRangeList(ranges).setBackground("red");
}
Reference:
Class ConditionalFormatRuleBuilder
RangeList.setBackgroundColor(color)

Google Sheets - Two-way lookup pulling data from multiple sheet tabs

I've been working on a sheet where I want to have and input tab and output tab.
The input tab is basically a table and the output tab will be a calendar (of sorts).
In my example:
Sheet1 = input tab
Sheet2 = output tab
I wish to have a vlookup that will pull its search_key from Sheet2 (output) and search it against a range in Sheet1.
I've been messing around with the following (green cell Sheet2 in example):
=IFERROR(VLOOKUP(A2,Sheet1!$A$2:$C$7,MATCH(B1,Sheet1!$A$2:$C$7,0),False))
I had also tried a variation of this using hlookup instead of MATCH but didn't have much luck with it.
The problem I have is that I no longer know where to place my column index. In my example sheet I have it working with a one way vlookup (blue cell Sheet2) that returns the desired value from Sheet1 (Length Column) using this index. Is it not possible to do so in the two way lookup??
Here's a link to the example:
https://docs.google.com/spreadsheets/d/1_nqH-XOxNhQAUVJzesNBZeMci7AV9RowSQUnptAruPc/edit?usp=sharing
Try running this function in Apps Script:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet1 = ss.getSheetByName('Sheet1');
var sheet2 = ss.getSheetByName('Sheet2');
var firstRow = 2;
var numRows = sheet1.getLastRow() - 1;
var firstCol = 1;
var numCols = sheet1.getLastColumn();
var inputData = sheet1.getRange(firstRow, firstCol, numRows, numCols).getValues();
var numBrands = sheet2.getLastRow();
var outputRange = sheet2.getDataRange();
var outputData = outputRange.getValues();
// Iterating through each row in Sheet1 data:
for(var i = 0; i < numRows; i++) {
// Iterating through each row in Sheet2:
for(var j = 1; j < outputData.length; j++) {
// Iterates through each cell for each row in Sheet2.
for(var k = 1; k < outputData[0].length; k++) {
var inputBrand = inputData[i][0];
var outputBrand = outputData[j][0];
var inputDate = inputData[i][1];
var outputDate = outputData[0][k];
// It checks whether the date and brand corresponding to each cell
// (same row or column) matches the date and brand in the current
// row in Sheet1
if(inputBrand == outputBrand && inputDate.toString() == outputDate.toString()) {
var inputLength = inputData[i][2];
sheet2.getRange(j+1, k+1, 1, 1).setValue(inputLength);
}
}
}
}
}

Find and write to next blank cells in a column using App maker

I need help with finding a number from a specific row in column A and write next to its blank cells in two different columns of the same row. e.g Find a number in COLUMN A2, Write to cells in COLUMN B2 and C2.
I have currently used filters and it hasn't helped.
function filterRange(filteredRange) {
return filteredRange == [2.0];
}
function findCellByValue() {
var ss = getSpreadSheet();
var sheet = ss.getActiveSheet();
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
var range = values[i];
var filtered = range.filter(filterRange);
var newValue = filtered.concat(["Tee", "uhuuu"]);
console.log(newValue);
var ssheet = sheet.getRange("B2:C2");
console.log(ssheet.setValues([newValue]));
}
}
Anyways I have managed to find a workaround it though it is not the best possible solution but for this, it works.
function findCellByValue(cellValue) {
console.log(cellValue);
var ss = getSpreadSheet().getActiveSheet();
var range = ss.getRange("A2:A").getValues();
for(var i = 0; i < range.length; i ++)
{
if(range[i] == cellValue)
{
var Arrayvalues = range[i].concat(["test1","test2"]);
ss.getRange(i+2,1,1,3).setValues([Arrayvalues]);
i = range.length;
}
}