Applying script to a single column [duplicate] - google-apps-script

This question already has answers here:
Add a timestamp to one column when other columns changed
(2 answers)
Google Spreadsheet SCRIPT Check if edited cell is in a specific range
(6 answers)
Closed 5 years ago.
I am trying to use the following generic script, and only apply it to a specific column. How would I specify this to say, column F within the sheet?
function onEdit(e){
// Set a comment on the edited cell to indicate when it was changed.
var range = e.range;
range.setNote('Last modified: ' + new Date());
}

function onEdit(e) {
var range = e.range;
// if you want to test a specific sheet, un-comment the following the following and move the range test inside this if
/* if (range.getSheet().getName() === 'required sheet') {
// do something
}*/
if (range.getColumn() == 6) {// 6 is for col F
range.setNote('Last modified: ' + new Date());
}
}
This should work. It tests the column of the range if it is F (6 in this case) and sets the note.

To build on Karan's great answer. With this you can modify a row and update a column within the modified row.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1')
var row = e.range.getRow();
// 'A' specifies the columns
var range = sheet.getRange('A'+ row)
Logger.log(range)
range.setNote('Last modified: ' + new Date());
}

Related

Event Trigger: Cannot read undefined property 'range' [duplicate]

This question already has answers here:
How can I test a trigger function in GAS?
(4 answers)
Closed 3 months ago.
Google Apps Script - triggered onEdit(e) with onEdit and oChange, both returned same error.
TypeError: Cannot read property 'range' of undefined code 6 ie; e.range
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var row = range.getRow();
if(sheetName == 'DATA')
{
var new_date = new Date();
spreadSheet.getActiveSheet().getRange(row,6).setValue(new_date).setNumberFormat("MM/dd/yyyy hh:mm:ss A/P");
}
}
`
Using SpreadSheet with 6 columns, the Col6 (F) for update (MM/DD/YYYY hh:mm:ss A/P) triggered with onedit. Tried necessary changes on colA to colE, but Col6 (F) not updating the for any changes.
Please note: for empty cell running the script, property return error due to "null" value is understood. But here even the changes made on SS does not return the UPDATE on col6(F). Kindly HELP
This is working for me:
function onEdit(e) {
e.source.toast('Entry')
const sh = e.range.getSheet();
if(sh.getName() == 'Sheet0') {
e.source.toast('Gate1')
var new_date = new Date();
sh.getRange(e.range.rowStart,6).setValue(new_date).setNumberFormat("MM/dd/yyyy hh:mm:ss A/P");
}
}
But you don't have any logic to control where you wish to monitor the ranges it just triggers on any edits to a given page.

How to add two variables together in sheets script?

I'm trying to make a script that adds the value of one cell to another one before I clear the first cell. Unfortunately, all my attempts to add the second one have given errors. This is my latest one: I get a NUM error here. what do I do?1
You can use onEdit simple trigger, which will give you access to oldValue of cell which was edited and you can use that value to add it with column B.
Based on your this problem statement, try this sample script:-
function onEdit(e)
{
const range = e.range;
const sheet = range.getSheet();
const row = range.getRow();
const column = range.getColumn();
var oldValue = e.oldValue;
if(column === 1)
{
const colB = sheet.getRange(row,column+1); // Getting Column B value
var colB_Value = colB.getValue();
oldValue = isNaN(Number(oldValue)) ? 0 : Number(oldValue)
colB.setValue(oldValue + colB_Value) // adding old value of column A with B and setting it on Column B
}
}
Reference:
OnEdit()
Event Objects
isNaN

Script needs to find last in row, not sheet [duplicate]

This question already has answers here:
Determining the last row in a single column
(30 answers)
Closed last year.
I saw another thread Here with a solution to my start stop issue except it is written to find the last cell in the whole book. I need this for just rows A (for start), and row B (for stop) as I will have other data on the sheet.
I also need to be able to do the same function for multiple sheets... so start and stops just for that sheet.
Here is the current code I am using...
I believe your goal is as follows.
When you run the script of startTime(), you want to put new Date() to the cell of the next row of the last row of the column "A".
When you run the script of stopTime(), you want to put new Date() to the cell of the next row of the last row of the column "B".
You want to run the script for the specific sheets you expect.
getLastRow returns the last row of all columns. When you want to retrieve the last row of the specific column, it is required to check it using a script instead of the method of getLastRow. So, from your sample Spreadsheet shown in your image, how about the following sample script?
Sample script:
const sheetNames = ["Line1",,,]; // Please set the sheet names you want to run the script.
// Ref: https://stackoverflow.com/a/44563639
Object.prototype.get1stNonEmptyRowFromBottom = function (columnNumber, offsetRow = 1) {
const search = this.getRange(offsetRow, columnNumber, this.getMaxRows()).createTextFinder(".").useRegularExpression(true).findPrevious();
return search ? search.getRow() : offsetRow;
};
function startTime() {
const sheet = SpreadsheetApp.getActiveSheet();
if (!sheetNames.includes(sheet.getName())) return;
const row = sheet.get1stNonEmptyRowFromBottom(1) + 1;
sheet.getRange(row, 1).setValue(new Date());
}
function stopTime() {
const sheet = SpreadsheetApp.getActiveSheet();
if (!sheetNames.includes(sheet.getName())) return;
const row = sheet.get1stNonEmptyRowFromBottom(2) + 1;
sheet.getRange(row, 2).setValue(new Date());
}
Note:
If you don't want to put the value to the column "B" when the column "A" is blank, please modify sheet.getRange(row, 2).setValue(new Date()); in stopTime() as follows.
const range = sheet.getRange(row, 2);
if (range.offset(0, -1).isBlank()) return;
range.setValue(new Date());
Reference:
Related thread
Determining the last row in a single column

Find cells within range [duplicate]

This question already has answers here:
Google Spreadsheet SCRIPT Check if edited cell is in a specific range
(6 answers)
Is there an existing way in google script to check if an A1 notation is in range of a second A1 notation
(2 answers)
Closed 2 years ago.
I have aRange which I do not know what it contains (not size nor values).
Now I want to check if 'B2:B4' is within aRange and get the value(s) of B2:B4 if indeed it is inside aRange.
I am really frustrated to be unable to figure out how to solve this (to me apparently) trivial requirement.
Thank you for any suggestions.
B2:B4 matches exactly given range:
Try range.getA1Notation():
function myFunction(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
const range = sh.getRange('B2:B4'); //given range
if (range.getA1Notation()=='B2:B4'){
var vals = range.getValues().flat(); //flat is optional but it returns 1D list
}
Logger.log(vals)
}
B2:B4 is within given range:
As Cooper suggested in his comment, use getRow(), getColumn(), getWidth(), getHeight():
function myFunction(){
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
const range = sh.getRange('B1:B5'); //given range
if(range.getRow()<=2 && range.getColumn()<=2 && range.getWidth()>=1 && range.getHeight()>=3){
var vals = sh.getRange('B2:B4').getValues().flat(); //flat is optional but it returns 1D list
}
Logger.log(vals)
}
References:
getA1Notation()
Class Range

Copy edited values before they are edited

I'm trying to setup a daily report that will send me an email with only the edited rows from a sheet, but also including the old values before they were edited.
I wrote the following script, where when the specified range is edited, the whole row is transferred to another tab called "new_values".
function onEdit_inRange(e,sheetName,sheetRange){
var sh=e.range.getSheet();
if(sh.getName()===sheetName){
var range = SpreadsheetApp.getActiveSheet().getRange(sheetRange);
var xy=[e.range.getColumn(),e.range.getRow()];
if (xy[0]>=range.getColumn() && xy[0]<=range.getLastColumn() && xy[1]>=range.getRow() && xy[1]<=range.getLastRow()) {
return e.range;
}
}
return false;
}
function onEdit(e){
var range=0;
if((range=onEdit_inRange(e,'sheet','M6:O'))){
// SpreadsheetApp.getUi().alert('You Edited a Cell INSIDE the Range!');
} else if ((range=onEdit_inRange(e,'sheet','Q6:Q'))) {
// SpreadsheetApp.getUi().alert('You Edited a Cell INSIDE the Range!');
}
var ss = e.range.getSheet();
//ss.getRange(e.range.getRow(),49) //set timestamp in column 49
//.setValue(new Date()); // Set time of edit in "G"
var appendSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('new_values');
var archiveLastRow = appendSheet.getLastRow();
Logger.log(archiveLastRow);
var archiveAppendRange = "new_values!" + (appendSheet.getLastRow() + 1) + ":" + (appendSheet.getLastRow() + 1);
Logger.log(archiveAppendRange);
var destRange = ss.getRange(archiveAppendRange);
Logger.log(destRange);
var sourceDataValues = ss.getRange(range.getRow(),1,1,49).copyTo(destRange);
Logger.log(sourceDataValues);
}
What I can't manage to do is to make this script to also copy the old values, when they are edited, and move them to another separate tab (called "old_values").
How can I copy the old value, when cells are edited in the same way I do the new values?
My plan is that I'll merge both tables and send over email.
Here's an example spreadsheet with my code: https://docs.google.com/spreadsheets/d/1xzyVD7ElA0FMVC8sta6beDJCIwOQEMRqjhF5eW4mExI/copy