SpreadsheetApp / FormApp - Changelog - javascript

I have a script that records a log of all changes in a spreadsheet:
function onEdit() {
var timestamp = new Date();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cell = sheet.getActiveCell();
var user = Session.getActiveUser();
var columnLabel = sheet.getRange(1, cell.getColumn()).getValue();
var changelogSheet = ss.getSheetByName("Changelog");
changelogSheet.appendRow([timestamp, cell.getA1Notation(), columnLabel, cell.getValue(), user.getEmail()]);
}
This codes beautifully creates a row of data in "Changelog" sheet every time there is an edit on "Sheet1". It tells you the date and time, the cell where it was edited, the contents of edit and user who edited it.
My issue is that "Sheet1" is linked to a Google Form that allows users to edit their responses. When users indeed edit their responses on Google Forms, the edit is not registered on my script and there is no log for it.
I presume my script only logs physical edits on the sheet itself.
Is there a way (perhaps using FormApp) to do a similar code that logs every edit on a Google Form?
I really appreciate your help.

You should create a new onFormSubmit trigger that will include similar logic and create a new row in the Google Sheet when a form response is submitted.

Related

manipulate the table locally, i.e. read the table into memory, process and then write to server

I have a script that steps through a sheet, then updates the sheet content and adds calendar items. I noticed that the execution takes up to 3 minutes and I suspect that the server calls are the reason. This is how I access the data today.
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses");
var ss = SpreadsheetApp.getActiveSpreadsheet();
var startRow = 2; // First row of data to process
Now I wanted to make it better and manipulate the table locally, i.e. read the table into memory, process and then write to server in one go. I am sure there are plenty similar issues on SO for google apps script, if I only could get a good search term. "async bulk request" did not give me good hits on SO. Any hints on available issues or how to search for them?
Then I can start with selfstudy.
This particular best practice is described in Google's documentation here
According to the docs the correct way to read data from a spreadsheet, manipulate it, and then save it again is as follows:
function readAndWriteInBulk() {
// read all the data in the active sheet at once with getValues()
const sheet = SpreadsheetApp.getActiveSheet();
const range = sheet.getDataRange();
const data = range.getValues();
// manipulate the data as you like
for (const row of data) {
// do something to a row
Logger.log(row);
}
// paste the data at once in a new sheet with setValues()
const newSheet = SpreadsheetApp.insertSheet();
const pasteRange = newSheet.getRange(1, 1, data.length, data[0].length);
pasteRange.setValues(data);
}
References:
getValues()
setValues()

Auto sync data from firebase to google sheets

Every time a change is made in my RealtimeDB, I need to get those data to my Google Sheet without pressing any button. How to achieve this?
PS. The following code does exactly what I mentioned but not automatically
function getData() {
var firebaseUrl = "https://databse.firebaseio.com/Items";
var base = FirebaseApp.getDatabaseByUrl(firebaseUrl);
var data = base.getData();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
var num = 2;
range = sheet.getRange("A"+num+":D"+num+"");
var range2 = sheet.getRange("A2:D");
range2.clearContent();
for(var i in data) {
var values = [
[ data[i].itemname, data[i].itembarcode, data[i].itemprice]
];
range.setValues(values);
num += 1;
range = ss.getRange("A"+num+":D"+num+"");
}
}
To automatically update the sheet when the database changes, you have two options:
Periodically refresh the sheet with the database contents. You can accomplish this by running your getData function on a trigger.
Listen to realtime updates from the database. While Firebase has this option, it isn't available in the FirebaseApp library.
If you want to push updates to the sheet as they happen, you'll have to push them into your sheet from an environment that does support listening for realtime updates. Doug Stevenson wrote a great example of this on Copying data from Firebase Realtime Database to a Google Sheet in real time via Cloud Functions.

How to detect the change when my google sheet is updated and send an Email

