How to run a Dynamic Script in Google Sheets (live edit) - google-sheets

I am trying to run a script that will execute when the checkbox is marked "TRUE" and send an email to a client. I can not get the triggers to work and I can seem to make my own work either. I am putting the code below. Please help.
'''code'''
***Email Function
function SendEmail(i) {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//var lr= ss.getLastRow();
//for (var i = 2; i<=lr;i++){
var currentEmail= ss.getRange(i, 1).getValue();
//logger.log(currentEmail);
var currentADID= ss.getRange(i, 3).getValue();
MailApp.sendEmail(currentEmail,"Customer Ready"+ currentADID,"This customer should be ready to schedule and installtion date and time" );
}
Trigger Function
function CheckCD() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lr= ss.getLastRow();
for (var i = 2; i<=lr;i++){
var currentDCheck= ss.getRange(i, 4).getValue();
var x= onEdit():
if (currentDCheck == true)
SendEmail(i)
}
}***

You actually misunderstood how to use onEdit trigger, although you need to install the trigger in this case due to permission needed by MailApp.sendEmail
Anyways, you need to make use of the event object (e) as it holds the details about the edited cell's properties. See code below:
Code:
// Trigger function, install it under "Triggers" tab as you need permission for MailApp
function CheckCD(e) {
// get the row and column of the edited cell
var row = e.range.getRow();
var column = e.range.getColumn();
// proceed only if edited cell's range is D2:D and value is "TRUE"
if (row > 1 && column == 4 && e.value == "TRUE") {
// get the sheet where the cell was edited
var ss = e.source.getActiveSheet();
// get Email and ADID of the same row where checkbox was ticked
var currentEmail = ss.getRange(row, 1).getValue();
var currentADID = ss.getRange(row, 3).getValue();
MailApp.sendEmail(currentEmail, "Customer Ready" + currentADID, "This customer should be ready to schedule and installtion date and time");
}
}
Install trigger:
Make sure to choose On edit event type and choose the function you want to run. (in this case, CheckCD)
Sample data:
Output:
Note:
The behavior of this script is that every time someone checks a checkbox on range D2:D and the resulting value is TRUE, then it sends an email. (as it seems you have different email per row, but if not, send them all in one email)
References:
Installable Triggers

Related

Google Sheets connecting with Gmail or Slack

I'm looking for a code I can use in google sheets.
I need to get a notification when a cell changes in a specific column and get it through email or Slack.
Can someone please help me?
I'm currently using
function onSpeEdit(e) {
var sh = e.source.getActiveSheet();
var rng = e.source.getActiveRange();
var col = 1
if (sh.getName() == 'mySheet' && rng.getColumn() == col) {
MailApp.sendEmail(
'yourEmail#gmail.com',
`Change Notification`,
`Change in ${rng.getA1Notation()} old value "${e.oldValue}" new value "${e.value}" `);
}
}
Try
function onSpeEdit(e) {
var sh = e.source.getActiveSheet();
var rng = e.source.getActiveRange();
var col = 1
if (rng.getColumn() == col) {
MailApp.sendEmail(
'yourEmail#gmail.com',
`Change Notification`,
`Change in ${rng.getA1Notation()} of ${sh.getName()} old value "${e.oldValue}" new value "${e.value}" `);
}
}
change name of sheet, column and email address
you will need to define an installable trigger in order to use services that requires authorization.
Installable Triggers
edit : il you want to add another information, i.e. from column B, try to replace the sentence by
`Hey, the title ${sh.getRange('B'+rng.getRow()).getValue()} from sheet ${sh.getName()} changed. Before it has the number ${e.oldValue} now is ${e.value}.`

Google Sheets - Creating a button to run on a column selected by the user

I'd like to have a user click/highlight a column (or a checkbox at the top of the column, then click a single button to run the script on all checked columns.
var values1 = "Pass";
// Where to look for Auto:
var enabledDisabled = sheet.getRange("B3:B140").getValues();
var testResultsRange = sheet.getRange("AL3:AL140");
var testResults = testResultsRange.getValues();
// Keyword to look for in Auto: column
var putValues = [];
for (var i = 0; i < enabledDisabled.length; i++) {
if (enabledDisabled[i][0] === "Yes") {
putValues.push([values1]);
} else {
putValues.push([testResults[i][0]]); // Push the existing cell value
}
}
// Put value1 inside row, column# for test result
testResultsRange.setValues(putValues);
Instead of hardcoded ranges, I'd like it to run on every column that is checked, basically.
Any help would be hugely appreciated!
One solution I usually use is to put checkboxes on the first row of the columns, then with onEdit I run the script by clicking on the checkbox and by detecting the column by getColumn ()
function onEdit(event){
var sh = event.source.getActiveSheet();
var cel = event.source.getActiveRange();
if (sh.getName()=='mySheet' and cel.getValue()){
var col = cel.getColumn()
// run your script in column 'col'
cel.setValue(!cel.getValue())
}
}

Google Sheets - making script run on iOS sheets app

