Email trigger for google sheet when a specific column is updated to "YES" and Email id's to be taken from another column in the same sheet - excel

I have multiple rows and columns which will be updated on a daily basis, and I want email to be triggered to mail id's taken from another column from the same sheet.
For example I have many email id's present in column C [can't mention a specific range since the data will be added everyday] and when values of column H are marked "Yes" then the mail id from the corresponding row in C column must be taken and email should be triggered to that id. I have tried multiple scripts but it's not working.

function onEdit(e) {
if(e.range.getSheet().getName()!='Sheet Name Used in this Operation') return;
if(e.range.columnStart==8 && e.value=="YES") {
//Send email
}
}
I'm not sure but I think you may need to create an installable trigger to send email.

Enable the Gmail service for your script
Go to your sheet and click Tools > Script editor
In the script editor, click Resources > Advanced Google Services... enable 'Gmail API' and click OK
Code
Copy & paste the following code (and make any modifications, if needed) to your sheet's script editor:
function sendEmail(dest, data) {
var messageBody = 'Hello, there has been a new release:\n\n' + JSON.stringify(data);
GmailApp.sendEmail(dest, 'Automated email from sheet', messageBody);
}
function onEditTrigger(e) {
var range = e.range;
if (range.columnStart == 8 && e.value == 'YES') {
// Prepare the email
var row = range.getSheet().getRange(e.range.rowStart, 1, 1, 8).getValues()[0];
var headers = range.getSheet().getRange(1, 1, 1, 8).getValues()[0];
var dest = row[1];
var data = {};
for (var i=0; i<8; i++) {
data[headers[i]] = row[i];
}
sendEmail(dest, data);
}
}
The code will get the 8 first columns of the row that has been modified and send them to the email specified in column B, along with the headers, as JSON format. You can see the spreadsheet I used for testing here. The email I received looks like the following:
Set the onEditTrigger function as an installable trigger
From the sheet's script editor, click the clock icon ("Current project's triggers")
Click the Add Trigger button
Choose the onEditTrigger function as the function to be ran, and On edit as the event type (example trigger configuration) and click save
Now every time the sheet gets modified the code above will run, and if appropriate, send the message.

Related

Delete rows after check text in a specific column

I would like to know which script to use with the following conditions:
Built in trigger Google Sheets at a specific time, not after edit or change.
Delete entire rows where the text "canceled" is in one of the cells of column D (4).
Should only check in rows >=5.
Text "canceled" appears because of a formula in column D.
Specific sheets only!
What I have so far, but not working.
function deleterowoncheck (e){
var sheets = ["TEST"]; // Please set your expected sheet names;
var sheet = e.range.getSheet();
if (sheets.includes(sheet.getSheetName()))
if (e.range.getColumn() == 4 && e.range.getRow() >= 5 && e.range.getValue() == "CANCELED") {
{
var sheet = e.range.getSheet(); // Sheet in which the change was made
sheet.deleteRow(e.range.getRow());
e.source.toast('Deletion complete.');
}
}
}
You can try the following script:
function deleteRowOnCheck() {
var ss = SpreadsheetApp.getActive().getSheetByName("Name of the sheet");
var data = ss.createTextFinder("CANCELED").findAll();
for(var i=0; i<data.length; i++)
{
var textFinder = ss.createTextFinder("CANCELED");
textFinder.findNext();
ss.deleteRow(textFinder.getCurrentMatch().getRow());
}
}
Just remember to configure the installable time driven trigger as desired.
References:
Time-driven triggers
Class TextFinder

Flutter - Convert data from firestore into Excel sheet

