Check highest digit and copy text from grid cell - google-apps-script

I'm new to scripting, but need to do the following in Google sheet script for my RPG gaming system...
Check a cell for the highest one-digit number. i.e. 1 6 3 2 4 = 6 highest number.
Check the same in another cell.
Depending on the combo of these digits, i.e. 6-2, 3-4, 1-6 etc, text from a specific cell in a grid table on another sheet should be copied.
The grid has 1 to 6 vertically, and 1 to 6 horizontally, different texts in each combo cell.
The copied text shall be entered into a specific cell (i.e. E10) in the first sheet.
Can someone help me?

From what I see, you would like to check the highest value in two cell, and would like to use that to get an exact location in a table of values, and get that value printed on another cell.
The problem can be solved in 3 phases.
1) Finding the highest value in the cell.
2) Retrieving the value in the table.
3) Setting the destination cell with the retrieved value.
1) Depending on if you are finding the highest value in a cell refers to:
A) 1534 in one cell and taking 5
OR
B) 1 in A1, 5 in A2, 3 in A3 and 4 in A4. and retrieving 5 from A2 cell.
A: Your solution would use a combination of .split() & Array.prototype.concat.apply() & Math.max.apply(). Reference: Inputting an array into Math.Max in Google Apps Scripts
B: Your solution would use a combination of getRange(row,column,row,column) & Array.prototype.concat.apply() & Math.max.apply()
You would get an output of two max number, which we would call A and B
2) To retrieve the value, you would require the getRange(A,B) & getValue() and depending on where the table is you might need to modify A and B to get the correct location in the table.
3) To set the value in cell E1, you would require the setValue() function.
You might want to try resolving the issue by yourself using the handles above. They might not be the most efficient, but should work. Alternatively i have a sample script below for you. There is a flaw, whereby if the value input is larger than your table, it would not flag out an error. so either you limit the users input or you would create a way to flag out the error:)
function SetRetrievedValue() {
var app = SpreadsheetApp;
var ss = app.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//var cellcontent1 = sheet.getRange(2,1,6,1).getValues(); use this if its a range of cells you are searching
var cell1 = sheet.getRange(1,1).getDisplayValue(); //gets value as string
var cellcontent1 = cell1.split(""); // splits up the string individually
var newcellcontent1 = Array.prototype.concat.apply([], cellcontent1); // flatten the array
var maxNum1 = Math.max.apply(null, newcellcontent1); //gets the max value in the array
// repeat of cell 1
var cell2 = sheet.getRange(1,2).getDisplayValue();
var cellcontent2 = cell2.split("");
var newcellcontent2 = Array.prototype.concat.apply([], cellcontent2);
var maxNum2 = Math.max.apply(null, newcellcontent2);
var tablecell = ss.getSheetByName("Table sheet").getRange(maxNum1,maxNum2).getValue(); //retrieve the value based on the corresponding max value
sheet.getRange(1,3).setValue(tablecell); // sets the cell C1 as the value retrieved from the table
}

Related

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.

A code that fills column A with unique reference numbers starting from 1

I want to have a code that when it runs, it fills the entire column A of the active sheet with a continuous series of numbers starting from 1 like 1,2,3,... . The numbers should start from cell A2. The result should be as follows:
A2 = 1 ; A3 = 2 ; A4 = 3 ; etc. until it reaches the last row of the sheet.
I have no idea how to write the code!
Any help?
In Cell A2: enter your starting value 1
Cell A3: type =A2+1
Click on A3, and you will see a small square in the bottom right corner of A3
Click and drag that little square down as far as you need the numbers
When you release the mouse button, it will auto fill the series of numbers
Finally I made it!
I wrote the following two functions for this purpose. Creating the following functions took me a lot of time and energy and a lot of trial and error, but it was really enjoyable.
The main GAS function with passing arguments:
function refreshRefNums(sheetName,refColumnIndex,refFirstRowIndex){
var spreadSheet = SpreadsheetApp.getActive();
var sheet = spreadSheet.getSheetByName(sheetName);
var refLastRowIndex = sheet.getLastRow();
var baseRange = sheet.getRange(refFirstRowIndex,refColumnIndex,2);
var destinationRange = sheet.getRange(refFirstRowIndex,refColumnIndex,refLastRowIndex);
baseRange.autoFill(destinationRange, SpreadsheetApp.AutoFillSeries.DEFAULT_SERIES);
}
And the function I run to do the job:
function refreshRefNumsIOUData(){
refreshRefNums("IOU Data",1,2);
}
Notes:
sheetName is the name of the sheet that has a column for unique reference numbers strating from 1.
refColumnIndex is the index of the column that contains reference numbers.
refFirstRowIndex is the index of the row that reference numbers start.
refLastRowIndex is the index of the last row containing reference numbers.

Loop through a range of cells Google Sheets

First of all, I'm new to coding - so the script that I have I combined it from a couple different scripts and it seems to work, but I would like to simplify it.
I have such a script:
function count() {
var Month = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Private').getRange('A2').getValues();
var PCC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Private').getRange('B1').getValues();
var PCCQ = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(Month).getRange(PCC);
var PCCS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(Month).getRange('B4').getValue();
var PhoneCC = GmailApp.search(PCCS);
PCCQ.setValue(PhoneCC.length);
}
What it does:
it takes the name of the sheet where I want the results from cell A2 of sheet Private.
it takes the cell where I want the result from cell B1 of sheet Private.
we get the range by combining the sheet name in 1 and cell from 2
it takes the query that we need from the sheet that get from 1 and cell B4
makes a search in Gmail with the query from 4
sets the value of the cell from point 3 as the length of the search from point 5
However I have a range of cells for point 2 that I need this to work through, let's say B1:B70.
Is there a way to adjust this script to do this?
Will be very thankful.
I'd make the following changes. Keep going.
var Month = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Private').getRange('A2').getValue();
var PCC = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Private').getRange('B1').getValue();
var PCCQ = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Month').getRange(PCC);//The range is not sensible unless it is a named range but the getRange does not work with named ranges.
var PCCS = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Month').getRange('B4').getValue();
var PhoneCC = GmailApp.search(PCCS); //how do you plan to display your results.

Google app script to copy column values to a different sheet

I am trying to write a google app script so I can copy a few columns (C and D) from my main report sheet to a different sheet, based on the value of column M if that's equal to 0.
As shown in the pic below:
So I want to copy the "Name" and "Variety" columns into another sheet where the "Germination %" column is 0.
It can be a time based trigger, that runs after every 2 hours or onEdit also. I was trying to make it a script using OnEdit, as shown below:
function onEdit( e ){
var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("germination");
var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("watering");
var data = sheetFrom.getDataRange().getValues();
var target = new Array();// this is a new array to collect data
for(n=0;n<data.length;++n){ // iterate in the array, row by row
if (data[n][12]=="0"){ // if condition is true copy the whole row to target
target.push(data[n]);// copy the whole row
}//if
}//for
//Paste to another sheet from first cell onwards
sheetTo.getRange(1,1,target.length,2).setValues(target);
}
But I am getting errors on this "Incorrect range width, was 15 but should be 2 (line 25, file "Code")"
Line 25 is "sheetTo.getRange(1,1,target.length,2).setValues(target)"
Thanks in advance.
In the getRange(1,1,target.length,2) method you're specifying it to select only 2 columns, change it to getRange(1,1,target.length,target[0].length) to select the array length of columns.
Update:
To write only the C and D, change the target push() to:
target.push( [[data[n][2], data[n][3]] )