Copy cell background to other spreadsheets - google-apps-script

I am new to Google Apps Script and I don't know how to do some codes. I have two spreadsheets, 1 for the admin and 1 for the client. Every time the admin will update the cells the client side must be updated also. However, only the data in the cells are copied but not the backgrounds in it. Here are the screenshots for better understanding:

Copy value and background from Admin to Client
This requires an installable onEdit(e) trigger. You will also need the id of the client spreadsheet. Note you cannot run this from the Script Editor unless you do it from another function that supplies the event object. See this example.
function updateClient(e) {
var ss=SpreadsheetApp.openById('ClientSideSpreadsheetId');//You need to provide id here. You cannot pass other parameters to this function because it a trigger.
var sh=ss.getSheetByName(e.range.getSheet().getName());
var rg=sh.getRange(e.range.rowStart,e.range.columnStart);
rg.setValue(e.value);
rg.setBackground(e.range.getBackground());
}
I tested this on my account and it works. I suspect that you'll have trouble getting it to run so read the answer in the link I provided thoroughly before telling me that it doesn't work.
This is what the event object looks like:
{"authMode":{},"range":{"columnStart":3,"rowStart":18,"rowEnd":18,"columnEnd":3},"source":{},"user":{"nickname":"nickname","email":"email#email.com"},"triggerUid":"123456","value":"3"}
Event Objects

Related

Custom google sheets function that auto updates when change is made wont change when others edit

I have a custom function that auto updates when a change is made on the google spreadsheet, but when some other users edits the sheet the function doesn't work for them, how can i make it update for anyone that uses the sheet.
The function auto updates using this:
function onEdit(e) {
SpreadsheetApp.getActiveSheet().getRange('Z1').setValue(Math.random());
}
Then passing the parameter of Z1.
Explanation:
Just a couple of notes to make sure we are on the same page.
This is not a custom function but an onEdit trigger function.
As the name suggests it is triggered when user changes the value of any cell in a spreadsheet.
The function is only triggered when the change of the cell is made by a user and not by formulas or scripts.
Potential Issues:
Make sure the other users have edit permissions on the target cell. If they are not allowed to edit cell Z1 in the activeSheet which might be any sheet in the spreadsheet file, then the script won't work for them. You can either give them access, or make the script work only under particular sheets when you can give them access.
Some users sometimes have experienced issues when tried to chain with active methods directly. See reference links here and here although I can't reproduce that issue, it might be the cause in your case.
Potential Solution:
Please take care of the first issue.
Regarding the second issue, modify your code as follows:
function onEdit(e) {
const active_sheet = e.range.getSheet();
active_sheet.getRange('Z1').setValue(Math.random());
}
This is anyway the recommended way to use an onEdit trigger as you should take advantage of the event object.

Why Isn't My Spreadsheet Changing From Input Values of An Outside Source?

