Checking if specific column contain active cell - google-apps-script

Just started my adventure with apps-script and im already stuck.
I'm trying to write script that triggers when any cell in my table is edited , check if that cell is in specific range ( entire column "O"), then gets cell row and sends mail to person bounded with that row.
As long as I got first and last part, I'm having trouble with checking if that range contains cell :
var cell = get.ActiveCell();
var range = ss.getRange("O:O");
However there are few similar columns with similar values, and i want to check this one only so far i got something like that
var ss = getActiveSpreadsheet();
var sheet = ss.getSheetByName("zamówienia");
var cell = get.ActiveCell();
var range =ss.getRange("O:O");
while (i != range.lenght){
if (cell != range[i]) {
i++;
}
else {
break;
return 1;
}
}

You should be using the onEdit() simple trigger, and then you can use the associated event object.
Example:
// This will show a pop up in your spreadsheet whenever you edit a cell in Column O of any sheet
function onEdit(e) {
var columnO = 15;
if (e.range.getColumn() === columnO) {
Browser.msgBox("Column O");
}
}

Got it like that if anybody's trying to sort out same problem. Added on edit simple trigger
function sprawdzenie(){
var ss = SpreadsheetApp.getActive();
var activeRow = ss.getActiveCell().getRow();
var activeCol = ss.getActiveCell().getColumn();
if (activeCol === 13){
var klient = SpreadsheetApp.getActiveSheet().getRange("c"+activeRow).getValue();
var data_wys = SpreadsheetApp.getActiveSheet().getRange("H"+activeRow).getValue();
var numer_oferty = SpreadsheetApp.getActiveSheet().getRange("E"+activeRow).getValue();
var kolor = SpreadsheetApp.getActiveSheet().getRange("B"+activeRow).getValue();
var prowadzacy = (SpreadsheetApp.getActiveSheet().getRange('AL'+activeRow).getValue() );
var zejscie = SpreadsheetApp.getActiveSheet().getRange("M"+activeRow).getValue();
var temat = ('Zejście z produkcji ' + numer_oferty + ' wysłanej dnia ' + data_wys);
var wiadomosc = (' Oferta o numerze :' + numer_oferty + ' ' + klient + ' w kolorze : ' + kolor + ' zeszła z dniem : ' + zejscie);
MailApp.sendEmail(prowadzacy, temat, wiadomosc);}

Related

OnEdit with Mailapp on Google Script

I have a Google Spreadsheet with 4 columns including Products, Salesperson, Category and Status. What I am trying to reach is whenever a user choose Yes option on Status column and if that product category is also G, then sending an email using the MailApp.
The e-mail should include the product value as well.
So far, I was able to sending an email. But I've really confused about the offset concept here and was not able to send the product in the email
The spreadsheet: https://docs.google.com/spreadsheets/d/1wVr0SGryNNvorVdDZEY1E6UDgh25_A5A2LhN1UNbIHE/edit?usp=sharing
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var sheetName = sheet.getName();
var r = sheet.getActiveCell();
var cell = sheet.getActiveCell().getA1Notation();
if(ss.getActiveCell().getColumn() !== 5) return;//
var row = sheet.getActiveRange().getRow();
var cellvalue = sheet.getActiveCell().getValue().toString();
var prod = sheet.getRange().offset(0, -2).getValues();
var cat = cellvalue.offset(0, -1).getValues();
var recipients = "email#email.com";
var message = '';
if(cellvalue === 'Yes' && cat === 'G') {
message = cell + ' in Sheet ' + sheetName + ' was changed to YES.';
var subject = 'Cell Changed to YES';
var body = message + ss.getUrl() + ' to view the changes' + prod;
MailApp.sendEmail(recipients, subject, body);
}
}
It's probably easier to use the object passed with the onEdit event instead of manipulating active cells and offsets.
This event object gives you the new value, so you can check if it is the one that you want ('Yes'). It also gives you the range that was edited, so you can use it to check if the change was in the correct column ('D') and to get the row that was modified. Once you have the row, you can use it to get the values of the other columns ('Products' and 'Cat') in that row.
Something like this should work:
function onEdit(event) {
const statusColumnNumber = 4; // Indices of rows and columns start from 1, so column D is 4.
if (event.range.getColumn() === statusColumnNumber && event.value === 'Yes') {
const sheet = event.range.getSheet();
const rowValues = sheet.getRange(event.range.getRow(), 1, 1, sheet.getLastColumn()).getValues().flat();
const categoryColumnIndex = 2; // Indices of JavaScript arrays start from 0, so column C is in position 2 of the array.
if (rowValues[categoryColumnIndex] === 'G') {
const prodColumnIndex = 0;
const prodValue = rowValues[prodColumnIndex];
const recipients = "email#email.com";
const subject = 'Cell Changed to YES';
const message = event.range.getA1Notation() + ' in Sheet ' + sheet.getName() + ' was changed to YES. '
const body = message + '\n' + sheet.getParent().getUrl() + ' to view the changes for ' + prodValue;
MailApp.sendEmail(recipients, subject, body);
}
}
}
As mentioned in the comments of your question, since you use a service that needs permissions (MailApp), you'll need to create an installable trigger that calls this function.

