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.
Related
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
So I have a Google sheet where, when a user enters a number of an item, it will output a description and price. I actually have 50 sheets (one for each state in the US) that are all almost exactly the same, but put out slightly different prices because state taxes vary from state to state.
I used onEdit() to have my sheet work and it was working fine until I changed where the source for information came from. Originally in my sheet, I had another page with all the item information so that a simple Vlookup could do most of the work except calculate the item's price (this is what my code was doing, using the info page that was in the sheet to calculate a price).
However, when an edit needs to be made to an item, I want to make it so that we only have to update one "master" sheet, and make a call by openByUrl(...) instead of going to all 50 sheets and copy pasting the information. I tried implementing this in a sheet, and now it doesn't work when I edit, but it does work when I manually go into script editor and press run. What gives?
EDIT: Here's the code requested.
function onEdit(d) {
itemPriceSetup();
}
// Runs the actual program.
function itemPriceSetup() {
// Grabs and stores the sheet where a customer places an item number and where the code will output the price to.
var orderSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Item Sale Doc");
var orderSheetArray = orderSheet.getSheetValues(1, 1, 34, 8);
// Grabs and stores the sheet that has the information on the item.
//***var infoSheet = SpreadsheetApp.openByUrl('link to info');
var infoSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheet with info");
var infoSheetArray = infoSheet.getSheetValues(1, 1, infoSheet.getLastRow(), 10);
So the code with the three asterisks is what I want to use, but causes my the program to not work - that is, it onEdit() won't run (I have it commented out so the code will run - the line below it is the one I'm trying to replace). If I were to go through the debugger with the line un-commented, it actually works.
So I figured it out, but it's a bit strange. I didn't realize triggers for a script are found under resources, so I made put one straight in my script (I guess?). Either way, use the link and go to "Managing triggers manually" to read on how to do it.
https://developers.google.com/apps-script/guides/triggers/installable
I had the same problem onEdit(e) wasn't working. After trying out many different things disabling the new Apps Script V8 engine worked for me. To disable go to Script-menu Select Run and click disable the engine
Dissabling new Apps Script V8 engine
I hope this answer will helps many. I appreciate all of the help that I've received on StackOverflow.Thank you
I have a spreadsheet with different sheets in Google sheet, 3 users can edit each one a sheet (protections are set, each user can edit only one sheet). They all can execute a google script function that writes what they edited in a summary sheet. I don't want anyone to be abble to edit the summary sheet, so I set myself as the only available editor.
So my problem is to authorize the 3 users, only through the google script function, to write in the summary sheet. I tried to use the following function :
var unprotected = summarySheet.getRange('G3:G10');
protection.setUnprotectedRanges([unprotected]);
but since the users are not allowed to edit the summary sheet, and since the function is run with the active user, so they can't give themselves the right to unprotect a range in the summary sheet... Do you know how to workaround this problem?
Thanks a lot!
I see two script-based choices, one easy and one quite hard, and one sheet-based choice, that is easiest:
Easy:
You run the "summarize" script instead of them or, you set the summarize script run on a trigger out of your account. Then you actually leave protections alone. You could set the summarize script to run on open with error catching if the user doesn't have the necessary authority to unprotect the summary sheet and/or write to the summary sheet.
Hard:
When they run the "summarize" script it calls a published standalone script that has been given the authorization to make the necessary protection changes. I'll be honest, I wouldn't be able to code this but have seen/heard of similar implementations.
Easiest:
Finally, I want to make sure you've considered having the summary sheet itself contain the necessary formulas, parsing, etc. to summarize data from the other sheets without any need of scripts for this aspect of the sheet. The sheet could call custom functions as needed if the parsing or other summarization functionality is beyond built-in functions' capabilities. The sheet could stay fully protected and update itself in real time as users enter data (no need for users to trigger the summary creation, unless spreadsheet settings have auto-recalculate turned off).
Edited to add: put in A1 of Summary sheet something like:
=summarize()
And have that custom function return a 2-dimensional array of the summarized data.
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.
I have created a form that pushes data to a Google Spreadsheet. The data is latitude, longitude, location, and other identifying data. The spreadsheet is then published as a .CSV file and imported into ARC GIS to be displayed on an interactive map. It works exactly as I wanted and I set it to republish after each change.
The problem is that when the spreadsheet has rows appended by the script, it is not seeing it as a change and republishing. In order to get the updated data imported to the map, I need to go in and manually republish. Is there anyway through the Google Apps Script that I could make a few lines of code to force a republish? I could then add that to the "on form submit" script I have or another time based one that already runs at 3 am everyday.
I have looked through the Google Apps Script documents and not found anything. When searching for help on the web, the overwhelming majority of responses are for how to publish your script as a template for other.
My testing sheet was republished after the following function was executed by either a menu entry or a time-based trigger.
function ChangeIt() {
var sheet = SpreadsheetApp.getActiveSpreadsheet()
var t = new Date()
var x = 'upd: ' + t
var range = sheet.getRange('a3')
range.setValue(x)
}
If I were in your shoes, I'd add an extra column to the end of the sheet with some benign constant data that a script can change without affecting the systems consuming the data. If an extra column isn't an option, try modifying my sample to read in a current value, change it, and immediately change it back.
Also, I'd see if the spreadsheet onEdit() trigger fires when the form submit adds a new row. If so, tie your GAS function to it to force the republish. If not, setup a timed trigger to execute the GAS function.
A quick workaround for this issue that doesn't require scripting is to simply make an array copy of the data.
For example, I made a new tab and in A1 put this: =ArrayFormula('Form Responses 1'!A1:Z1000)
While the main Form responses tab will insert rows and not play nice with formulas this new tab stay nice and constant and updates automatically when new data is added.