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.
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 have an existing google form and am looking to:
Image 1. of the google form question.
1) Have the response to the question (What is your name) in the form automatically populate (Sheet 1, Column C) on this existing google sheet
Image 2. Where the google form data will have to go
2) The timestamp that gets generated with each google form submission to automatically populate (Sheet 1, Column E) in the YYYY-MM-DD format.
3) While these google form responses will be recorded in this spreadsheet there will be times when I will have to manually go in and enter information in subsequent rows as well.
Is this possible to do? I am new to bringing in data from google forms into google sheets, can anyone help with the questions above?
Okay. A couple of things.
Go to the Tool menu > Script editor.
Name the script (maybe 'Form Submission'?) by clicking the 'untitled project' text in the top left of the editor.
Replace all text in code.gs with the code below. (Change the code where indicated).
Then go to Edit > Current project's triggers.
Click the link that says: No triggers set up. Click here to add one now.
Under Run, select onSubmit.
Under Events, select on form submit.
Click save.
Now you should go back to the editor and push the play button. This will run the function and initiate the authorisation process. Click through the prompts and accept.
Now, every time a form is submitted, the name and timestamp will be copied over.
function onSubmit() {
var spreadsheet = SpreadsheetApp.getActive();
var responseSheet = spreadsheet.getSheetByName('Form Responses 1');
var copyToSheet = spreadsheet.getSheetByName('Target');
var rLastRow = responseSheet.getLastRow();
var tLastRow = copyToSheet.getLastRow() + 1;
var lastCol = responseSheet.getLastColumn();
var values = responseSheet
.getRange(rLastRow, 1, 1, lastCol)
.getValues()[0];
var timestamp = Utilities.formatDate(new Date(values[0]), Session.getScriptTimeZone(), 'yyyy-MM-dd');
var name = values[1];
copyToSheet.getRange('C' + tLastRow).setValue(name);
copyToSheet.getRange('E' + tLastRow).setValue(timestamp).setNumberFormat('yyyy-MM-dd');
}
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");
}
}
This is my 1st time using Google sheets, I have a Master sheet set up for people to use, but I don't want them to have a chance to change the master and I don't trust them to create a copy before using the sheet.
I want people to start out opening the master but have the name changed after they open it and before they have the chance to make any changes.
The name of the new sheet should be the name used in the Master but add to it the current date.
The new sheet can be added to the current workbook
I don't want this to happen again if they sheet being created is opened later to modify or view the new sheet
I'm open to alternatives
The Google sheets api is fine to use
Please include examples of code or pointers to samples that all ready work
Thanks for the help
Found some code that started me down the right road, played with it until it did what I wanted. Only problem is that when you use the Google Sheet app on phone does not execute the onOpen code.
var ss = SpreadsheetApp.getActiveSpreadsheet();
/**
* Duplicate and rename Master spreadsheet invoking the makeCopy() function.
* The onOpen() function is automatically run when the spreadsheet is opened.
*/
function onOpen() {
var entries = [{
name: "Weekly Cashier Accounting",
functionName: "duplicateTemplateSheet"
}];
ss.addMenu("New sheet", entries);
var oldSheet = ss.getActiveSheet();
ss.setActiveSheet(ss.getSheetByName("Master"));
var formattedDate = Utilities.formatDate(new Date(), "PST", "MM-dd-yyyy");
if (ss.getSheetByName(formattedDate) == null) {
Logger.log("Does not exist");
var newSheet = ss.duplicateActiveSheet();
newSheet.activate();
ss.moveActiveSheet(2);
newSheet.setName(formattedDate);
ss.setActiveSheet(ss.getSheetByName(formattedDate));
}
};
Thanks for the help