I'm not a technical person and need help on using apps script.
I have a sheet with 5 tabs (each sheet are exactly the same format of column headers)
Column B is a dropdown of 4 points of contact. E.g. John, Anna, Peter and Michelle
Goal: when a user selects a name from the dropdown, it will send an email to whoever was chosen.
subject and message can be a generic template for everyone
Can someone help me with a script I can copy and paste for this?
As it says in the comments, StackOverflow is not a coding writing service, but I will give you a couple of keys to achieve it by yourself.
What is the main point? We need to observe the changes on the sheet, and when it coincides with the cell that contains the email, we send the email to the one the value is in the cell.
We need to observe the changes on the sheet, how we achieve it? With an installable trigger we can capture edits events on the Sheet, as the change of the drop-down list.
Finally we need to filter the event and only attend to the ones that are in the cell or cells that contain the drop-down.
In this example I have the cell A1 with the drop-down of emails:
const sendEmailFromSheets = (e) => {
const range = e.range;
const email = e.value;
if( range.getA1Notation() === 'A1') {
MailApp.sendEmail(email,'Message from the Sheet', 'Body')
}
}
After this, we attach this function to an installable trigger with the source From spreadsheet and type On change.
With all of this, you should be able to change it to adapt it to your needs.
Documentation:
SpreadsheetApp
Event-driven Trigger
Related
I own two columns A contains numbers and B contains checkboxes.
If A = 0 I would like to auto-check the checkbox else I would like to let the user checks it (or not). But when I use a IF statement in the checkbox cell I can't check it myself (I lose its behavior).
I need something like :
=IF(A1=0;TRUE;#keep checkbox classical behavior#)
How could I do that ?
Explanation:
I don’t think you can accomplish this behaviour with a google sheet formula without compromises. This auto-check behaviour you describe can only be achieved with a trigger; activated when you edit a cell in column A.
I believe you need to take advantage of Google Apps Script and in particular use an onEdit trigger.
Solution:
Click on Tools => Script editor on the top menu of the spreadsheet file, copy & paste the below code into a blank script and click on save. After that, when you put 0 in column A, the corresponding row in column B will be checked. This behaviour will be applied to a sheet named Sheet1. Change that part of the code to apply it to a sheet with a different name.
function onEdit(e) {
const sheet= `Sheet1`; // change Sheet1 to the name of your sheet
const as = e.source.getActiveSheet();
const col = e.range.getColumn();
const row = e.range.getRow();
if(as.getName()==sheet && col==1 && e.value==0){
as.getRange(row,2).setValue(true);
}
}
Unfortunately you can't do what you wish in one formula. As you discovered, interacting with a checkbox in a cell with a formula is essentially like typing over that formula and would overwrite it.
My suggestion to accomplish this is to add an extra column and use the formula you suggested as the final check to what the state of that row should be (true or false).
=if(A2=0,True,B2)
Where A is your values and B is your user entered checkbox.
Here's a sample sheet with it loaded as an array formula. https://docs.google.com/spreadsheets/d/1z8A4WqVppcxGlGiM3l-kW6q88iYBE6LGw5PyVfRh9Js/edit#gid=0
You could then format that column as checkboxes, but if you use an array formula it will get tripped up when it thinks the checkbox is blocking the formula for each new row.
I need some help from the experts here.
Please take a look at this spreadsheet:
https://docs.google.com/spreadsheets/d/1tSl8LxhLGoQMVT_83Ev4jMu_Fo1AW8lN6N8Yw8kX44U/edit#gid=640017957
Here is the story (in short):
Our company deals with many different sellers of e-commerce businesses that want to sell their business to new owners. For each seller, we have a specific sheet (seller A, seller B, seller C in the example spreadsheet above) where we fill out various data, including the last action and next action that we took/need to take when handling the communication regarding the sell of the business with each of our potential buyers. We try to find an easy way to automatically store the data that we fill out in the “last step” column so that every time we update a cell in this column, the data will be automatically copied to a sheet that store all the communication history with each buyer for each deal.
I thought about creating a tab such as the “all actions” sheet in the example spreadsheet above, where every time we update the data in the “last action” column, a new row will be automatically added to the “all actions” sheet with the relevant data shown there.
Is there any way to achieve this goal? If not, will you recommend a different method to get similar results so that we can automatically store (and see once needed) all the data that was entered in the past in the “last action” column?
You can use triggers to do this.
In your sheet, click Tools > Script Editor.
In the script editor, click Edit -> Current Project Triggers
In that window, in the lower right, there is a button to "Add Trigger".
When you add the trigger set the "Select Event Type" to "On Change".
Reference the function you wish to run that will do the work of adding the information.
You will need to write the JavaScript function (in the script editor) to do the insert.
If you are not familiar with JavaScript and using it to work with Google Sheets, the learning curve isn't very steep to do this basic thing. I recommend digging in. The power you will wield with your spreadsheets is well worth the time.
You need to use Google Apps Script and the onEdit trigger in particular.
Try this:
function onEdit(e) {
var row = e.range.getRow();
var col = e.range.getColumn();
if ( e.source.getActiveSheet().getName() != "All actions" && row>1 && col==2 ){
s_name = e.source.getActiveSheet().getName();
b_name = e.source.getActiveSheet().getRange(row,1).getValue();
a_taken = e.source.getActiveSheet().getRange(row,2).getValue();
e.source.getSheetByName("All actions").appendRow([s_name,b_name,a_taken,new Date()])
}
}
In order to use this function you need to go to the Spreadsheet file menu; click on Tools => Script editor, clear the code.gs file and copy the aforementioned code snippet. Then, everytime a seller edits the last action column the relevant information will be appended to the All actions sheet.
Try this:
function onEdit(e) {
var sh=e.range.getSheet();
var s_name=sh.getName();
if ( s_name!= "All actions" && e.range.rowStart>1 && e.range.columnStart==2 ){
values=sh.getRange(e.range.rowStart,1,1,2).getValues()[0];
e.source.getSheetByName("All actions").appendRow([s_name,values[0],values[1],new Date()])
}
}
I have a spreadsheet on Google sheets with 2 sheets, Sheet1 and Sheet2. On Sheet1 I have 2 columns (ID1 and Result1), in which are filled. On Sheet2 I have 2 columns (ID2 and Result2), in which ID2 is filled and Result2 is filled with the word "empty".
Sheet1 in my real spreadsheet is getting data from Google Forms, so every time Sheet1 receives a value on ID1 and Result1, it should search for the ID1 value on Sheet2's ID2 and when finding, paste Result1 value in Result2 in the row it's was found.
Result2 would then only be updated when there's new data on Sheet1 submitted from the form.
I created this editable form and spreadsheet to make it easier to understand (I also added a note explaining it in there). You can see the form here and the spreadsheet here.
In cell B2 of your second sheet I entered the following:
=VLOOKUP(A2,Sheet1!A:B,2,FALSE)
I guess VLOOKUP on Google-Sheets does allow reference across worksheets?
FYI, when entering the formula, after enter the first argument which is your look up criteria, you can click your sheet1 and highlight column A and B, then go back to your sheet2 (with the second argument automatically filled by the system) to finish the formula with the third (result range column position within the look up range) and fourth argument (TRUE for approximate match and FALSE for exact match) and hit Enter to exit the formula.
After looking through the current answers and comments I think I understand what you are looking for.
Answer:
You can do this in Google Apps Script by creating a function that is bound to your Google Form which collects the latest response and does the data processing, and making it run on Form submission.
Steps to take:
Firstly, on your Form, you will need to create a bound script. From the menu in the top right of the Form edit page, click ⋮ > Script editor, which will open a new script page.
From there you can make a script which will automatically do this for you, and make an Installable Trigger which runs when you need.
Code:
After opening the Script Editor, you will see a ready-to-edit function that looks like this:
function myFunction() {
}
Replace the entire script with the following code:
function onSubmit(e) {
var responses = FormApp.getActiveForm().getResponses();
var response = responses[responses.length - 1].getItemResponses();
var connectedSheet = SpreadsheetApp.openById('<your-sheet-id>').getSheets();
var sheet2 = connectedSheet[1];
var result2Column = sheet2.getRange('A1:A').getValues();
for (var i = 0; i < result2Column.length; i++) {
if (response[1] == result2Column[0]) {
sheet2.getRange('B' + (i +1)).setValue(response[0]);
}
}
}
Make sure to replace <your-sheet-id> with the unique ID of your Google Sheeet - you can find this in the URL of the sheet between the d/ and /edit like so:
https://docs.google.com/spreadsheets/d/<your-sheet-id>/edit
Run the script by pressing the play button (►) and authorise the application to run.
Then go to Edit -> Current Project's Triggers and set up a new installable trigger with the following settings:
Choose which function to run: onSubmit
Choose which deployment should run: Head
Select event source: From form
Select event type On form submit
Explanation:
This script will run each time a new form submission is made automatically - it will take the ID from the form response and search Sheet2 for it. If it's found, then the response given for result will be put in Sheet2 also, next to the corresponding ID.
References:
Google Apps Script Installable Triggers
do it simply like this:
=ARRAYFORMULA(IFERROR(VLOOKUP(A2:A, Sheet1!A:B, 2, 0)))
or reset by checkbox:
I've created a spreadsheet that collects data from a Google Form.
When a certain cell's value reach above certain number, I'd like to the sheet to send an email to my account. However I can't seem to get my head around how to do this. I've realized that I can't use the conditional formatting option that I get by right clicking the cell. I can only alter the cell/text color by using that option. Do I have to use a script to be able to perform this task automatically?
(The sheet collects absence/attendance data in a class, and when the absence percentage reach a certain value (15%) I'd like the sheet to e-mail a notice about this.)
This might be a newbie question, but that's what I am; A newbie.
You can setup a onFormSubmit trigger on the Response Spreadsheet and after every submit, it can calculate the attendance percentage and send an email using the MailApp.sendMail() method.
function calculate(e)
{
var s = SpreadsheetApp.getActiveSheet();
var data = s.getDataRange.getValues();
for (var rows in data) {
// Calculate the attendance data
}
if (condition_met) {
MailApp.sendEmail(email, subject, message);
}
}
I have Written Script on Google Spreadsheet to send Email when spreadsheet is modified or any Data is added. Email Trigger is working but whenever any data is entered in next Row it send Email to previous email address also.
Please suggest solution
The below is written script :
function onEdit(e) {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = 1; // Number of rows to process
var dataRange = sheet.getRange(startRow, 1 , numRows,3) // Fetch the range of cells A2:B3
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[2]; // First column
var message = row[0] + "requested" + row [1]; // Second column
var subject = "Sending emails from a Spreadsheet";
MailApp.sendEmail(emailAddress, subject, message);
}
}
Your question is unclear... nowhere in the script I see something that reads which cell is actually modified... your target range is hardcoded on row 2 so the only row that can be processed is row 2 (and the mail can only be sent once)...
So can you :
explain how it should work
explain how it works now , especially what do you mean by 'previous email'
remove typos in your code (row[2] is not First column)
explain how you trigger this function : the name onEdit(e) suggest an onEdit trigger but simple triggers cannot send mail so I suppose you have set some other trigger.
explain why (e) in your function parameter and not using it ?
EDIT : thanks for the complement of information.
The script you suggest is not sufficient to achieve what you want. The idea here is to check if something in the sheet has been modified either by adding (or inserting) a row of data or (if I understood well) by editing any row in the sheet with a new value.
This is not really as simple as it looks at the first glance ;-)
What I would do it to take a 'snapshot' of the sheet and -based on a timer or onEdit - compare that snapshot to the sheet's current state.
There is more than one way to get that result, you could have a second sheet in your spreadsheet that no one could modify and that is a copy of the main sheet that you update after each modification/mail send. So before updating the script should look for any difference between the sheets and send a report to the corresponding email when a difference is found.
Another way to do that is to store the sheet data converted to a string in the script properties, the principle is the same but it's more 'invisible' for normal users accessing the spreadsheet.
You could also use scriptDb or your userproperties but the script properties is probably better suited (simpler) for this use case.
Tell us what you think/prefer and I (or someone else) could probably give you some code to start with.
It appears that you're using a shared spreadsheet to collect the add-user-requests, and trusting the requesters to fill in the information. In the detail document you shared, it further appears that requests are ADDED, but not EDITED. (That's an important simplifying distinction.)
I suggest that what you really need is to use a form for receiving that input. Using a form will create a "data table" within your spreadsheet, a set of columns that you must not mess with. (You can edit the contents, add and delete rows, but must not add or remove columns.) However, you CAN add columns to the spreadsheet outside of this table, which gives you a handy place to store state information about the status of individual requests.
Further, you can trigger your processing to run on form submit, rather than a simple "onEdit" - this gets away from the problem that ScampMichael pointed out. Alternatively, you can use an installable edit trigger, as described in this answer.
Try this sheet, and this form. Save yourself a copy, go into the script and remove the comments that are stopping emails from being sent, and try it out. There's a menu item in the spreadsheet that can kick off processing; just clear the "Request State" column to re-run it. You can open the form (and find its URL), and add more entries to experiment.
It's the core of a similar system that I've written, and contains a discreet state machine for processing the requests. My system has large amounts of very complex data in multiple spreadsheets, so it often gets pre-empted, then needs to run again. (I use a timed trigger for that.) That's why requests are handled through states. If you find that too complex, pull out only the parts you need.