How to Ignore Empty Rows in getRange()getValues() with A1 notation - google-apps-script

Teaching myself how to code in Google Apps Script and I can't figure out how to ignore blank rows in the array, based on getRange A1 notation.
This other post works if my range is only one column, but I'm trying to do it if a whole row is blank, not just the value in one column.
How to ignore empty cell values for getRange().getValues()
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sample");
var data = sheet.getRange("A1:E").getValues();
var filtered = data.filter(String);
Logger.log(filtered);
}
In the code sample above, my log still shows all of the blank rows after the populated rows. If I change the A1 notation to A1:A, then it works, but I want to filter based on the whole row.
Thanks for helping a newbie.

Try this:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("sample");
var data = sheet.getRange(1,1,sheet.getLastRow(),5).getValues();
var filtered = data.filter(String);
Logger.log(filtered);
}
You could do it this way too.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet2");
var data = sheet.getRange("A1:F").getValues();
var filtered = data.filter(function(r){
return r.join("").length>0;
});
Logger.log(filtered);
}

Related

copying not a scpecific number of rows

first I'm not good in coding just trying figure my way and make what i need.
so my function is to copy data from sheet to sheet and delete the data after finishing.
my issue is small but can't find a solution for it, it's when I'm copying it copy just 12 rows, but for me i want it to copy as much rows will be.
my final code i want it to copy the rows that have a specific word, but for now I'm searching for a solution for this issue.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Sheet1");
var pasteSheet = ss.getSheetByName("Sheet2");
// get source range
var range = copySheet.getRange(2,1,12,4);
var source = range.getValues();
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,12,4).setValues(source);
range.clearContent();
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,12,1);
// clear source values
Browser.msgBox('Commande Confirmer');
}```
this is my code
thanks in advance
Description
In this example, the script gets all values from Sheet1, not just 12 rows. It then uses the Array.filter() to get all rows that have the word "Hello" in Column A. Not knowing how many rows match the filter I use source.length to tell getRange() how many rows to output.
Code.gs
function test() {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Sheet1");
var pasteSheet = ss.getSheetByName("Sheet2");
// get source range
var range = copySheet.getDataRange(); // Get all values
var source = range.getValues();
source = source.filter( row => row[0] === "Hello" );
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,source.length,source[0].length).setValues(source);
// clear source values
range.clearContent();
Browser.msgBox('Commande Confirmer');
}
catch(err) {
console.log(err);
}
}
Reference
Sheet.getDataRange()
Array.filter()

I am trying to only activate the worksheet of which the value is in a specific cell

I have a formula in worksheet 'Price History' cell E21 that changes to different worksheet names automatically depending on what other cells are equaling too. The script I have is returning TypeError: newSheetName.getRange is not a function. In the below script i tried to copy a blank cell above E21 and paste the cell into a blank cell on the specified worksheet but that didn't help. I am trying to only activate the worksheet of which the value is in E21. Thank you
function MyAccount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Price History");
var newSheetName = sheet.getRange("E21").getValue();
sheet.getRange("E20").copyTo(newSheetName.getRange("C1"), { contentsOnly: true });
}
This line var newSheetName = sheet.getRange("E21").getValue(); doesn't set the variable newSheetName as a sheet but a string value.
SUGGESTION:
Since you have mentioned that the value of cell E21 basically contains worksheet name that is randomly changing, perhaps you can still try using getRangeByName(name) method as this will return the sheet with the given name & then you can get the range of that sheet. See this sample tweaked script below:
UPDATED
function MyAccount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Price History");
var newSheetName = ss.getSheetByName(sheet.getRange("E21").getValue());
var Direction=SpreadsheetApp.Direction;
var lastRowOfC = ss.getRange("C"+(ss.getLastRow()+1)).getNextDataCell(Direction.UP).getRow() + 1; //Get the last row of column C on any worksheet
sheet.getRange("E20").copyTo(newSheetName.getRange(lastRowOfC,3), { contentsOnly: true });
}
Getting the last row script was derived from one of the answers from Determining the last row in a single column (Getting last row on a column that contains empty gaps)
Sample test on my end:
NOTE: It would also be better if you could share a sample sheet that you're using in case I have misunderstood your setup.
UPDATED
After running the script, the test cell value was copied to the destination sheet called NewTestSheet on the last row of column C, which is C4
You are trying to use a String value as a Sheet. Instead, use the sheet name to get a new sheet, then copy to the new range.
function MyAccount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Price History");
var copyRange = sheet.getRange("E20");
var nameRange = sheet.getRange("E21");
copyRange.copyTo(ss.getSheetByName(nameRange.getValue()).getRange("C1"), { contentsOnly: true });
}
Or,
function MyAccount() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Price History");
var copyValue = sheet.getRange("E20").getValue();
var nameRange = sheet.getRange("E21");
ss.getSheetByName(nameRange.getValue()).getRange("C1").setValue(copyValue);
}

Having problems with custom function

I am converting some spreadsheets from Excel to Google Sheets, and there is a function I am trying to do which gets the code and apply the function. For example I have a list of codes in a column and the next 5 columns with texts. I want to type =myFunction("code") and I would like to return the value with this formula =vlookup(code;A1:F30;3;0), that would return the column 3 with the row the code is.
I've tried these:
function myFunc(code) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var cell = sheet.getRange(getCell);
var test = cell.setFormula('=VLOOKUP('+code+';a1:b10;2;0)')
return test;
}
it says I don't have permission to call setFunction,
function gettext(code) {
var func = '=VLOOKUP("'+ code +'";\'VA-Texte\'!A1:I383;\'VA-Texte\'!E1;0)';
return func;
}
it prints the exact code I need, but does not act like a formula.
Your code can't be evaluated because we don't know the value of getCell.
In the code below "lookup" is a named range. The range is Cell E4 which contains the value "ghi", which is the search term.
function test01(){
var abc = "lookup";
so5693959103(abc);
}
function so5693959103(abc) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "56939591";
var sheet = ss.getSheetByName(sheetname);
// Lookup value is the named range = lookup which is found in E4
var vlookupformula03 = "=VLOOKUP("+abc+",A1:B10,2,0)";
//insert formula into cell E8
var targetRange03 = sheet.getRange("E10");
targetRange03.setFormula(vlookupformula03);
Logger.log("DEBUG: result03 = "+targetRange03.getValue());
}
Vlookup screenshot
Edit
This revision will work for a function value of =mylookup("xxx"), where 'xxx' is the lookup value.
In the example below, the lookup value is 'ghi'
/*
Imitates the Vlookup function. Receives:
search - The desired value to look for in the column.
Once the cell of the [search] has been found, the returned parameter would be the value of the cell which is 1 cell to the right of the found cell.
*/
function mylookup(search) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "56939591";
var sheet = ss.getSheetByName(sheetname);
var thevalue = search;
var lastRow=sheet.getLastRow();
var data=sheet.getRange(1,1,lastRow,2).getValues();
for(i=0;i<data.length;++i){
if (data[i][0]==thevalue){
return data[i][1];
}
}
}
Mylookup function

Google Sheets function to rename sheet to equal cell value

I'm trying to get my sheet names to equal cell values, whether it be text or numbers, but I've come up short.
After numerous google searches, and testing, this is as close as I've gotten to an answer.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[1]
var cell = sheet.getRange("A2")
sheets[3].setName(cell);
}
You need to getValue¹ from the range you got.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[1]; //Sheet 2
var cell = sheet.getRange("A2");//Sheet2!A2
var value = cell.getValue();//Added
sheet.setName(value);//Sheet2 name changed
}

How to get number of sheet from list

What script should do. First, get sheet names from range on sheet List_1. Then, using this array of names, put some data only on these sheets.
https://docs.google.com/spreadsheets/d/1Xdws6Vr6YVXuj19mvpOvkpJokOfY2T7Sh1aMpous_Xw/edit#gid=0
function VList() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetNames = ss.getSheetByName("List_1");
var rangeNames = sheetNames.getRange("B3:B5").getValues();
for (var sheetId = 0; sheetId<sheets.length; sheetId++){
if(sheets[sheetId].getSheetName() == rangeNames) {
ss.getRange("C1").setValue("done");
}
}
}
Problem. When script starts - nothing happens. How to get number of sheet and vlookup only on them? Maybe, exist some function like "getSheetId" which can get number of sheet.
Solved, thanks to bruce.
function VList() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var sheetNames = ss.getSheetByName("List_1").getRange("B3:B5").getValues();
sheetNames.forEach(function(row) {
var sheet = ss.getSheetByName (row[0]);
if (!sheet) throw 'missing sheet ' + row[0];
sheet.getRange("c1").setValue ("done");
});
}
getValues() returns a two dimensional array, which you then compare with a string value - so that will never be true.
Once you fix that, you will still be updating the same cell, C1 with 'done' multiple times - ss points to the List_1 sheet - I assume you mean to update the sheet whose name is in the list.
Why not just use the list in b3:b5 to simply get each sheet by name and update it? There's no need to go through the sheets list since you already know their names.
something like
ss.getSheetByName("List_1").getRange("b3:b5").getValues()
.forEach(function(row) {
var sheet = ss.getSheetByName (row[0]);
if (!sheet) throw 'missing sheet ' + row[0];
sheet.getRange("c1").setValue ("done");
});