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()
Related
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
}
}
}
}
I've been trying to get this one to work without success so far.
I need to get the TaskNumber on the first column of the row I'm on and bring it to the destination sheet, so that I can update it there.
I have the following, which I'm tweaking to achieve my goal, but I guess I've bumped into my limitation walls:
function jump() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell();
var TaskNoCol = TaskNoRow.getColumn() == 1
var TaskNo = TaskNoCol.getValue;
var sheet = ss.getSheetByName('Updates');
//var Tasks = ss.getSheetByName("To Do List").getActiveRange(Tasks.getColum(1)).getValue();
var values = sheet.getRange("B:B").getValues();
var maxIndex = values.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sheet.setActiveRange(sheet.getRange(maxIndex + 2,2)).setValue(TaskNo);
}
Any help is appreciate.
Cheers,
A
If I understood you correctly, you want to:
Get the value in column A from the currently active row (in sheet To-Do List).
Find the first empty cell in column B (in sheet Updates) (start looking at row #8).
Copy the value that was retrieved in step 1 to the cell retrieved in step 2.
Set the cell retrieved in step 2 as the active cell.
If that's the case, you can do the following:
function jump() {
var ss = SpreadsheetApp.getActive();
// Step 1:
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell().getRow();
var TaskNoCol = 1;
var TaskNo = TaskNumberSheet.getRange(TaskNoRow, TaskNoCol).getValue();
// Step 2:
var sheet = ss.getSheetByName('Updates');
var firstRow = 8;
var column = 2;
var numRows = sheet.getLastRow() - firstRow + 1;
var values = sheet.getRange(firstRow, column, numRows).getValues().map(function(value) {
return value[0]
});
var i = 0;
for (i; i < values.length; i++) {
if (values[i] === "") break;
}
var targetRange = sheet.getRange(i + firstRow, column);
targetRange.setValue(TaskNo); // Step 3
sheet.setActiveRange(targetRange); // Step 4
}
function jump() {
var TargetRow=?;//Fillin target row
var TargetCol=?;//Fillin target column
var ss=SpreadsheetApp.getActive();
var TaskNumberSheet=ss.getSheetByName('To-Do List');
var TaskNoRow=TaskNumberSheet.getActiveCell().getRow();//Getting row from active cell
var TaskNoCol=1
var TaskNo=TaskNumberSheet.getRange(TaskNoRow,TaskNoCol).getValue();
ss.getSheetByName('Updates').getRange(targetRow,targetCol).setValue(TaskNo);
}
I have a to-do list app in google sheets. I have functions for filtering by "note type" and "done status" that can be in use at any given moment by the user.
I also have functions to easily add a new note of any given type. However, when running the function to add a new note, and the sheet is already filtered, I'm getting the following error:
"This operation is not supported on a range with a filtered out row."
Any advice on how I can add a row to a filtered range?
Here is the code that I am using to add a new note of a particular type:
function addNewCueNote() {
if( sheet.getSheetName() == sheetName ) {
var noteType = "CUE"
//ADDS ROW AND COPIES FORMULA DOWN
//SETS VARIABLES FOR LAST ROW AND LAST COLUMN
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn();
//INSERT LAST ROW
sheet.insertRowsAfter(lRow, 1);
//COPY FORMULAS DOWN FOR SPECIFIED COLUMNS
sheet.getRange(lRow,firstCopyCol,1,numColCopy).copyTo(sheet.getRange(lRow+1,firstCopyCol,1,numColCopy));
//SETS NOTE TYPE
sheet.getRange(sheet.getLastRow(),noteTypeCol).setValue(noteType);
}
Grab the existing filter, remove it from the sheet, add the new row, then recreate the filter using the criteria from the initial filter.
function addNewCueNote() {
var sheet = SpreadsheetApp.getActiveSheet(); // added to get code to run; not sure if you handle elsewhere
if (sheet.getSheetName() === sheetName) {
// Save state of existing filter before removing it
var oldCriteria = [];
var filter = sheet.getFilter();
if (filter != null) {
var oldNumColumns = filter.getRange().getNumColumns();
for (var c = 1; c <= oldNumColumns; c++) {
var criteria = filter.getColumnFilterCriteria(c);
if (criteria != null) {
oldCriteria.push([c, criteria.copy()]);
}
}
filter.remove();
}
//*** PUT YOUR ROW INSERT LOGIC HERE ***
// Recreate filter on new data range
var dataRange = sheet.getDataRange();
var newFilter = dataRange.createFilter();
if (filter != null) {
var newNumColumns = dataRange.getNumColumns();
for (var i = 0; i < oldCriteria.length && oldCriteria[i][0] <= newNumColumns; i++) {
newFilter.setColumnFilterCriteria(oldCriteria[i][0], oldCriteria[i][1]);
}
}
}
#Nick there is something wrong with your code logic. In any ways this is a working code
// *** I have to add this for tests ***
var firstCopyCol = 3;
var numColCopy = 2;
var noteTypeCol = 2;
var sheet = SpreadsheetApp.getActiveSheet();
var sheetName = 'MatchImport';
// ************************************
function addNewCueNote() {
if (sheet.getSheetName() === sheetName) {
var filter = sheet.getFilter();
if (filter) {
var dataRange = sheet.getDataRange();
var oldNumColumns = filter.getRange().getNumColumns();
var newNumColumns = dataRange.getNumColumns();
var criterias = {};
for (var c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
var criteria = filter.getColumnFilterCriteria(c);
if (criteria) criterias['_' + c] = criteria;
}
filter.remove();
}
// START OF YOUR INSERT LOGIC
var noteType = 'CUE';
// ADDS ROW AND COPIES FORMULA DOWN
// SETS VARIABLES FOR LAST ROW AND LAST COLUMN
var lRow = sheet.getLastRow();
var lCol = sheet.getLastColumn(); // This is never used
// INSERT LAST ROW
sheet.insertRowsAfter(lRow, 1);
// COPY FORMULAS DOWN FOR SPECIFIED COLUMNS
sheet
.getRange(lRow, firstCopyCol, 1, numColCopy)
.copyTo(sheet.getRange(lRow + 1, firstCopyCol, 1, numColCopy));
// SETS NOTE TYPE
sheet.getRange(sheet.getLastRow(), noteTypeCol).setValue(noteType);
//* * END OF YOUR INSERT LOGIC
if (!filter) return;
dataRange = sheet.getDataRange();
var newFilter = dataRange.createFilter();
newNumColumns = dataRange.getNumColumns();
for (c = 1; c <= oldNumColumns && c <= newNumColumns; c++) {
if (criterias['_' + c])
newFilter.setColumnFilterCriteria(c, criterias['_' + c]);
}
}
}
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;
}
}
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)
}