Firstly excuse me for my lack of knowledge.
Let me explain my current situation.
I have 3 Tabs on one Spreadsheet:
A master list
Types of Stock
Stock Requisition sheet
The master list simply gathers the information from the Stock Tab.
The Stock requisition gathers the information from Master list.
I currently have the following simple script that triggers based upon an edit.
function myFunction() {
MailApp.sendEmail(
"excessstock#greenlifepharma.co.uk",
"Excess Stock - Someone Added Stock ",
"Please see changes on main list of spreadsheet");
}
These are different triggers that i need...
A trigger for my function upon edit of the Stock sheet column C.
A different Trigger for when stock requisition sheet is edited.
Hope i explained well.
Very easy to do what you require. Copy and paste the code below and set an onEdit() trigger.
NOTE: In the IF statment I have 'Stock' and 'Stock Requisition', these must be exact matches to the sheet names i.e. capitalisation and spacing.
function myFunction(e) {
var getSheet = e.source.getSheetName();
var getRange = e.range.getColumn();
if(getSheet == "Stock" && getRange == 3 || getSheet == "Stock Requisition"){
var stockEmail = "---------";
var stockReqEmail = "----------";
MailApp.sendEmail(
(getSheet == "Stock") ? stockEmail : stockReqEmail ,
"Excess Stock - Someone Added Stock ",
"Please see changes on main list of spreadsheet");
}
}
Related
SoI'm using Google Sheets and I have an Activecampaign integration that adds a new row when a new user subscribe. I would like to add, with the user info, the current day - so I can know when people got in my list.
I have 4 tabs. The one that I want the day is called "leadData".
I tried this code, but it's not working:
function onChange(e) {
var sheet = e.source.getSheetByName("leadData")
columnToWatch = 1,
columnToStamp = 7, //change all of these to your needs...1 is column A, 2 is column B, etc
excluded = ["General Info", "Campaigns", "Automations"]; //add names of sheets/tabs to this list. The script will not work on these sheets.
if (e.range.columnStart !== columnToWatch || !e.value || excluded.indexOf(sheet.getName()) > -1) return;
sheet.getRange(e.range.rowStart, columnToStamp)
.setValue(new Date()).setNumberFormat("MM/dd HH:mm");
}
How can I solve it?
Answer:
The source and range fields are not part of the event object for onChange triggers. You must specify the Sheet and rows you want directly.
More Information:
As per the documentation on event objects, the Google Sheets onChange() trigger is an installable trigger and does not have the source nor the range fields in the event object that it gets passed.
Code Modifications:
You need to specify the sheet directly. Change the following line
var sheet = e.source.getSheetByName("leadData");
to:
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("leadData");
and change
sheet.getRange(e.range.rowStart, columnToStamp)
.setValue(new Date()).setNumberFormat("MM/dd HH:mm");
to
sheet.getRange(sheet.getDataRange().getNumRows(), columnToStamp)
.setValue(new Date()).setNumberFormat("MM/dd HH:mm");
References:
Event Objects | Apps Script | Google Developers
Installable Triggers | Apps Script | Google Developers
I have a table in Google Sheets in the format:
A B C
Day Date inventory demand
Day2 Date2 inventory demand
etc.
Others are required to fill in inventory and demand every day. Thus, it would be helpful if they open the sheet they jump always to the current date. This could be done over HYPERLINK or code. However, as I am informed onOpen works for the editor, however not for viewers. As this is currently the case. When I open the file I jump to the current date, however people viewing and editing the file per link do not.
Could somebody please help me? Thank you.
I also do not understand, why creating a cell that jumps to the current date as an alternative does not work.
I tried various variations of
=HYPERLINK("l i n k&range=B"&MATCH("TODAY",B1:B1500,0),"Jump to today")
or
=HyperLink("LINK&range=B" &Match(Today(),B6:B,1),"JUMP to Today")
// jump to current date
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("B:B");
var values = range.getValues();
var day = 24*3600*1000;
var today = parseInt((new Date().setHours(0,0,0,0))/day);
var ssdate;
for (var i=0; i<values.length; i++) {
try {
ssdate = values[i][0].getTime()/day;
}
catch(e) {
}
if (ssdate && Math.floor(ssdate) == today) {
sheet.setActiveRange(range.offset(i,0,1,1));
break;
}
}
}
try like this:
=HYPERLINK("#gid=0&range=B"&MATCH(TODAY(); B6:B; 0)+5; "zu heute")
I found the options: Edit Triggers
To manually create an installable trigger through a dialog in the script editor, follow these steps:
From the script editor, choose Edit > Current project's triggers.
Click the link that says: No triggers set up. Click here to add one now.
Under Run, select the name of function you want to trigger.
Under Events, select either Time-driven or the Google App that the script is bound to (for example, From spreadsheet).
Select and configure the type of trigger you want to create (for example, an Hour timer that runs Every hour or an On open trigger).
Optionally, click Notifications to configure how and when you are contacted by email if your triggered function fails.
Click Save.
Google Explanation
I'm trying to take a set of names with check boxes next to them and make a system so that you can check some of the names (mark them as "True") and click a button. It would then increment +1 the value next to the names of the people marked true.
Here is a link to a sample sheet:
https://docs.google.com/spreadsheets/d/1gf-BrXXR0cAYCn7bMkvvK65R290NXbP9D6aA68c06C8/edit?usp=sharing
If column A, row 2 (Tim's row) is marked true, I want to increment the value in column C, row 2 by one, so Tim would have a running total of tardies next to his name.
I hope this is do-able. Thanks!
(Now I know what you're trying to get)
In order to increment a value via the press of a button, as far as I know you have to use scripts (Tools -> Script Editor). Here's something I threw together:
// editCell takes the cell to edit and it's new value
function editCell(cellName, value) {
SpreadsheetApp.getActiveSheet().getRange(cellName).setValue(value);
}
// getCell takes the cell's value and returns it
function getCell(cellName) {
return SpreadsheetApp.getActiveSheet().getRange(cellName).getValue();
}
// plusOne adds one to the field supplied. It's linked to the button in the sheet
function plusOne() {
editCell("C2",getCell("C2")+1);
}
In order to make it work, you may need to change the targeted Cell (currently C2). You'll also need to create a drawing (Insert -> Drawing) which will act as the button you'll be able to press. Once inserted, click on the three dots on it and click on Link Script. Type in plusOne. When executing it the first time, it'll ask you to authenticate the use of scripts.
That should do the trick. I hope you have some understanding of Java Script though (to modify the code to your needs optimally).
Edit - Expandable version
So, to make every number behind a ticked field increase by one, you can use this version of the code:
// Adds one to every field within "AddArea" that has a tick in front of it. It's linked to the button in the sheet.
function plusOne() {
var ss = SpreadsheetApp.getActiveSheet();
var range = ss.getRange("AddArea");
var values = range.getValues();
var newValues = [];
for (var i = 0; i < range.getNumRows(); ++i) {
var row = values[i];
if(row[0]) {
newValues.push([true, row[1]+1]);
}
else {
newValues.push([false, row[1]]);
}
}
range.setValues(newValues);
}
You need to define a custom named area, named "AddArea" (Data -> Labeled Areas [or similar]), link the script to a button and allow the script to be run. This was hard but very fun to figure out.
Example Sheet for reference (updated)
Can be achieved with just, for example for C2:
=A2+C2
but you would need to turn on iterative calculation (File > Spreadsheet settings... > Calculation [Max. 1 is adequate]) and I would not really recommend that over a trigger with Google Apps Script.
I'm trying to have a timestamp appear in a column whenever data is added to a sheet. I've had some success with the following script:
function onEdit(e) {
var colToWatch = 2, colToStamp = 1;
if (e.range.columnStart !== colToWatch) return;
var writeVal = e.value ? new Date() : '';
e.source.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.setValue(writeVal);
}
My issue is, every time the text in col 2 is edited, the timestamp changes to the current time.
My hope it to have a timestamp that shows when the text was originally added (so it can be organized by that date in another sheet). Other people will have access to this sheet and may change something by accident and cause changes in the sheet organized by date.
I'm new to scripting, is it possible to have an onEdit only run the first time data is added? It seems like onChange() might be able to help me, but I haven't been able to find anything.
Basically you want to terminate if the timestamp cell is already filled.
if (e.source
.getActiveSheet()
.getRange(e.range.rowStart, colToStamp)
.getValue()) {
return;
}
I have a very large sheet of data with comments applied to different projects (totally 16). Each comment has a status such as active, confirmed, cancelled or blank (if not applicable) applied to the projects
It's difficult for users to update the status with filters in the source sheet because when many users using the sheet they cannot apply different filters at the same time.
The best way is to pull all data from the source sheet to many target sheets (one for each project) and apply filters according to project, so the users can update the status in target sheets. My problem is how to get the new updated status from the target sheets into the source sheet.
I have found a script to automatically update all target sheets whenever I change or add something in the source sheet, but I need also to update the source sheet when I change the status in the target sheet (project sheets). See script below:
function getdata() {
var files = DriveApp.getFolderById(""folder key with target sheets"").getFiles()
while (files.hasNext()) {
var file = files.next();
var shoot = SpreadsheetApp.openById(file.getId());
var sourcesheet = SpreadsheetApp.getActive().getSheetByName(""source sheet name"");
var sourcerange = sourcesheet.getRange('A:AE');
var sourcevalues = sourcerange.getValues();
var destsheet = shoot.getSheetByName('target sheets name same for all');
var destrange = destsheet.getRange('A:AE');
destrange.setValues(sourcevalues);
See below a link of my source sheet:
https://docs.google.com/spreadsheets/d/1h0mpPo2nl9AoCF-hJDjMaU3sZg-qBX4dat7Ig4poAJo/edit?usp=sharing
The sheet "form responses new" receiving comments from users through a form and I manually cut and paste them in sheet ""Sent"" after review and submission.
You might want to look into making filter views for each project in the single sheet. Filter views are applied only for the person using it and do not modify it for others. From your question this may be a better solution than a syncing script.
However to answer the question asked an onEdit event in each of the project sheets could manage the reverse updates.
function onEdit(event){
var range = event.range;
if(range.getSheet().getName() == "Sheet1" && range.getColumn() > 1 && range.getRow() > 1 ){//example conditionals to limit the action to exclude headers or other static data could be changed to work specific cells or ranges
var mainsheet = SpreadsheetApp.openByUrl("main spreadsheet URL").getSheetByName("destination sheet");
var dataA1 = range.getA1Notation();
range.copyTo(mainsheet.getRange(dataA1));
}
}
this is a simple trigger and requires your users to have edit access to your main sheet. If you do not want to give them that access you could use an installable trigger instead.