I'm trying to find the index of a value in an array. The array is a spreadsheet, and I want to search down the rows till it finds the value in the active cell and returns the row number/index.
I have tried this searching across columns and it works fine, but when trying to search down rows it does something I can't quite figure out.
var datass =SpreadsheetApp.getActiveSpreadsheet().getSheetByName('####')
var actCell = ss.getActiveCell()
var name =datass.getRange(3,2,datass.getLastRow(),1).getValues();
var nameIndex = name[0].indexOf(actCell.getValue)
nameIndex always returns -1 unless name[#]is the right index number. even if I omit a # it returns -1.
logger.log(name) shows that the pulled is corrected but because of the way it pulls the data index only searches on []
it shows as:
[[##], [##], [##]]
when this functions correctly searching along columns instead of rows, the log shows as
[##,##,##,##]
how do can I search down my list and get the row number based off the value in my active cell?
(Option 1)
As what was mentioned by #Cooper, you can use Range.createTextFinder(findText) to search for a specific string within your selected range.
(Option 2)
You can convert your 2-d array to 1-d array to be able to search for a specific value using Array.prototype.indexOf()
Sample Code:
var datass =SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet15");
var actCell = datass.getActiveCell();
var rowStart = 3;
var name =datass.getRange(rowStart,2,datass.getLastRow()-2,1).getValues().flat();
Logger.log(name);
Logger.log(actCell.getA1Notation());
Logger.log(actCell.getValue());
var nameIndex = name.indexOf(actCell.getValue());
Logger.log("match found at row: "+(rowStart+nameIndex));
What it does?
Select a sheet and get its active cell.
Get the values of a given range. This will return a 2-d array values. Convert it to 1-d array using Array.prototype.flat(). Your array will be from this [[##], [##], [##]] to [##,##,##]
Use Array.prototype.indexOf() to search for a value within the array.
Note:
When you select the range of values, you start at row3. To get the actual row index of the matched value you also need to add an offset 3 to the index found in your name array
Output:
4:59:23 AM Notice Execution started
4:59:24 AM Info [A, B, C, D, E, F, G]
4:59:24 AM Info A1
4:59:24 AM Info D
4:59:24 AM Info match found at row: 6
4:59:24 AM Notice Execution completed
Related
I found some code that almost does what i need and have tried playing around with it to get it to work, but no luck. I get an export with data with dates in the last column on every row.
I simply want to copy the last column rows of dates to the tabs with the same name.
function MoveDate_FourthDEC() {
var ss=SpreadsheetApp.getActive();
var sh1=ss.getSheetByName("Import");
var sh2=ss.getSheetByName("4/12/2020");
var rg1=sh1.getRange(2,1,sh1.getLastRow(),32);//starting at column2
var data=rg1.getValues();
for(var i=0;i<data.length;i++) {
// 13 = collected should be in this column which is column N
if(data[i][31]=="4/12/2020") {
sh2.appendRow(data[i]);
}}}
Explanation:
Your goal is to copy all the rows for which column AF matches the names of the sheets.
To begin with, you can use forEach() to iterate over every sheet. For each sheet, you want to check whether the sheet name matches a date in column AF. If it does, then you need to filter only the rows that contain this date in column AF and store them into an temporary array:
let temp_data = data.filter(r=>r[31]==sh.getName());
Then you can efficiently copy and paste all the relevant rows to the matching sheet:
sh.getRange(sh.getLastRow()+1,1,temp_data.length,temp_data[0].length).setValues(temp_data);
Side notes:
When dealing with date objects you need to consider the display values in the sheet. This is why I am using getDisplayValues instead of getValues.
Since data starts from the second row, you need to deduct one row from the last row with content, to get the correct range:
getRange(2,1,sh1.getLastRow()-1,32)
I am using includes to check if the sheet name matches the last column. In order to use includes you need to flatten the 2D array that is returned by the getDisplayValues function.
Solution:
function MoveDate_FourthDEC() {
const ss = SpreadsheetApp.getActive();
const sh1 = ss.getSheetByName("Import");
const shs = ss.getSheets();
const dts = sh1.getRange('AF2:AF'+sh1.getLastRow()).getDisplayValues().flat();
const data=sh1.getRange(2,1,sh1.getLastRow()-1,32).getDisplayValues();
shs.forEach(sh=>{
if (dts.includes(sh.getName())){
let temp_data = data.filter(r=>r[31]==sh.getName());
sh.getRange(sh.getLastRow()+1,1,temp_data.length,temp_data[0].length).setValues(temp_data);
}});
}
I want to import rows from one google sheet to the other, however source sheet imports a number of empty rows. Now I use a filter function to get rid of these rows but they will not disappear, can anyone tell me why?
var a = SpreadsheetApp.openByUrl("url").getSheetByName("Admin Use Only").getRange(4,1,6,21).getValues();
var b = SpreadsheetApp.getActive().getSheetByName('Credit_Detail');
b.getRange(b.getLastRow() +1, 1, a.length,21).setValues(a);
//filter function below:
var otarget=b.getRange(2,1,b.getLastRow()-1, 26).getValues();
var data=otarget.filter(function(r){
return !r.every(function(cell){
return cell === "";});
});
Logger.log(data);
b.getRange("A2:Z").clearContent();
b.getRange(3,1,data.length,data[0].length).setValues(data);
here's how I would do it. First, create an variable to store the array of the source. then run a for loop scanning the first column for empties. something like: for (var i = 0, i < data.length; i++) { if (data[i][0] != '') { XXXX } }
XXXX means that you can either put a code to create a new set of array which can be passed to the target sheet at once or use append row to transfer non blank rows to the target sheet one by one.
Note: Creating a new array to store non-empty rows would speedup the execution time if you are dealing with large data, thousands of rows.
I have 10 rows of data on my input step, i transform them in a for-loop and i should get more than 10 rows, but in this case i get the last transform of each iteration that the loop have for each data
I tried to use appendToFile() but the result data is not useful and pentaho read it as a unique header
On my alert() method i can see that the for loop transform the data.
var PERIODO = 2
var i
var fecha_final
//var ruta_acess ="D:\TEST.accdb"
//var contenido
////var contenido2
//var arreglo_completo
for (i=0; i<=PERIODO; i++){
fecha_final = dateAdd(FECHA_INICIO,"d",i)
Alert(i)
}
As I show in the below photo i get only 10 records and in the other photo appears the result that i want that are the results data of each iteration of the for-loop
Modified JavaScript value photo:
Expected result:
Obtained result:
For loops are not really a thing in PDI. Transformations work on sets of rows that flow through the steps, so it's best for performance and stability to use that mindset.
In your scenario each incoming row should end up as three copies, but with different calculated values based on a single new field (with values 0,1,2).
The way to do this in PDI is with a Join rows (cartesian product) step. It takes two sets of input rows and outputs a row for every combination of input rows, possibly filtered by defining a key field that has to match. So if you have 10 rows in the main input and 3 rows in the second, it will output 30 rows.
You will first need to create a data grid as the second input. Define a single integer field, name it something clear and on the second tab fill three rows with 0, 1 and 2 respectively.
Connect both inputs to the Join rows step. You don't need to configure any matching key.
The output of the Join step will be three rows for each input row, one with each of the values 0, 1, 2. Connect that output to a Calculator step and use the calculation Date A + B days to replace the logic from your javascript step.
what i mean is that in the obtained result photo the "i" variable only shows the value of "3" and i would like to have "1", "2" and "3"
to solve this i used
var row = createRowCopy(getOutputRowMeta().size())
var idx = getInputRowMeta().size()
row[idx++] = DPROCESS
this add a row for each result of the iteration.
before the tranformation result showed to me only the last value of each loop.
Google sheets has an option which is selectable from the top menu to separate text into columns when specifying a character. It's possible use a comma or other characters.
I am looking for a script which can do this process automatically for a given column. There are numerous scripts available to do this but I have not been able to accomplish my task using them.
I am using an application on Android which allows me to scan a qr code and send the string of information to Google sheets.
A sample of the information would appear as : 464839|362|2840|927|72|617
I need to separate this information into separate columns when the information is sent to sheets. The process should be automatic.
I have a snip of code which I've found searching however it doesn't work for me.
var range = SpreadsheetApp.getActiveRange();
var cell = range.getCell(1, 1); // Gets the cell A1
var cellValue = cell.getValue(); // Gets the value of the cell A1
var cellArray = cellValue.split("|"); // Splits the cell value by ',' and stores it in array.
//Iterate through the array
for(var i = 0; i < cellArray.length; i++){
Logger.log(cellArray[i]);
}
I'm not very code savvy, please help.
Below would be a code that you place on an installable trigger that runs at a regular interval and iterates through the values of each row in column A and tries to split the value with the pipe symbol and the replace then write those split values along the columns in that row. If this has already been done in the past the function will error when it tries to split the values because no pipe symbol exists but the try/catch will catch that error and allow the function to continue through the loop.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NameOFSheet"); //Change "NameOFSheet to the actual name of the sheet.
var col1Values = sheet.getSheetValues(1, 1, sheet.getLastRow(), 1) //Gets 2d (2 dimensional) array of the Values in Column 1 (getSheetValues(startRow, startColumn, numRows, numColumns)_
var splitVals = []; //Instantiate an empty 1d array variable
//Iterate through the 2d array and set the values
for(var i = 0; i < col1Values.length; i++){
try{
splitVals = col1Values[i][0].split("|"); //Creates a 1d array of values split at every occurrence of the pipe symbol ("|").
//If there is no pipe symbol (which would be the case if this operation has already happened then the array will be blank because .split will throw an error which will get "caught" in the try catch and the row will be skipped
//Iterate over the splitVals array and set the values of the columns along the row (i+1) that you are in.
for(var col = 0; col < splitVals.length; col++){
sheet.getRange(i+1, col+1).setValue(splitVals[col])
}
}catch(e){}
}
}
I commented the code for explanation. I would recommend reading up on 2 dimensional arrays to help you understand them and the code above better.
I am trying to insert a row to the bottom of a sheet, but instead of my values I see text similar to what happens when you try to print an array in Java. I checked to see if the array is made correctly with logger and it has the values I want.
var name = e.range.getRow() + SpreadsheetApp.getActiveSpreadsheet().getName();
var array = e.range.getValues().concat(name);
Logger.log(array.toString());
masterSheet.appendRow(array);
array contains a timestamp, string1, string2, and finally the name I concatenated. Instead I get something like [Ljava.lang.Object;#7dch7145
This is because appendRow() is looking for array[] not array[][].
If you attempt to append:
var array = [[1,2,3],"some string"]
It will show up as the following as it is trying to get the entire contents of the first position of the array in a single cell. It does this by returning a string of the array object which turns out to be the native code identifier.
[Ljava.lang.Object;#32dba1e2 | some string
You can append the contents of array by appending its individual members such as
ss.appendRow(array[0])
Would append
1 | 2 | 3
It looks like a problem with your use of getValues() which returns a two-dimensional array and needs to be accessed as such.
GAS API Reference: getValues()
Return
Object[][] — a two-dimensional array of values
I believe this edit to setting your var array should do the trick, assuming your data range is for a single row (index 0 will be the first row, otherwise just change the index to the row you want):
var array = e.range.getValues()[0].concat(name);