copy and paste cell value from one sheet to another onEdit

I wrote a google script to create and paste the values from a cell in one sheet to another (same spreadsheet). The code consists of following two steps:
(works): If a cell of specific columns of one sheet are edited, then the next adjacent cell gets a value based on the edit.
(does not work): Paste the new value of the adjacent cell into the cell of the next empty row (1st column) in the second sheet.
The code below is what I have tried so far, but the value does not appear on the second sheet. Does anybody know where the problem is in my attempt below?
Thx
function onEdit() {
var a = [19,21,23]
var ss = SpreadsheetApp.getActive()
var s = ss.getActiveSheet();
if( s.getName() == "ALL" ) {
var valActive = s.getActiveCell();
var col = valActive.getColumn();
var row = valActive.getRow();
var range = s.getRange(row, 1);
var val0 = range.getValue();
if( a.indexOf(col) > -1 && valActive.getValue() != '') {
var nextCell = valActive.offset(0, 1);
var val1 = valActive.getValue();
var time = Utilities.formatDate(new Date, "GMT+1", "HHmm");
nextCell.setValue(val0 + '_' + val1 + '_' + time);
var rowNext = nextCell.getRow();
var colNext = nextCell.getColumn();
var target = SpreadsheetApp.getActive().getSheetByName("Samples");
var lastRow = target.getLastRow();
s.getRange(rowNext, colNext).copyTo(target.getRange(lastRow + 1, 1), {contentsOnly: true});
}
}
}
To get the second part to work you want to append a row to your other sheet. Try something like this:
var sheet = SpreadsheetApp.getActive().getSheetByName("Name");
sheet.appendRow([newValue]);

Need to get email notification if column in Google Spreadsheet is changed

I am trying to create a script that triggers a notification whenever a value is changed in a specific column of a Google Spreadsheet. Ideally, I would like to trigger notifications to other people, each based on changes to specific columns.
I have a test spreadsheet here:
https://docs.google.com/spreadsheets/d/1V4X1FNtYKbXhha84MzeU8kI57ck246WfvSluHlsP1eo/edit?usp=sharing
And have found a script for a custom notification elsewhere in the answers on SO. I took that and tweaked it until I got this:
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = ss.getActiveCell().getA1Notation();
var row = sheet.getActiveRange().getRow();
var column = sheet.getActiveRange().getColumn();
var colLetter = columnToLetter(column);
var cellvalue = ss.getActiveCell().getValue().toString();
var recipients = "email#domain.org";
var message = '';
if(cell.indexOf('G')!=-1){
message = sheet.getRange('F'+ sheet.getActiveCell().getRowIndex()).getValue()
}
var subject = 'Update to Notification TEST Sheet';
var body = 'Sheet ' +sheet.getName() + ' has been updated. Visit ' + ss.getUrl() + ' View the changes in row ' + row + ', column ' +colLetter+ '.';
MailApp.sendEmail(recipients, subject, body);
};
function columnToLetter(column) {
var temp, letter = '';
while (column > 0)
{
temp = (column - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
column = (column - temp - 1) / 26;
}
return letter;
}
function letterToColumn(letter)
{
var column = 0, length = letter.length;
for (var i = 0; i < length; i++)
{
column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
}
return column;
};
Once you change the receipient email, the script runs, but sends a notification for any change in any cell, not for cells with a specific column.
Can anyone help me get it to do what I am looking for?
TIA!
Imagine your trigger event is, onEdit(e)
function onEdit(e)
{
var range = e.range;
var column = range.getColumn();
if(column == `your expected column number`)
{
// call your send notification function
sendNotification();
}
}
You can read about triggers more. Event Objects

How to convert cell formula to script

How can I change this simple cell formula to a script that will be apply to the sheet :
=if(D3="Devis";B3+8;(if(D3<>"Devis";"")))
Where :
C column contains the formula
"Devis" is a name presents in the D column
B column contains Dates
Thanks a lot
First you need something that will trigger the script. So you'll need something like a simple onEdit() function, or a change trigger.
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('Sheet1');
var valueOfCellEdited = e.value;
Logger.log('valueOfCellEdited: ' + valueOfCellEdited);
var columnOfCellEdited = e.range.getColumn();
Logger.log('columnOfCellEdited: ' + columnOfCellEdited);
var rowOfCellEdited = e.range.getRow();
Logger.log('rowOfCellEdited: ' + rowOfCellEdited);
if (columnOfCellEdited === 3) {
var valueToGet = sh.getRange(rowOfCellEdited, 4);
var dateToGet = "";
if (valueOfCellEdited === "Devis") { //Date to write is already set to an empty string, so no "Else" needed
var dateInColB = sh.getRange(rowOfCellEdited, 2).getValue();
Logger.log('dateInColB: ' + dateInColB);
Logger.log('typeof dateInColB: ' + typeof dateInColB);
dateToGet = new Date(dateInColB);
var dateInMilliseconds = dateToGet.valueOf();
Logger.log('dateInMilliseconds: ' + dateInMilliseconds);
//60 seconds in a minute = 60 * 1000 = 60000 milliseconds in a minute.
//60 minutes in a hour = 60,000 * 60 = 3,600,000
//24 hours in day 3,600,000 * 24 = 86,400,000
var datePlusEight = dateInMilliseconds + (8 * 86400000);
Logger.log('datePlusEight: ' + datePlusEight);
var newDateIs = new Date(datePlusEight);
Logger.log('newDateIs: ' + newDateIs);
Logger.log('newDateIs: ' + newDateIs.toString());
sh.getRange(rowOfCellEdited, 4).setValue(newDateIs);
};
};
};
Comment out the Logger.log() statements for use. To test, edit a cell in column C, with a date right next to it in the same row, but in column B.
In the spreadsheet, under the Tools menu, choose Script Editor, copy the code and paste it into the script editor.