How to convert data from Firestore Into an Excel sheet on both Android app and flutter web?
Any response will be appreciated... thanks in advance!
Excel library for flutter
You can go through the documentation here.
Now as jay asked to explain in detail how you are gonna retrive the data and store it in the excel sheet,
First step,
var excel = Excel.createExcel(); //create an excel sheet
Sheet sheetObject = excel['SheetName']; //create an sheet object
Second step, commands to write in excel sheet,
where A is column id and 1 is row.
var cell = sheetObject.cell(CellIndex.indexByString("A1"));
cell.value = 8; // Insert value to selected cell;
Third step, getting data from firebase
QuerySnapshot _qs =
await _notificationRef.where('language', isEqualTo: selectedLang).get(); // Lets say I have some collection where I need to get some documents with specific language
//This loop will iterate in all of the documents in the collection
for (int i = 0; i < _qs.docs.length; i++) {
string data = _qs.docs[i].data()['names']; //Where name is the field value in the document and i is the index of the document.
}
});
Now if we combine second and third step
QuerySnapshot _qs =
await _notificationRef.where('language', isEqualTo: selectedLang).get();
for (int i = 0; i < _qs.docs.length; i++) {
var cell = sheetObject.cell(CellIndex.indexByString('A${i+1}')); //i+1 means when the loop iterates every time it will write values in new row, e.g A1, A2, ...
cell.value = _qs.docs[i].data()['names']; // Insert value to selected cell;
}
});
Once you are done with the data part you can save the file,
// Save the Changes in file
excel.encode().then((onValue) {
File(join("Path_to_destination/excel.xlsx"))
..createSync(recursive: true)
..writeAsBytesSync(onValue);
});
Once you are done with the saving you can choose any of the library to share your sheet to others,
Usually this libraries asks you to provide a file or file path
which you can easily provide using the last code block explained where I passed file path to join method

Delete rows after a date has passed automatically for Google Spreadsheets [duplicate]

