Get other value based on active cell - google-apps-script

Google sheets / Google app's script
I'm want to know how to get a Cell, based in my current active Cell. Example:
A table where my active Cell is at G15, im wanna get the value of C15 (same row, but C column) and the value of C3 (same column now). To get the logic, imagines if my current Cell change to (example) H7, so, i would get C7 and H3.
I know It maybe is very simple, but im learning, so, im don't very very good ate that.

Try to add into the cell G15 this formula:
=TEXTJOIN(", ", TRUE, $C15, G$3)
And then copy it from G15 to H7, etc.

You can also achieve this using Apps Script:
function returnVals() {
let sheet = SpreadsheetApp.getActiveSheet();
let activeCell = sheet.getActiveCell();
let row = activeCell.getRow();
let col = activeCell.getColumn();
let colCValue = sheet.getRange(row,3).getValue();
let sameCol = sheet.getRange(3,col).getValue();
console.log(colCValue);
console.log(sameCol);
}
The getActiveCell method will return the active cell from the sheet and the getRow and getColumn will get the row and the col of the active cell. Afterwards, based on the row and col retrieved, the function above will simply get the values you need by using the getRange and getValue methods.
So if the active cell is G17, the row will be 17 and the col will be 7; therefore:
colCValue will be the value corresponding to the (17,3) range which is C17;
sameCol will be the value corresponding to the (3, 7) range which is G3.
Reference
getActiveCell();
getRow();
getColumn();
getRange();
getValue().

Related

How to lookup value from sheet1 on sheet2, and then fill in the date to the right of match on sheet2

Complete Google Apps Script novice question. I am trying to build some additional functionality into my spreadsheet where I can attach a script to a button that "checks off" the current selection as completed with the current date on a different sheet.
The pages are on one page of the sheet "sheet1" and the index of all pages are on "sheet2".
I am trying to run a textfind/replace function to find the cell of the match from sheet1, match the cell value from a column in "sheet2". From there I was thinking to try and pull out the row and column of that cell and then try write the date one cell to the right.
Im not sure how to pull the row and column out of the .getA1notation() below... and then really not sure if this is the right way to approach the problem.
From below I would want to look up the cell values from sheet 2 (F1143 on this one) and then write the current date in G1143.
Here is where I am so far:
function markComplete() {
var spreadsheet = SpreadsheetApp.getActive();
var encounterSheet = spreadsheet.getSheetByName("sheet2");
var tosearch = "chapter1"; //hoping to make cell reference from "sheet1"
var tf = encounterSheet.createTextFinder(tosearch);
var all = tf.findAll();
for (var i = 0; i < all.length; i++) {
Logger.log('The sheet %s, cell %s, has the value %s.', all[i].getSheet().getName(), all[i].getA1Notation(), all[i].getValue());
Logger.log(all[i].getA1Notation());
}
}
Logger results:
8:41:33 AM Notice Execution started
8:41:34 AM Info The sheet Sheet2, cell F1143, has the value Chapter1.
8:41:34 AM Info F1143
8:41:34 AM Notice Execution completed
Sheet.findAll() returns an array of the ranges containing that text.
let all = tf.findAll();
all.forEach( range => range.offset(0,1).setValue(new Date());
Reference
TextFinder.findAll()
Range.offset()

Google Sheet Macro - how do I return a column number based on dynamic cell contents?

I have the following code as a starting point. I want to select the entire column where row 3 contains a specific date value (it will be the date of the previous Monday; I have a formula returning this date in cell E1).
function selectDate() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss.getRange(3,?,1,ss.getMaxColumns()).activate();
}
Basically, the getRange column value would be interpreted as something like: "Find the column number where the value in row 3 is equal to the value in cell E1".
Any ideas would be very helpful, even if it's using a totally different method to achieve the same thing. Thank you so much!
In your situation, how about the following sample script?
Sample script:
function selectDate() {
var sheet = SpreadsheetApp.getActiveSheet();
var searchValue = sheet.getRange("E1").getDisplayValue();
var res = sheet.getRange(3, 1, 1, sheet.getLastColumn()).createTextFinder(searchValue).matchEntireCell(true).findNext();
if (!res) return;
var column = res.getColumn();
sheet.getRange(1, column, sheet.getLastRow()).activate(); // Here, the found column is activated.
Browser.msgBox("Found column number is " + column); // Here, the found column number is shown in a dialog.
}
From your situation, I thought that getRange(3,?,1,ss.getMaxColumns()) in your script might be getRange(3, 1, 1, sheet.getLastColumn()).
When this script is run, row 3 is searched using the value of cell "E1". When the value is found, as a sample, the found column is activated and the column number is shown in a dialog. This is a sample. Please modify this for your actual situation.
Note:
If no column is selected, it is considered that the value of cell "E1" is not found in row 3. At that time, can you provide the detail of your Spreadsheet? By this, I would like to modify it.
Reference:
createTextFinder(findText) of Class Range