I have been trying to send an email when my sheet gets new values, The sheet is getting values automatically, and email needs to be sent to a specific Email address, and it needs to be sent to every new entry, so google integrated "Notify on change is out of the question".
Here is my scenario:
my source sheet: "Leads"// name of the sheet
my target sheet: "Closer"//name of the sheet
when a new row is inserted into the Leads sheet Its values automatically get inserted into the Closer sheet in the end. So for each new values inserted in the Leads, Closer gets a new row.
I have designed a script of my own for that but it sends me too many emails, what I want my script to do is when a new row is inserted send the email, whether that is to self or any email, I know how to send email I am just getting a lot of problems, with getting the change functionality in my script.
Here is what I have done so far:
function sendNotification() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Leads");
var mycell = sheet.getRange("A:A");
var cellcol = mycell.getColumn();
var cellrow = mycell.getRow();
var recipients = "someone#gmail.com";
var subject = "Notification for sheet updation "+ss.getName();
var body = ss.getName() + "has been updated. Visit " + ss.getUrl() + " to view the changes.";
if (mycell == 1)
{
MailApp.sendEmail(recipients, subject, body);
}}
This function works, but it sends 5,6 emails for each row submitted, I have tried many things but I cannot figure out what is the problem with this code.I just want my code to send one email for each row inserted, I would really appreciate some help with this script, Thank you.

How to take rows of data in Google Spreadsheet from one sheet, and pre-populate another sheet

So, I've been trying to start a hobby/business venture and I started sitting down with Google Spreadsheets to document all of my raw materials/stock and how much each "unit "costs to use a in a recipe.
INGREDIENTS Sheet (main datasource)
The ingredients page lists all my stock, and is the main datasource for creating new recipes, and a cost-analysis.
The recipe sheet should be dynamically populated, and be able to add more rows
I just wanted to be able to populate the ingredients sheet, then simply create new sheet for new recipes, so I can then keep track of how much inventory I have, and how much a new batch will cost.
So, to simplify my questions:
**1. How can I click on a button and add a new "row" with ingredients populated in the columns?
How can I populate each recipe field with a drop-down populated by the ingredients data?**
I think this is enough to get you started. You need to click on the image and there is a drop down to assign a script. Assign the script addNew. Then open the script editor and create the function like below.
function addNew() {
var sheet = SpreadsheetApp.getActiveSheet();
var lastRow = sheet.getLastRow() + 1;
var ingredientCol = 3;
//you will want to pull these values from your other sheet
//check here for documentation:
//https://developers.google.com/apps-script/reference/spreadsheet/data-validation-builder
var ingredients = ['pepper', 'salt', 'sugar'];
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(ingredients, true);
sheet.getRange(lastRow, ingredientCol).setDataValidation(rule);
}
I shared the document I was testing. Just open the script editor to see the code.
https://docs.google.com/spreadsheets/d/1EowRjZeRxIy18ZyMekehc976AlTcx4tmfWeEDis79hc/edit?usp=sharing

creating account by data from spreadsheet - google apps

I am working on a simple script that creates an account in the control panel of a domain - for example Gmail - and I was looking for a function in the Google apps script that creates an account automatically on inserting data to a spreadsheet
I searched the internet and I did find this though : https://developers.google.com/apps-script/class_usermanager
and the method I am using is : var user = UserManager.createUser("john.smith", "John", "Smith", "password
My question is, how can I insert the parameters from the spreadsheet that I have.
Sorry if this sounds a bit stupid I'm just new to Google apps script.
To read from the spreadsheet, you would use the SpreadsheetApp.
An example of reading a set of rows. (Let's say all rows).
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
.getValues() returns a 2D array. So you would access it by data[rowNum][colNum]. Let's say you want to add every row as a new user, you could do
for (var i in data) {
UserManager.createUser(data[i][0], data[i][1], data[i][2], data[i][3]);
}
How would you run said script? You could put all of it inside some function (function addAllUsers()) and then run it from the run menu in the Script Editor.

Categories