I am running the following script as its own .gs file
/**
* TITLE:
*     Hide a row if a value is inputted.
*/
//**GLOBALS**
// Sheet the data is on.
var SHEET = "Norm Adam";
// The value that will cause the row to hide.
var VALUE = "Yes";
// The column we will be using
var COLUMN_NUMBER = 11
function onEdit(e) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var activeSheet = ss.getActiveSheet();
  
  //Ensure on correct sheet.
  if(SHEET == activeSheet.getName()){
    var cell = ss.getActiveCell()
    var cellValue = cell.getValue();
    
    //Ensure we are looking at the correct column.
    if(cell.getColumn() == COLUMN_NUMBER){
      //If the cell matched the value we require,hide the row.
      if(cellValue == VALUE){
        activeSheet.hideRow(cell);
      };
    };
  };
}
It works fine on a computer browser but on iOS device it doesn't work through the google sheets app and I actually can't even get the editable through safari. I read that only the onEdit function will work on a mobile device so I figured this should work. Is there another piece to this puzzle?
Thanks
Mike
(credit for script creation goes to: https://yagisanatode.com/2018/05/26/how-to-hide-a-row-based-on-a-cell-value-in-google-sheets-with-filter-or-google-apps-script/ )
Script V2:
I commented below on this still not working in iOS. I figured the simpler it was the more likely to work?
function onEdit(e) {
if (e.range.getColumn() == 11 && e.value == 'Yes') {
e.range.getSheet().hideRows(e.range.getRow());
}
}
getActive calls, especially ss.getActiveCell() should be avoided on mobile apps. Consider alternatives like e.range to get the edited range from event objects.

running script on an Inactive sheet

I have been using the following script to move "Finished" columns from one sheet to another:
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = event.source.getActiveSheet();
var r = event.source.getActiveRange();
if(s.getName() == "Sheet1" && r.getColumn() == 15 && r.getValue() ==
"Finished") {
var row = r.getRow();
var numColumns = s.getLastColumn();
var targetSheet = ss.getSheetByName("Finished");
var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
s.getRange(row, 1, 1, numColumns).moveTo(target);
s.deleteRow(row);
}
}
Im trying to figure out how to get the script to run even if the sheet has not been opened or edited. Im just not sure how to go about changing it to use a time trigger every minute or so.
There are two aspects to the change to a timed trigger from onEdit.
The first concerns revisions to the code, the second is the trigger details.
Code
The code can't be re-used because the timed trigger doesn't provide the same event details as OnEdit.
In addition, it is possible that several rows might be tagged "Finished" between each trigger event, and the code needs to respond to them all. lastly, each "finished" row can't be deleted as it is found, because this affects the row number of all remaining rows in the column.
The following code would do the job:
Most of it will be familiar to the questioner. The main except is to keep a record of each row number that is moved to "Finished". This is done by pushing the row number onto an array. Then after all data has been examined and moved, there is a small loop that takes the row numbers recorded in the array and deletes the relevant row. The loop works from the highest row number to the lowest; this is so that the deletion of a row does not affect the row number of any remaining rows to be deleted.
function so_53305432() {
// set up the spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// identify source and target sheets
var sourceSheet = ss.getSheetByName("Sheet1");
var targetSheet = ss.getSheetByName("Finished");
// get some variables to use as ranges
var sourcelastRow = sourceSheet.getLastRow();
var numColumns = sourceSheet.getLastColumn();
var targetLastRow = targetSheet.getLastRow();
// get data from the Source sheet
var sourceData = sourceSheet.getRange(1, 1, sourcelastRow, numColumns).getValues();
// set up some variables
var finishedRows = [];
var i = 0;
var x = 0;
var temp = 0;
// loop through column 15 (O) checking for value = "Finished"
for (i = 0; i < sourcelastRow; i++) {
// If value = Finished
if (sourceData[i][14] == "Finished") {
// define the target range and move the source row
var targetLastRow = targetSheet.getLastRow();
var target = targetSheet.getRange(targetLastRow + 1, 1);
sourceSheet.getRange(+i + 1, 1, 1, numColumns).moveTo(target);
// keep track of the source row number.
finishedRows.push(i);
}
}
// set up variables for loop though the rows to be deleted
var finishedLength = finishedRows.length;
var startcount = finishedLength - 1
// loop throught the array to delete rows; start with the highest row# first
for (x = startcount; x > -1; x--) {
// get the row number for the script
temp = +finishedRows[x] + 1;
// delete the row
sourceSheet.deleteRow(temp);
}
}
Trigger
The trigger needs to be revised. To do this:
1) Open the script editor, select Current Project Triggers. OnEdit should appear as an existing trigger with an event type of OnEdit.
2) Change "Choose which function to run" to the new function,
3) Change "Select Event Source" from Spreadsheet to "Time Driven".
4) Select "Type of time based trigger" = "Minutes Timer".
5) Select "Select Minute Interval" = , and select a time period and interval.
6) Save the trigger, and then close the Trigger tab
If "Every Minute" is found to be too often, then the Questioner could try "Every 5 minutes".

Google Sheets Script permissions for everyone allowed access to a sheet

I know there are a lot of questions out there related to Google Scripts and some of them touch on my issue but I can't seem to figure out the full answer.
I only want to be able to run 1 or 2 scripts in the same project file for 1 spreadsheet. How do I allow permission for everyone with whom the sheet is shared WITHOUT forcing each user to go through the process of allowing Authorization? Is this possible?
Maybe there is an alternative script? Here is my script (in case this helps):
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{name:"Go to active row", functionName:"Go to active
row"}];
sheet.addMenu("Scripts", entries);
myFunction();
};
function gotoend() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getDataRange().getValues();
lastRow.forEach(function (row,index) {
if (row[3] == "") { // row[0] is the same as Column A. row[1] = B
lastRow.length = index;
}
});
var newRange = sheet.getRange(lastRow.length,1);
sheet.setActiveRange(newRange);
}
/**
* #OnlyCurrentDoc
*/

Resources