I'd like to be able to delete an entire row in a Google Spreadsheets if the value entered for say column "C" in that row is 0 or blank. Is there a simple script I could write to accomplish this?
Thanks!
I can suggest a simple solution without using a script !!
Lets say you want to delete rows with empty text in column C.
Sort the data (Data Menu -> Sort sheet by column C, A->Z) in the sheet w.r.t column C, so all your empty text rows will be available together.
Just select those rows all together and right-click -> delete rows.
Then you can re-sort your data according to the column you need.
Done.
function onEdit(e) {
//Logger.log(JSON.stringify(e));
//{"source":{},"range":{"rowStart":1,"rowEnd":1,"columnEnd":1,"columnStart":1},"value":"1","user":{"email":"","nickname":""},"authMode":{}}
try {
var ss = e.source; // Just pull the spreadsheet object from the one already being passed to onEdit
var s = ss.getActiveSheet();
// Conditions are by sheet and a single cell in a certain column
if (s.getName() == 'Sheet1' && // change to your own
e.range.columnStart == 3 && e.range.columnEnd == 3 && // only look at edits happening in col C which is 3
e.range.rowStart == e.range.rowEnd ) { // only look at single row edits which will equal a single cell
checkCellValue(e);
}
} catch (error) { Logger.log(error); }
};
function checkCellValue(e) {
if ( !e.value || e.value == 0) { // Delete if value is zero or empty
e.source.getActiveSheet().deleteRow(e.range.rowStart);
}
}
This only looks at the value from a single cell edit now and not the values in the whole sheet.
I wrote this script to do the same thing for one of my Google spreadsheets. I wanted to be able to run the script after all the data was in the spreadsheet so I have the script adding a menu option to run the script.
/**
* Deletes rows in the active spreadsheet that contain 0 or
* a blank valuein column "C".
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
var rowsDeleted = 0;
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
if (row[2] == 0 || row[2] == '') {
sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
rowsDeleted++;
}
}
};
/**
* Adds a custom menu to the active spreadsheet, containing a single menu item
* for invoking the readRows() function specified above.
* The onOpen() function, when defined, is automatically invoked whenever the
* spreadsheet is opened.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Remove rows where column C is 0 or blank",
functionName : "readRows"
}];
sheet.addMenu("Script Center Menu", entries);
};
Test spreadsheet before:
Running script from menu:
After running script:
I was having a few problems with scripts so my workaround was to use the "Filter" tool.
Select all spreadsheet data
Click filter tool icon (looks like wine glass)
Click the newly available filter icon in the first cell of the column you wish to search.
Select "Filter By Condition" > Set the conditions (I was using "Text Contains" > "word")
This will leave the rows that contain the word your searching for and they can be deleted by bulk selecting them while holding the shift key > right click > delete rows.
This is what I managed to make work. You can see that I looped backwards through the sheet so that as a row was deleted the next row wouldn't be skipped. I hope this helps somebody.
function UpdateLog() {
var returnSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('RetLog');
var rowCount = returnSheet.getLastRow();
for (i = rowCount; i > 0; i--) {
var rrCell = 'G' + i;
var cell = returnSheet.getRange(rrCell).getValue();
if (cell > 0 ){
logSheet.
returnSheet.deleteRow(i);
}
}
}
quite simple request. Try this :
function try_It(){
deleteRow(2); //// choose col = 2 for column C
}
function deleteRow(col){ // col is the index of the column to check for 0 or empty
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getDataRange().getValues();
var targetData = new Array();
for(n=0;n<data.length;++n){
if(data[n][col]!='' && data[n][col]!=0){ targetData.push(data[n])};
}
Logger.log(targetData);
sh.getDataRange().clear();
sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);
}
EDIT : re-reading the question I'm not sure if the question is asking for a 'live' on Edit function or a function (like this above) to apply after data has been entered... It's not very clear to me... so feel free to be more accurate if necessary ;)
There is a simpler way:
Use filtering to only show the rows which you want to delete. For example, my column based on which I want to delete rows had categories on them, A, B, C. Through the filtering interface I selected only A and B, which I wanted to delete.
Select all rows and delete them. Doing this, in my example, effectively selected all A and B rows and deleted them; now my spreadsheet does not show any rows.
Turn off the filter. This unhides my C rows. Done!
There is a short way to solve that instead of a script.
Select entire data > Go to menu > click Data tab > select create filter > click on filter next to column header > pop-up will appear then check values you want to delete > click okay and copy the filtered data to a different sheet > FINISH
reading your question carefully, I came up with this solution:
function onOpen() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// create menu
var menu = [{name: "Evaluate Column C", functionName: "deleteRow"}];
// add to menu
ss.addMenu("Check", menu);
}
function deleteRow() {
// get active spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
// get active/selected row
var activeRow = ss.getActiveRange().getRowIndex();
// get content column C
var columnC = ss.getRange("C"+activeRow).getValue();
// evaluate whether content is blank or 0 (null)
if (columnC == '' || columnC == 0) {
ss.deleteRow(parseInt(activeRow));
}
}
This script will create a menu upon file load and will enable you to delete a row, based on those criteria set in column C, or not.
This simple code did the job for me!
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); // get active spreadsheet
var activeRow = ss.getActiveRange().getRowIndex(); // get active/selected row
var start=1;
var end=650;
var match='';
var match2=0; //Edit this according to your choice.
for (var i = start; i <= end; i++) {
var columnC = ss.getRange("C"+i).getValue();
if (columnC ==match || columnC ==match2){ ss.deleteRow(i); }
}
}
The below code was able to delete rows containing a date more than 50 days before today in a particular column G , move these row values to back up sheet and delete the rows from source sheet.
The code is better as it deletes the rows at one go rather than deleting one by one. Runs much faster.
It does not copy back values like some solutions suggested (by pushing into an array and copying back to sheet). If I follow that logic, I am losing formulas contained in these cells.
I run the function everyday in the night (scheduled) when no one is using the sheet.
function delete_old(){
//delete > 50 day old records and copy to backup
//run daily from owner login
var ss = SpreadsheetApp.getActiveSpreadsheet();
var bill = ss.getSheetByName("Allotted");
var backss = SpreadsheetApp.openById("..."); //backup spreadsheet
var bill2 = backss.getSheetByName("Allotted");
var today=new Date();
//process allotted sheet (bills)
bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 7, ascending: true});
var data = bill.getDataRange().getValues();
var delData = new Array();
for(n=data.length-1; n>1; n--){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){ //change the condition as per your situation
delData.push(data[n]);
}//if
}//for
//get first and last row no to be deleted
for(n=1;n<data.length; n++){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){
var strow=n+1 ; //first row
break
}//if
}//for
for(n=data.length-1; n>1; n--){
if(data[n][6] !=="" && data[n][6] < today.getTime()-(50*24*3600*1000) ){
var ltrow=n+1 ; //last row
break
}//if
}//for
var bill2lr=bill2.getLastRow();
bill2.getRange((bill2lr+1),1,delData.length,delData[0].length).setValues(delData);
bill.deleteRows(strow, 1+ltrow-strow);
bill.getRange(1, 1, bill.getMaxRows(), bill.getMaxColumns()).activate();
ss.getActiveRange().offset(1, 0, ss.getActiveRange().getNumRows() - 1).sort({column: 6, ascending: true}); //get back ordinal sorting order as per column F
}//function

Get and use user data from another sheet in Google Docs

We use google spreadsheets for reporting by quite a big number of users.
I have written a basic script, which opens a specific sheet depending on the current user:
var CurrentUser = Session.getUser().getEmail()
var ss = SpreadsheetApp.getActive();
switch(CurrentUser){
case "usermail1#gmail.com":
SpreadsheetApp.setActiveSheet(ss.getSheetByName("sheet1"));
break;
case "usermail2#gmail.com":
SpreadsheetApp.setActiveSheet(ss.getSheetByName("sheet2"));
break;
case "usermail3#gmail.com":
SpreadsheetApp.setActiveSheet(ss.getSheetByName("sheet3"));
break;
etc...
I would like to put the userdata and sheetnames into an external table and get these data depending on that table, so it is easier to maintain the list of e-mails and users.
How can I get data from a specific google spreadsheet and let the script work according to that?
You can try this. It simulates a VLOOKUP on a different sheet and switches to the 'matched' sheet in your current workbook. This doesn't handle non-matches, but that should be relatively straightforward to add to suit your case.
function switchSheets() {
// Current sheet
var ss = SpreadsheetApp.getActive();
// Target sheet (using the key found in the URL)
var target = SpreadsheetApp.openById("my_other_sheet_id");
var rows = target.getDataRange();
var values = rows.getValues();
// Get the current user
var CurrentUser = Session.getUser().getEmail();
// Now iterate through all of the rows in your target sheet,
// looking for a row that matches your current user (this assumes that
// it will find a match - you'll want to handle non-matches as well)
for (var i = 1; i <= rows.getNumRows() - 1; i++) {
// Match the leftmost column
var row = values[i][0];
if (row == CurrentUser) {
// If we match, grab the corresponding sheet (one column to the right)
target_sheet = values[i][1];
break;
}
}
// Now switch to the matched sheet (rememeber to handle non-matches)
ss.setActiveSheet(ss.getSheetByName(target_sheet));
};

Using Selenium RC, Excel (Data Driven) and SeleniumException

I'm working on an automation project right now which is to create an account on a specific site.
There are different set of rules that needs to be checked. There needs to be a set of data where some of the required fields are missing, the email address used to create on the account is already used on the system and the last set is where the account could be created. The general flow of the process is:
Run SeleniumRC
Get Data from ExcelFile
The Excel Data is composed of different sets.
Set A : Missing Required Fille
Set B : Email address is already used
Set B : Complete/Correct Data
Go the site.
Input all data.
If set A :
Then creation will not process.
It will provide output:
Row Number - Error
If set B :
Then creation will not process.
It will provide output:
Row Number - Error
If set C :
It will create account.
Provide Screenshot ounce login
Go back to step 2 until all rows found on the Excel File is completely checked.
Output will be placed on another Excel File
I am able to run the process however that is if I am using a flag for each entry in the Excel File. This does defeat the purpose of checking the creation process works as expected.
My Selenium Command goes like this:
public void test_CreateAccount() throws Exception {
//Some code to data from Excel Sheet
totalrows = s.getRows();
int i = 1;
while(i<totalrows){
//Some command to set data to string names
RowNum = s.getCell(0, i).getContents();
FName = s.getCell(1, i).getContents();
selenium.open // Go to a specific site
selenium.click("css=a > img"); // click create account
selenium.waitForPageToLoad("60000");
selenium.type("name=q1557", FName);
selenium.type("name=q1558", LName);
selenium.type("name=q1578", JobTitle);
selenium.type("name=q1579", email1);
selenium.type("name=email_confirm", email2);
selenium.type("name=q1583", phone);
selenium.type("name=q1584", ext);
selenium.type("name=q1585", fax);
selenium.type("name=q1587", company);
selenium.select("name=q1588", organization);
selenium.type("name=q1591", address1);
selenium.type("name=q1592", address2);
selenium.type("name=q1593", city);
selenium.select("name=q1594",state);
selenium.type("name=q1595", other);
selenium.type("name=q1598", zip);
selenium.select("name=q1596", country);
selenium.type("name=q1599", password1);
selenium.type("name=password_confirm", password2);
selenium.type("name=q1600", question);
selenium.type("name=q1601", answer);
selenium.click("name=submit_signup"); // click submit
i = i + 1;
}
}
When I run the command above, this does work. If data is SET A or B, then error occurred. If data is SET C, then it will create and then done.
In order to check all data within the Excel file or continue until end of totalrows, I placed a flag.
In the middle of the command I place something like
if(flag=1){ //input process only until submit button. }else
if(flag=2){ //input process only until submit button. }else{ create
}
I tried using try and catch with SeleniumException however it still does not work. Can you provide me with any idea on how to do this.

Resources