Generate a number of rows based on input and adding SUM formula to last row

I am trying to add a rent roll to my Google sheets real estate investment calculator. Since each property this is used for will have a different number of units, I want to generate a row for each rental unit in the property based on a user input.
For example: User inputs "12" for number of units, and 12 rows are generated that are numbered 1-12.
This will be in column A. In column B, the user will then input the amount of rent collected for each unit. The total rent from the generated rows will be added and displayed in a specific cell that can be referenced in another formula.
Here's an example https://docs.google.com/spreadsheets/d/1KCeyLCcQZPBwzuuq8v8nn0flOlIx89-Tyjv5GjR4koI/edit?usp=sharing
Anyone have a suggestion on how to do this?
You can use this sample onEdit simple trigger:
function onEdit(e) {
var sheet = e.source.getActiveSheet();
var cell = e.range;
//Check if modified cell is Sheet1!B3
if(sheet.getName() == 'Sheet1' && cell.getA1Notation() == 'B3'){
//Change formula in Sheet1!B4
var unit = cell.getValue();
var formula = '=sum(B8:B'+(8+unit-1)+')';
Logger.log(formula);
sheet.getRange('B4').setFormula(formula);
//Clear output in Sheet1 starting from row 8 for Column A and B (including format)
sheet.getRange(8,1,sheet.getLastRow(),2).clear();
//Create an output data
var output = [];
for(var i=0; i<unit; i++){
output.push([i+1,""]);
}
output.push(["Total",formula]);
Logger.log(output);
sheet.getRange(8,1,output.length,output[0].length).setValues(output);
var yellow = '#ffff00';
var orange = '#ff9900';
//Add background color 'orange' to column A
sheet.getRange(8,1,unit,1).setBackgroundColor(orange);
//Add background color 'yellow' to column B
sheet.getRange(8,2,unit,1).setBackgroundColor(yellow);
}
}
What it does?
Get the active sheet and the modified cell using the Google Sheets event objects e.source and e.range
Check if the modified cell is in Sheet1!B3
Get the value of the modified cell
Create a SUM formula based on the input value
Set the formula in Sheet1!B4
Clear the content of Sheet1 for Column A and B starting in row 8
Create a 2-d array [(Unit#),(Empty Cell Rent)]. Append ["Total", (SUM formula)] at the end of the array
Write the 2-d array output in Sheet1, starting from Column A row 8
Set background colors for column A and column B
Note:
Since we used Google Sheets event objects, you cannot run this function in your Apps Script editor. Event object is undefined. If you want to debug the code, include logs in the code then modify a cell in your sheet to trigger the onEdit() which contains the event object then check the execution tab for the latest logs
Output:

Google Sheets (Google Finance) - Get stock price once and track

I would like to, upon data being entered into a new row (from external sheet - date, time, stock ticker), use google finance to get the current price of the stock into a cell and then no longer update the price in that cell. In the cell next to it, I want to track the price and in the cell next to that, I want to track the high, since creation (the highest value of the 'current price' cell).
Here is my sheet https://docs.google.com/spreadsheets/d/1EUU1bZnIfBatNI8H9pPk202PCD1g8wWXt5M0wx6S-jM/edit?usp=sharing
All I've got so far is a high value tracker that runs on the first row only for the right cells. Embarrasingly enough I can't figure out how to apply it to the entire columns.
So in summary, date time and stock will be entered into column A B and C. When that happens, I want to get the current price of the stock in C, and have that number no longer update. In D I want the price to be tracked, like Google Finance normally functions, and in E, the highest value of the D, in the same row.
That's the goal. Any help would be very much appreciated :)
All I've got so far is a high value tracker that runs on the first row
only for the right cells. Embarrasingly enough I can't figure out how
to apply it to the entire columns.
The code bound to your spreadsheet is
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange("D2:E2");
var values = range.getValues()[0];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
What does this code do?
It sets the range to work with always to D2:E2 - no matter what the actual edited range is
It works only with the first row of the range (range.getValues()[0])
It compares the 0 and 1 columns of the range (e.g. columns D and E) and assigns the value of column D back to column D (is it necessary?) and the higher of the two values to column E
How to modify your code?
It is not quite clear from your description how column D is populated and what you want to do with column F, but to give your general advice:
If you want your function to run on all rows:
Modify your range and expand it until the last row. Subsequently loop
through all rows:
function onEdit() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow();
var range = sheet.getRange("D2:E"+lastRow);
for (var i = 0; i < lastRow-1; i++){
var values = range.getValues()[i];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
}
If you want you code to run only on the currently edited row:
Use the event object e.range to find out which is the edited row and work on this row:
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var range = e.range;
var row = range.getRow();
var values = sheet.getRange(row, 4, 1, 2).getValues()[0];
range.setValues([[values[0], Math.max(values[0], values[1])]]);
}
Note: getRange(row, 4, 1, 2) is the notation to get the range starting with the defined row and column 4 (D), 1 row long and two columns wide, see here.
IMPORTANT: If your sheet is being populated automatically from an
external sheet - the onEdit trigger will not work for you (it only
fires on manual, human-made edits). In this case you will need a
workaround as described here.

Google Script to copy specific columns from one sheet to another sheets last row onEdit

I am looking for some help on google app scripting. Currently I have a spreadsheet that has 3 sheets. First sheet is data that comes from a google form. Second sheet is an "open" tab and third is a "closed" tab.
When data comes into the spreadsheet from the form it has only the columns that the form has. The "open" sheet has a combination of data from the form (sheet 1) and some additional cells to add more information to by me and not the person submitting the form. Because of this column miss-match I cannot just copy a whole row from sheet 1 to sheet 2. This also needs to be done onEdit trigger. So when an edit trigger fires, I want to store that rows data into memory and then copy column B to the last row of tab 2, column C. Column C > E, column D > B. etc..
How would I store the whole row into memory (an array I presume), and then copy only specific cells, in a specific order into the last row of a different sheet?
Hope that makes sense :-/
As you said, you'll have to use arrays to get data and write it back to another sheet in your selected order.
This is pretty basic manipulation and there are many ways to achieve it.
One way that is very easy to understand is as follow :
get row data in an array
pick up each value one by one and store in another array
write back to the last row +1 on another sheet.
Note that arrays are indexed starting from 0 , rows and columns start from 1 and A so you'll have to do some math !
function copyRow(){
var ss = SpreadsheetApp.getActive();
var sheet = ss.getActiveSheet();
var rowIdx = sheet.getActiveRange().getRowIndex();
var rowValues = sheet.getRange(rowIdx,1,1,sheet.getLastRow()).getValues();
Logger.log(rowValues);
var destValues = [];
destValues.push(rowValues[0][0]);// copy data from col A to col A
destValues.push(rowValues[0][2]);// copy data from col C to col B
destValues.push(rowValues[0][1]);// copy data from col B to col C
destValues.push(rowValues[0][3]);// copy data from col D to col D
// continue as you want
var dest = ss.getSheets()[1];//go on chosen sheet (here is the 2cond one)
dest.getRange(dest.getLastRow()+1,1,1,destValues.length).setValues([destValues]);//update destination sheet with selected values in the right order, the brackets are there to build the 2D array needed to write to a range
}
If you want that function to run on edit then just call it onEdit() and you're done !
Source: https://stackoverflow.com/a/64297866/14427194
function onEdit(e) {
//e.source.toast("Entry");
//console.log(JSON.stringify(e));
const sh=e.range.getSheet();
if(sh.getName()=="Sheet1" && e.range.columnStart==20 && e.value=="TRUE") {
const tsh=e.source.getSheetByName('Sheet2');
const nr=tsh.getLastRow()+1;
sh.getRange(e.range.rowStart,1,1,12).moveTo(tsh.getRange(nr,1,1,12));
sh.getRange(e.range.rowStart,16,1,4).moveTo(tsh.getRange(nr,16,1,4));
sh.deleteRow(e.range.rowStart);
}
}