Get values by specific column name - App Script - javascript

I'm trying to get values ​​from a specific column using the method getRange and specifying the name of the column using this example that I saw of the following question ... StackOverflow
When I combine it with my code, I got something like this...
function hola (){
var ss1 = SpreadsheetApp.getActiveSpreadsheet();
var ssh1 = ss1.getSheetByName("Sheet 1");
var lsc = ssh1.getLastColumn();
var data = ssh1.getRange(1,1,1,lsc).getValues();//Get 2D array of all values in row one
data = data[0];
var name = data.indexOf('Names') + 1;//Arrays are zero indexed- add 1
Logger.log(name);
var lastRow = ssh1.getLastRow();
var getRange = ssh1.getRange(name +(lastRow)).getValue();
Logger.log(getRange);
}
I'm not sure I'm wrong, I hope someone can guide me better :D

Related

Google Script GetRange with Filter based on values in a column AND select only certain columns

I have a dataset of 35 columns and 300 rows. I want to get the range that contains rows only for certain values in column 30 (names). The name for which to filter the data is based on the report file cell B6 in the report sheet that is active. So far I tried this:
var report = SpreadsheetApp.getActiveSpreadsheet();
var tsheet = report.getSheetByName("Transactions");
var areport = SpreadsheetApp.getActiveSheet();
var agent = areport.getRange('B6').getValues();
var criteria = SpreadsheetApp.newFilterCriteria().whenTextEqualTo(agent).build();
var trange = tsheet.getRange().createFilter().setColumnFilterCriteria(30, criteria); // ERROR
var tdata = trange.getValues();
I receive an error Exception: The parameters () don't match the method signature for SpreadsheetApp.Sheet.getRange.
The second part, I only want to get several columns, 5,6,7, 13, 15. I can't create another filter with the Spreadsheet app, so is the only way to make an array and filter out the needed data from there? I'm just trying to think ahead and reduce the amount of calculations.
Try with filter():
var report = SpreadsheetApp.getActiveSpreadsheet();
var tsheet = report.getSheetByName("Transactions");
var areport = SpreadsheetApp.getActiveSheet();
var agent = areport.getRange('B6').getValue();
var data = tsheet.getRange('A1:AI300').getValues();
var tdata = data.filter(function (row) {
return row[29] == agent && row[5] == 'Closed' ; // starts from 0, column A is 0.
});
To select particular columns from tdata do:
var cr_data = getCols(tdata,[5,6,7, 13, 15]);
where getCols() is defined as follows:
function getCols(arr,cols) {
return arr.map(row =>
row.filter((_,i) => cols.includes(++i)))
}
and finally you can copy cr_data to a particular place/sheet like that:
sheet.getRange(1,1,cr_data.length,cr_data[0].length).setValues(cr_data);
Regarding the second part of your question I would like to redirect you to this post:
Best method to extract selected columns from 2d array in apps script

Convert data from table to table

I was working in a project which is converting some data to another table by an online API (web service), so the plan is fetching data from the API and converting the prices to another table, I still got the same error again and again which is not convert each row as the way I need.
SCREENSHOT : THE UI TO UNDERSTAND THE USE
CODE :
function Send_Button() {
//activate the spreadsheet
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var cellCurrency = spreadsheet.getRange('E9').getValues();
//fatching the data from the API
var res = UrlFetchApp.fetch("https://api.exchangeratesapi.io/latest?base="+cellCurrency).getContentText();
//parsing data to JSON
var json = JSON.parse(res);
//exporting data in variables
var USD=json['rates']['USD'],
CAD=json['rates']['CAD'],
GBP=json['rates']['GBP'],
EUR=json['rates']['EUR'];
//an array to fetch just 4 currencies
var CRN = [USD,CAD,GBP,EUR];
var cellsPrice = spreadsheet.getRange('E5:E8').getValues();
//targeted cell in the second currencies table
var cellsTraget1 = spreadsheet.getRange('H3:K3');
var cellsTraget2 = spreadsheet.getRange('H4:K4');
var cellsTraget3 = spreadsheet.getRange('H5:K5');
var cellsTraget4 = spreadsheet.getRange('H6:K6');
//converting process
for(var i=0;i<4;i++)
{
cellsTraget1.setValue(cellsPrice[0]*CRN[0]);
cellsTraget2.setValue(cellsPrice[1]*CRN[1]);
cellsTraget3.setValue(cellsPrice[2]*CRN[2]);
cellsTraget4.setValue(cellsPrice[3]*CRN[3]);
}
}
You are iterating but not using the iterator variable i, is that correct? Perhaps writing the code in a more readable way with first getting the rows and then the cell value for each column and then iterating over both row and column would make it more readable and makes you find the issue faster.
Are you absolutely sure that your var cellCurrency is the correct range you want?
From your screenshot it appears the right cell is "E10"... but let's assume you fixed that.
Then you have an issue with your array dimensions, your var cellsPrice is a 2D array (Rows, Columns) even if the range you are getting values from is only one row!.
Another issue, your var cellsTraget* is also a 2D Range, so you can't use setValue()... You could use setValues() but the values array MUST match the range's dimension. And as they currently are, they don't match. Hint: transpose them if you want to use said function.
Apart from that, your for-loop makes no sense at all, since you are not looping anyhow!.
Here is some sample working code:
function sendButton() {
// Activate the spreadsheet
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var baseCurrency = "USD";
// Fetching the data from the API
var res = UrlFetchApp.fetch("https://api.exchangeratesapi.io/latest?base="+baseCurrency).getContentText();
// Parsing data to JSON
var json = JSON.parse(res);
// Exporting data in variables
var USD = [json['rates']['USD'], json['rates']['CAD'], json['rates']['GBP'], json['rates']['EUR']];
// I will do it for one row
var articlePrice = spreadsheet.getRange('E5').getValue();
// Mind the array's dimensions!
var convertedPricesRange = spreadsheet.getRange('I5:L5');
var convertedPriceValues = [[articlePrice*USD[0],articlePrice*USD[1],articlePrice*USD[2],articlePrice*USD[3]]];
// Set converted values
convertedPricesRange.setValues(convertedPriceValues);
}
Further reading:
Sheets Class Range