So I am trying to use an outside source (Zapier) to input values into my spreadsheet. These input values are then "transposed (formula wise)" into my spreadsheet to fit the cell coordinates with which they are to align.
I have the spreadsheet set to run 'onEdit' and when these incoming values arrive, it is supposed to cause the rest of the spreadsheet to change, but the function is not running.
However, if I were to edit the spreadsheet 'manually,' the onEdit function runs perfectly.
So why then would the spreadsheet not be running the function, when the outside source brings its input values?
UPDATE:
So I discovered that if I manually authorize an 'onChange' installable trigger, it will work. But if I create a copy of the same exact spreadsheet, the installable trigger will not exist in the copy. The copy needs to have the trigger without me having to do it manually. So I am trying to create a code inside of Google Script Editor that will either allow me to use the onChange function or install the onChange function in the Developer Hub. Any thoughts? Here is the code I tried but did not work:
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("My
Sheet")
var ssid = "My SpreadSheet ID";
ScriptApp.newTrigger('My Sheet)
.forSpreadsheet(ss.getId())
.onChange()
.create();
myFunction()
{
If there is an alternative for the onChange function, then I'm all ears. I just need a function that can run itself in my copies.
As a part of a collaborative effort, let me clarify the Zapier part (this answer does not concern the copy part).
Part 1. Zapier setup
Assuming you have a third-party application that you pull data from (btw, since you decided to use apps script, isn't it easier to drop the middleman like Zapier and connect to the 3P app API – if it has one, ofc – directly?), you created a Catch Hook and a POST Action.
The POST Action setup contains several fields:
URL field - this is where your /exec URL goes (WebApp is deployed via Publish->Deploy as a WebApp). After you deploy your script as a WebApp, you will get a URL that users and scripts can make requests to (it is always of this format https://script.google.com/macros/s/{yourProjectId}/exec - with some slight diff. due to access permissions). To avoid permissions issue, set the Who has access to the app option to anyone or anyone, even anonymous (otherwise, you'll have to devise auth handling).
Payload Type field is irrelevant here, but I suggest using JSON.
Data field is required if you chose the POST Action and should contain key-value pairs of data you would like to transmit via Zapier (the data will be available in parameter/parameters property of the event object).
Part 2. WebApp setup
Published WebApps should have either a doGet() or doPost() function to be able to receive and process requests (or both). Each of them accepts one special argument, which is constructed each time a request to the WebApp is made – an event object.
The event object will contain all the data that you sent from Zapier. You can then use this data to conditionally trigger different functions, pass data to handlers, etc. So, instead of relying on triggers, you can create a function that is called inside the doGet / doPost that will a) populate your target sheet with new values; b) do anything else after that, thus acting as an analogue of onEdit / onChange.
Useful links
Event object structure;
Passing event objects around;
Creating triggers on other documents;

Google App Script onFromSubmit Trigger doesn't trigger

I have a spreedsheet, with a sheet feed by a Google Form. unfortunetly, I need special features, like conditional formatting, and data added by google form are added in a new line without format.
So, I did an other sheet, with the same columns, and I had to copy paste from the first one to the second one. I'd like this copy to be automated. So I tried to do it using Google App Script. But it seems like I did something wrong with the trigger.
Here is the code :
function creerTrigger()
{
ScriptApp.newTrigger('deplacerCommande').forSpreadsheet("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").onFormSubmit().create();
}
function deplacerCommande(e)
{
var id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var feuille = SpreadsheetApp.openById(id).getSheetByName("Commande");
feuille.appendRow(e.namedValues);
}
When I run deplacerCommande() from Google App Script, the messageBox is displayed, but not when a form is submitted, so I don't think the trigger works.
Yes, I created my trigger. I did it by running the function creerTrigger() from Google App Script. I also tried deleting it, then changing the version, then recreating it, because I read it can solve the problem, but it didn't.
list of trigger
It's in French, but I'll translate the value for you :
deplacerCommande is the name of the function called by the trigger.
the second value means From the spreedsheet.
the third means sending Form
The solution was simple. The trigger triggered, but the appendRow function raised an Exception because namedValue is an object, not an arrow. using e.values instead of e.namedvalues solved the problem!

Send an e-mail if a cell value meets a given criterion

I'm working on a scoreboard automation process using Google Sheets, but I've come up with a little problem. I tried searching here but the question has been treated in a unclear way to me.
What am I trying to do is quite simple:
I want an automatic e-mail to be sent to a specific person IF cell value > X (threshold). I already know I need to use Google Apps Script for that, but I haven't found much interesting code lying around yet so I was wondering if you guys had an idea how that would work?
I tried something based on this thread with no success: How do I make a Google Sheet script send an email when a specific cell's value changes?
#Yvan1401,
You can use a script like this along with an installable trigger like onEdit or onChange to accomplish what you wish. To set up the installable trigger follow the steps below (found here):
From the script editor, choose Resources > 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 From spreadsheet.
Select and configure the type of trigger you want to create (e.g. on
Change or on Edit trigger).
Optionally, click Notifications to configure how and when you will
be contacted by email if your triggered function fails.
Click Save.
Please see comments in code for portions to change.
function SendEmail() {
var ui = SpreadsheetApp.getUi();
var file = SpreadsheetApp.getActive();
var sheet = file.getSheetByName("Sheet1"); //Change as needed
if(sheet.getRange(5,1).getValue()>10){ //change row and column in get range to match what you need
MailApp.sendEmail("xxxxxcxxx#gmail.com", "subject", "message");
}
}
function sendMail() {
if (SpreadsheetApp.getActive().getSheetByName('Scoreboard').getRange('AL2:AL1000').getValue()<2.70) return;
MailApp.sendEmail("yvan#********.com", "******** new potential candidate available ! ", "Dear ****, a new candidate with strong potential is available for due dil !", {
name: "SOURCE NAME"
});
}
Here is an example of code that works the best and is the shortest. The thing is, I want it to scan only the cells that has changed (updated) within the column in question and not the old responses (data source is a form). What do you think i should do ? Because i don't want to erase the previous response within the same column.
edit: I use an "onChange" trigger.

Contacts not being collected from "Soccer Club Homepage" tutorial

I am new to google apps scripts and I am following the tutorial at https://developers.google.com/apps-script/articles/sites_tutorial and when I run the myContact function from step 1, no contact info is populated into my spreadsheet.
I have a group created called AZ_Pilot, and I have the myContact function set up as follows:
function myContact() {
var contacts = ContactsApp.findContactGroup("AZ_Pilot").getContacts();
SpreadsheetApp.getActiveRange().setValue(contacts[0].getPrimaryEmail());
}
The script runs with no errors, but nothing is updated within the spreadsheet. It's a bit embarrassing to be stumped at step 1, but here we are.
You are using getActiveRange() which is the range which is currently under selection in the spreadsheet. By default, it is the first cell in the spreadsheet. Maybe you have a different cell selected and therefore, the email might be written to a different cell. Try keeping the first cell in focus and running the function again.
Also, you haven't mentioned whether or not there are any contacts in the group you created :)
I was adding some additional logging information, and it just started working correctly with no change to the functional code. Not sure what happened there.