Google SpreadsheetApp help needed

This is a program designed to move data within 1 Spreadsheet containing a few Sheets
I don't know much about JavaScript I have only learned Java.
My Problem:
The addAcceptedHours method is designed to move a cell with data of a number, to a separate sheet (containing a list of names in the first column, columns 2-5 contain numbers). I need it to move the hours to a certain column of the row (the row is given from searchCol(String, Sheet)).
The var data is 2d array of the information submitted from a form looks like this:
[[(new Date(1339776313000)), "Firstname last", "email#email.com", 2015 , "A paragraph of text.", another paragraph of text", 00, "Freshman", "yet another paragraph of text", "Even moar text", "more text :3", "Firstname last"]]
0=timestamp
1=**firstname last**
2=email
3=** int(year graduating)**
4= paragraph of text (irrelevant to part)
5=** float (a number of hours)
6= "freshman", "sophomore", "junior", or "senior" (this will determine the column the number from 5 goes)**
7= paragraph of text (irrelevant to part)
8=paragraph of text (irrelevant to part)
9=paragraph of text (irrelevant to part)
10=paragraph of text (irrelevant to part)
11=a name onceagain
I need to add the number (5), to a row in another sheet in the column of 2-5 depending on (6)
for some reason it skips everything after the if statement in addAcceptedHours and adds the hours into the the 2nd column every time
//made with `enter code here`Google SpreadsheetApp Scripts
//PUBLIC VARIABLES
var data;
//please ignore missing methoods
function onOpen(){
var menu = [{name: 'Manage Hours', functionName: 'run'}];
SpreadsheetApp.getActive().addMenu('Manage Hours', menu);
}
//starts the program
function run(){
log('open');
getNext();
}
//opens window with options
function getNext(){
data = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pending Hours').getSheetValues(2, 1, 1, 12);
var cont = Browser.msgBox('Manage Hours', 'Would you like to get the next submission?', Browser.Buttons.YES_NO);
if (cont == 'yes'){
{
var msg = data[0][1] + "\\nClass of " + data[0][3] + "\\n Submitted " + data[0][6] + " Hours for their " + data[0][7] + " Year." + "\\nDescription of Service:\\n" + data[0][4] + "\\nContact Information:\\n" + data[0][5] + "\\nRecommendation: " + data[0][8] + "\\n" + data[0][9] + "\\n\\nAccept?";
var ans = Browser.msgBox('Manage Hours', msg , Browser.Buttons.YES_NO_CANCEL);
log(ans);
}
if (ans == 'yes')
accept();
else if (ans == 'no')
deny();
else cancel();
}
else
log("close");
}
function accept(){
addAcceptedHours();//adds hours to accepted place
addChesedOpportunity();//adds to opportunitys
archive('yes');//archives the row
mailUser('yes');//mails user Accpeted
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pending Hours').deleteRow(2);//deletes row for next use
getNext();//starts over
}
function addAcceptedHours() {
//get data
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pending Hours');
var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Accepted Hours');
var numhr = parseFloat(ss.getRange(2, 7).getValue().toString());
//asks how many hours to accept
var hrs = Browser.inputBox("how many hours will you accept (out of " + numhr + " hours)", Browser.Buttons.OK);
if (hrs.length > 0){
numhr = parseFloat(hrs);
ss.getRange(2, 7).setValue(numhr);}
//finds the row with the students name to add hours to
var name = data[0][1];
var row = searchCol(name,sss);
if (row == -1)// if not found, look to see if simaler names (check for misspelled names), then if the name is the same person set row to that row
row = checkForSim(name);
if (row == -1) {//if not misspelled then add the students name to the list, put it in order, get the row #
addStudent(name);
sss.sort(1);
row = searchCol(name,sss);}
//finds wich column to add years to
var col = 2;
if (data[0][8] == 'Sophmore')
col=3;
else if (data[0][8] == 'Junior')
col=4;
else if (data[0][8] == 'Seinor')
col=5;
//sets info for hours
sss.getRange(row, col).setValue(parseFloat(sss.getRange(row, col).getValue()) + numhr);
}
function searchCol(str, ss){//returns the row "str" is found in the first column of the sheet("ss")
var data = ss.getRange(1, 1, ss.getLastRow()+1, 1).getValues();
var found = false;
for (var i=0; i < data.length;i++){
if (data[i].toString().equalsIgnoreCase(str)){
found = true;
return i+1;}}
return -1;
}
function checkForSim(name){//looks for simaler names, and suggestes them, if they say it is the same person, return that row #
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Accepted Hours');
var count =0;
for (var x=2; x < ss.getLastRow(); x++){
for (var i=0; i<ss.getRange(x, 1).getValue().toString().length - 2; i++){
if (ss.getRange(x, 1).getValue().toString().substr(i,i+2) == name.substr(i,i+2))
count++;}
if (count > 0 && Browser.msgBox('Is this the same person?', ss.getRange(x, 1).getValue().toString() + '\nAnd,\n' + name , Browser.Buttons.YES_NO) == 'yes')
return x;
count =0;}
return -1;
}
function addStudent(name){
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Accepted Hours');
var row = ss.getLastRow();
ss.getRange(row, 1).setValue(name);
for (var x = 2; x<5;x++){
ss.getRange(row, x).setValue(0);
}
ss.sort(1);
}
fixed:
function addAcceptedHours() {
//get data
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pending Hours');
var sss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Accepted Hours');
var numhr = parseFloat(ss.getRange(2, 7).getValue().toString());
//asks how many hours to accept
var hrs = Browser.inputBox("how many hours will you accept (out of " + numhr + " hours)", Browser.Buttons.OK);
if (hrs.length > 0){
numhr = parseFloat(hrs);
ss.getRange(2, 7).setValue(numhr);}
data[0][6]=numhr;
//finds the row with the students name to add hours to
var name = data[0][1];
var row = searchCol(name,sss);
if (row == -1)// if not found, look to see if simaler names (check for misspelled names), then if the name is the same person set row to that row
row = checkForSim(name);
if (row == -1) {//if not misspelled then add the students name to the list, put it in order, get the row #
addStudent(name);
sss.sort(1);
row = searchCol(name,sss);}
//finds wich column to add years to
var col = 2;
if (data[0][7].toString() == 'Freshman')
col=2;
else {
if (data[0][7].toString() == 'Sophmore')
col=3;
else{
if (data[0][7].toString() == 'Junior')
col=4;
else{
if (data[0][7].toString() == 'Senior')
col=5;
}}}
sss.getRange(row, col).setValue(parseFloat(sss.getRange(row, col).getValue()) + numhr);
}
function addChesedOpportunity(){
//gets info
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Chesed Opportunities')
var private = data[0][11];
//if private? is not awnsered, ask if they want it private
if (private==null)
private = Browser.msgBox("Would you like to make this information Private?",'Name:\\n' + data[0][2] + '\\nDescription of Service:' + data[0][5] + '\\nReccomends:' + data[0][9] + ' ' + data[0][10], Browser.Buttons.YES_NO);
//adds opportunity to oportunity sheet if the info is not private
if (private.equalsIgnoreCase('no')){
var rec = data[0][9] + " " + data[0][10];
var row = ss.getLastRow();
ss.getRange(row, 1).setValue(data[0][2]);
ss.getRange(row, 2).setValue(data[0][5]);
ss.getRange(row, 3).setValue(rec);
ss.getRange(row, 4).setValue(data[0][6]);}
}