Append an array in gSheets?

Firstly I am very inexperienced here so apologies if this is obvious.
I have an array of data that updates automatically and I wish to copy this data out so I have an archive of it.
I have managed to find the following script which works for what I want:
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("xxx");
var data0 = sheet.getRange("xxx!A2:AQ21").getValue();
var data1 = sheet.getRange("xxx!B2").getValue();
var data2 = sheet.getRange("xxx!C2").getValue();
var data3 = sheet.getRange("xxx!D2").getValue();
sheet.appendRow([data1,data2,data3,...]);
}
However I have a range of 860 cells, so doing it one by one isn't too feasible.
Reading up on the appendRow method I realise that it (seems) to only be able to append one row at a time. I only have 20 rows so this should still be doable.
I then tried using
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Insta faction post data");
var values = sheet.getSheetValues(2, 1, 1, 43);
sheet.appendRow([values]);
However this outputs the following in the first cell of the new row: [Ljava.lang.Object;#247f2c9a
This seems to be the array I'm trying to append (java: what is this: [Ljava.lang.Object;?) however I can't get it to work!
[I have also tried using
function saveInstaPostData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Insta faction post data");
var range = sheet.getRange(2,1,20,43);
var values = range.getValues();
sheet.appendRow([values]);
This outputs ' Range ' in the first cell of the new row.
]
Any pointers would be really appreciated,
Thanks,
On your example, you try to append a tri dimensionnal array:
var values = sheet.getSheetValues(2, 1, 1, 43);
or
var range = sheet.getRange(2,1,20,43);
var values = range.getValues();
Your "values" variable contains a bi dimensionnal array, that you've put in a mono dimensionnal array:
sheet.appendRow([values]); // [values] put bi dimensionnal array in a mono dimensionnal array
To append your data, you need to append each row of your array, one after a other like :
for(var i=0; i<values.length;i++){
sheet.appendRow(values[i]);
}

Google Script: Format URL in Array.Push

I have a working script that upon form submit, specific rows move from one sheet to another. One of the fields I'm pushing is a url.
On the second sheet, the link is listed and it is hyperlinked, but it's really ugly and I really want to format it so that it shows "Edit" with a hyperlink. I've tried a number of ways, but my knowledge is limited so all I get are errors. I'm hoping someone can point me in the right direction.
Here is my code. I'm very new at this so the script is not at all sophisticated. Any help/suggestions would be appreciated!
function copyAdHoc(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Form Responses 1"));
var data = sh.getRange(2, 1, sh.getLastRow() - 1, sh.getLastColumn()).getValues();
// Grab the Headers from master sheet
var headers = sh.getRange(1,1,1,sh.getLastColumn()).getValues();
var date = headers[0].indexOf('Effective Date');
var name = headers[0].indexOf('Employee Name');
var loc = headers[0].indexOf('Location');
var issue = headers[0].indexOf('Description/Question/Issue');
var add = headers[0].indexOf('Additional Information');
var change = headers[0].indexOf('Is this a Qualifying Life Event?');
var url = headers[0].indexOf('Form URL');
var category = headers[0].indexOf('Primary Category');
var status = headers[0].indexOf('Current Status');
var users = headers[0].indexOf('Users');
// Grab only the relevant columns
for(n = 0; n < data.length; ++n ) { // iterate in the array, row by row
if (data[n][change] !== "Yes" & data[n][category] !== "Employee Relations" & data[n][date] !== "") { // if condition is true copy the whole row to target
var arr = [];
arr.push(data[n][url]);
arr.push(data[n][users]);
arr.push(data[n][date]);
arr.push(data[n][loc]);
arr.push(data[n][name]);
arr.push(data[n][category]);
arr.push(data[n][issue] + ". " + data[n][add]);
arr.push(data[n][status]);
var sh2 = SpreadsheetApp.setActiveSheet(ss.getSheetByName("Ad Hoc")); //second sheet of your spreadsheet
sh2.getRange(sh2.getLastRow()+1,2,1,arr.length).setValues([arr]); // paste the selected values in the 2cond sheet in one batch write
}
}
}
It's a bit messy but the only way I know to achieve what you're trying to do would be to insert a column to the left of the hyperlink with the word Edit right justified and then remove the borders between the two.
From your description I am assuming you want the word "Edit" to be Hyperlinked. To do so, try this:
function getHyperlink(url)
{
return "=HYPERLINK(\""+url+"\","+"\"Edit\""+")";
}
function mainFunct()
{
//Do necessary steps
var tarLink = "https://www.google.com";
var tarRng = tarSheet.getRange(rowNum, colNum).setValue(getHyperlink(tarLink));
//perform other steps
}
EDIT:
Forgot to mention, since you're pushing your values to the array... you can do it in a similar way by either just storing the hyperlink in a variable or directly pushing it to the array like all the other values. Or if you're dealing with a hyperlink that has a static and dynamic part, For example: https://stackoverflow.com/questions/post_id, where post_id keeps changing but most of the URL is static, you can easily handle it by just passing the post_id to the getHyperlink function and getting the required Hyperlink in return. Hope this helps.

Google Spreadsheet On change write log to another sheet

please can anyone help with one problem in google spreadsheet?
After changing value in one concrete collumn in sheet "Venues", I would like to write log about name and time, when this value was changed. But I can't really realize , if I am working with spreadsheet "Venues" or some other. I am not very into class structure of google API for Spreadsheet. So can anyone help with it?
I need:
run eventhandler on event when value in appropriate column in appropriate sheet ("Venues") is changed
get value from collumn name from this sheet
get actual time
write name and time to another sheet called "status_history" to last row (like append)
My hard try to write something: (but that is really bad code)
function onEdit(event)
{
var sheet = event.source.getActiveSheet();
var cell = sheet.getActiveCell();
var cellR = cell.getRow();
var cellC = cell.getColumn();
var cellValue = cell.getValue();
var cellCName = cell.getColumn()-1; //column with names
var name = sheet.getRange(cellR, cellCName).getValue();//get name
var active_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
if(sheet.getName() == "Venues"){
if(cellC == 5 /* if correct collumn was changed */){
var output_sheet = active_spreadsheet.getSheetByName("status_history");
var lastRow = output_sheet.getLastRow();
var lastRange = output_sheet.getRange(lastRow, 1)
//HERE: write value: name
var lastRow = output_sheet.getLastRow();
var lastRange = output_sheet.getRange(lastRow, 2)
//HERE: write value: time
}
}
}
You were getting there. Just a couple of tweaks needed.
With onEdit functions, you need to keep things fast, since they get invoked so often.
Rely on the event information as much as you can, avoiding calls to Google Apps services.
If you must use a service, do it only when you absolutely need to - for example, wait until you are past the if statements that tell whether you are in a cell you want to log before calling SpreadsheetApp.getActiveSpreadsheet().
The API is rich, so look for functions that will let you reduce the number of system calls you make - see how appendRow() replaced multiple statements, for example.
Here's your function after a code inspection:
function onEdit(event) {
var sheet = event.range.getSheet();
if(sheet.getName() == "Venues"){
// correct sheet
var cell = event.range;
//var cellR = cell.getRow(); // not used at this time
var cellC = cell.getColumn();
var cellValue = event.value;
if (cellC == 5) {
// correct column
var name = cell.offset(0,-1).getValue(); // get name, 1 column to left
var time = new Date(); // timestamp
var active_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var output_sheet = active_spreadsheet.getSheetByName("status_history");
output_sheet.appendRow([name,time]);
}
}
}
You could make it more flexible and portable by using column names to test conditions. Take a look at Adam's answer here.

Categories