Copy Google Form Input to two different google Sheet tabs - javascript

I have a Google form the information that is submitted is from students and faculty. The form has a trigger to run the function every time information is submitted. I want to copy all the submitted information to different tabs. One with staff members and one with student info. I can copy all the information into one tab, but when I try to separate it I am not able to get the results I need.
Any tips or guidance would be much appreciated.
function copyRowsWithCopyto(){
var spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = spreadSheet.getSheetByName('Entrega_Dispositivos');
var sourceRange = sourceSheet.getDataRange();
var studentSheet = spreadSheet.getSheetByName('Student_Copy');
var staffSheet = spreadSheet.getSheetByName('Staff_copy');
var lr = sourceSheet.getLastRow();
var data = sourceSheet.getRange("A2:AS" + lr).getValues();
for(var i = 0;i<data.length;i++){
var rowData = data[i];
var status = rowData[2];
if(status == "Student" && status != "Staff"){
sourceRange.copyTo(studentSheet.getRange(1, 1));
} else {
sourceRange.copyTo(staffSheet.getRange(1, 1));
}
}
}

function onFormSubmit(e) {
const itemResponses = e.response.getItemResponses();
const status = itemResponses[1].getResponse();
const ss = SpreadsheetApp.getActiveSpreadsheet();
if (status === 'Student') {
ss.getSheetByName('Student_Copy').appendRow(e.values);
}
else {
ss.getSheetByName('Staff_copy').appendRow(e.values);
}
}

You can simply put 2 queries, one in each tab, to separate student and staff, without any scripts !

Related

How to add if and date in google script

I am a beginner with code script. Can you help me with my function please?
I have bot and he send data to google sheets, he send name, phone, date and method of communication. I need that google sheets write in column C date when was get the data from phone. I only now get the date, but in addition i need if - else. "If the column C is not empty send their date since last request", in addition i think I need to add method forEach and method so that the data is updated automatically when phone is received. For this I think need trigger "doGet(e)" from google documentation
(spread sheet image)
Data get from webhook
Here is my code:
function getDate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var numbers = ss.getActiveSheet().getRange("B2:B1000")
let dateGoogle = new Date();
var rr = ss.getActiveSheet().getRange("C1:C1000").setValue(dateGoogle);
}
Just in case. If you're able to run the function getDate() and all you need is to make it to fill cells in C column only for rows that have filled cells in B column it can be done this way:
function getDate() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var range = ss.getActiveSheet().getData();
var data = range.getValues();
let dateGoogle = new Date();
data.forEach(x => x[2] = (x[2] == '' && x[1] != '') ? dateGoogle : x[2]);
range.setValues(data);
}
If you ask how to run the function getData() via doGet() I have no answer.
Using a doPost()
function doPost(e) {
Logger.log(e.postData.contents);
Logger.log(e.postData.type);
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
let data = JSON.parse(e.postData.contents);
let row = [];
['name','phone','date','method'].forEach(k => row.push(data[k]));
Logger.log(JSON.stringify(row))
sh.appendRow(row);
}
Below function Simulate what I imagine the bot can do to send data. This one is sending the data as JSON.
function sendData(obj) {
const url = ScriptApp.getService().getUrl();
const params={"contentType":"application/json","payload":JSON.stringify(obj),"muteHttpExceptions":true,"method":"post","headers": {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}};
UrlFetchApp.fetch(url,params);
}
function saveMyData() {
sendData({name:"name",phone:"phone1",date:"date1",method:"post"});
}
You will have to Deploy the doPost(e) as a webapp.

How to set up sending automatic reminder emails linked to a questionnaire on Google Forms?

I have made a questionnaire using Google Forms. I have a set of emails (e.g. respondent1#example.com, respondent2#example.com, ...) as targets to send the questionnaire to. I receive the respondents' email address if they submit their responses. The responses can be saved in a google spreadsheet.
I would like to send a reminder email only to those who do not respond until a day after they received their email.
I am using the following code in the script.google.com that can send the email and works with a customized trigger in the G Suit Developer Hub. But it just sends a reminder email to all the emails listed in the following code. How can I add a condition to it that satisfies what I described?
function sendFormEmail() {
var emailAddress = "respondent1#example.com, respondent2#example.com";
var htmlMessage = HtmlService.createHtmlOutputFromFile("Reminder_email.html").getContent();
var subject = "Participation reminder";
var message = "Hi, please be reminded to submit your response";
MailApp.sendEmail(emailAddress, subject, message, {
htmlBody: htmlMessage
});
}
I managed to do it using two spreadsheets, one including the email of all participants, the other for the participants who have participated (extracted from the automatic spreadsheet made by Google Form when someone submits a response)
The function to send the reminder email is as follows. It can be triggered automatically using Google triggers embedded in the Google scripts.
Here is the code for the function I wrote.
function sendRemEmail()
// Load all the emails from the spreadsheet including all emails in the first column
{
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/...').getActiveSheet();
var All_lr = ss.getLastRow();
var Alladdresses = [];
for (var i = 2; i<=All_lr;i++){
var emailAddress = ss.getRange(i,1).getValue();
Alladdresses.push(emailAddress);
}
// Load emails from the spreadsheet linked to the questionnaire
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/...').getActiveSheet();
var sub_lr = ss.getLastRow();
var All_submitted_emails = [];
for (var i = 2; i<=sub_lr;i++){
var emailAddress = ss.getRange(i,2).getValue();
All_submitted_emails.push(emailAddress)
}
var rem_email_list = [];
for (var i = 0; i<=All_lr-1;i++){
if (All_submitted_emails.indexOf(Alladdresses[i])===-1){
rem_email_list.push(Alladdresses[i]);
}
}
var rem_email_list = rem_email_list.filter(function (el) {
return el != null;
});
Logger.log(rem_email_list);
var htmlMessage = HtmlService.createHtmlOutputFromFile("Reminder_email.html").getContent();
var subject = "Reminder";
var message = "Hi, please be reminded to submit your response";
for (var i = 0; i<rem_email_list.length;i++){
var emailAddress = rem_email_list[i];
MailApp.sendEmail(emailAddress, subject, message, {htmlBody: htmlMessage, from:'rzm#example.com', name: 'X Y',replyTo:'rzm#example.com'});
}
}
I have used a customized email (htmlMessage) written in HTML which is in the same project.

Save items to different childs in firebase

How can I save data to different childs in a firebase?
I push items to a firebase using onclick function and if/else statements for creating different categories.
Example
Button1 click -> push data from inputform to child1 in firebase,
Button2 click -> push data from inputform to child2 in firebase....
Problem
The item is pushed to one child only (e.g. ref0).
Everytime I push further items into the firebase, there appended to the ref0 child and not assigned to a new child (e.g. ref1).
Unfortunately I canĀ“t find specific information for solving this issue.
Would be great if you can support me.
Check my Code for more specific information.
//create firebase reference
var dbRef = new Firebase('https://firebaseurl.firebaseio.com/');
var ref0 = dbRef.child('ref0');
var ref1 = dbRef.child('ref1');
var ref2 = dbRef.child('ref2');
var ref3 = dbRef.child('ref3');
var showAllRefs = ref0, ref1, ref2, ref3;
//load all contacts (limited to last 5 items)
showAllRefs.limitToLast(5).on("child_added", function(snap) {
snap.forEach(function(childSnapshot) {
var key = childSnapshot.key();
var childData = childSnapshot.val();
//create divs from database-elements
var card = document.createElement('div');
card.setAttribute('class', 'linkprev');
$('#content').prepend($(card));
var cardtitle = document.createElement('div');
cardtitle.setAttribute('class', 'cardtitle');
cardtitle.innerHTML = childData;
card.appendChild(cardtitle);
});
$(document).ready(function(){
document.guteUrls.execute('linkprev');
});
});
//save contact
//save in database contacts
var elements = $('.f');
//console.log(elements);
//save items to firebase(childs)
var buttonPressed = function( event ) {
event.preventDefault();
//url validation from inputfield using Regex
var valpattern = new RegExp('^(http|https)://'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
var valselect = document.getElementById('url');
var val = valpattern.test(valselect.value);
//save in database to different childs on buttonclick
if(val && document.querySelector(".f1")){ref0.push({name: document.querySelector('#url').value})
contactForm.reset();}
else if(val && document.querySelector(".g1")){ref1.push({name: document.querySelector('#url').value})
contactForm.reset();}
else if(val && document.querySelector(".h1")){ref2.push({name: document.querySelector('#url').value})
contactForm.reset();}
else if(val && document.querySelector(".i1")){ref3.push({name: document.querySelector('#url').value})
contactForm.reset();}
else {
alert('Oops');}
};
for (var i = 0; i < elements.length; i++) {elements[i].addEventListener("click", buttonPressed, false);}
Thanks in advance
Ben

Create new spreadsheet with selected data from another sheet depending on the activeUser

first of all, this is the case:
I do have a masterdata sheet with lots of employee details (database). Column G contains email-adresses. I try to find a way to separate/select the lines for which the email-address matches the active user email-address. Without any opportunity for the user to change anything.
I tried different approaches with Query and IMPORTRANGE within the spreadsheet (e.g. =QUERY(IMPORTRANGE("101kbFw_DQGjmxhrw7BHK5-SM5IShkddre7GdqEhc2-U";"Data!A1:AC100"); "Select Col1,Col2,Col3,Col4 where Col7='Pascal Richter'"). But in this case the user would be able to change the name.
So I tried to build a webapp with the following functionalities:
the script identifies onOpen the activeUser
Button "send me data" starts the function createSSwithselectedData ()
the function createSSwithselectedData () creates a new spreadsheet
the function createSSwithselectedData () looks up the lines where the activeUser and the email in column g matches
the function createSSwithselectedData () transfers the identified data to the new spreadsheet
the activeUser gets an email with a link to the new spreadsheet
This is a dummy of the masterdata sheet.
Help is highly appreciated :)
// Log the email address of the active user
var email = Session.getActiveUser().getEmail();
Logger.log(email);
var DatabaseID = "101kbFw_DQGjmxhrw7BHK5-SM5IShkddre7GdqEhc2-U";
var Data = SpreadsheetApp.openById("101kbFw_DQGjmxhrw7BHK5-SM5IShkddre7GdqEhc2-U").getDataRange().getValues();
Logger.log(Data);
function doGet() {
var app = UiApp.createApplication();
// create a button and give it a click handler
var button = app.createButton("Send me data!").setId("button");
button.addClickHandler(app.createServerHandler("createSSwithselectedData"));
app.add(button);
return app;
}
function createSSwithselectedData(email) {
var app = UiApp.getActiveApplication();
app.getElementById("button").setText("Data is on the way");
return app;
var SheetTemplate = "1Z-ECGaRXaO8mEjTCx74z4sXOc_B7ZU81qfhtVJ3TAic";
var SheetName = "Jobgroup validation - ";
var newSheetName = SheetName + email ;
var folderId = "0B45D8-yA6A-HTWF1MjNhZW1VaXM"
var destination = DriveApp.getFolderById(folderId);
var copyId = DriveApp.getFileById(SheetTemplate).makeCopy(newSheetName, destination).getId();
var copySheet = SpreadsheetApp.openById(copyId);
// this is a new array to collect data
var target = new Array();
for(n=0;n<data.length;++n){ // iterate in the array, row by row
if (data[n][7]==email){ ; // if condition is true copy the whole row to target
target.push(data[n]); // copy the whole row
} //if
} //for
copySheet.getRange(1,10,target.length,target[0].length).setValues();
// Save and close the temporary document
copySheet.saveAndClose();
var url = copySheet.getUrl(); //DriveApp.getFileById(newFileId);
var link = "" + newSheetName + "";
var subject = "Jobgroup validation - " + email;
var body = "<p>You requested your team details. Please check the content.</p></br> " + link;
MailApp.sendEmail({to: email, subject: subject, htmlBody: body, name: alias, noReply: true});
}

How to Make a list on Google SpreadSheet of all files in a Google Drive folder

I have a Folder With more than 2000 Files.. And i Need to make a List of all these files on google spreadsheet.. I Found online some Scripts.. but they're not completely working.
When i hit "RUN" i just get a list of 250 Files.
Reading on Google Developers page i found some things about enabling Google Drive advanced services (and i did it)..
And i think i could solve this problem using something named "tokens"??
I don't know.. i'm not a programmer, and i barely know english..
i Tried editing this script making a fusion of what i found online.. But anything works.. i just get errors that i can't even understand..
So.. is there someone able to fix it?
function listFilesInFolder() {
var folder = DocsList.getFolder("Film");
var contents = folder.getFiles();
var file;
var data;
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.appendRow(["Nome", "Data", "Dimensione"]);
for (var i = 0; i < contents.length; i++) {
file = contents[i];
if (file.getFileType() == "SPREADSHEET") {
continue;
}
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
];
sheet.appendRow(data);
}
};
This Script works for at least 2200 Files :)
function listFilesInFolder(id) {
var folder = DriveApp.getFolderById('MyFolderID');
var contents = folder.getFiles();
var file;
var name;
var sheet = SpreadsheetApp.getActiveSheet();
var date;
var size;
sheet.clear();
sheet.appendRow(["Nome", "Data", "Dimensione"]);
while(contents.hasNext()) {
file = contents.next();
name = file.getName();
date = file.getDateCreated()
size = file.getSize()
data = [name, date, size]
sheet.appendRow(data);
}
};
The answer above appends a row in every iteration wich is particularly slow and there is a chance you will exceed the maximum execution time (see best practices)) so here is a version that uses an array to collect data and writes the array using a single setValues() .
The other issue is that it gets all the files in your drive, not in the folder you chose...
so below is a version that gets all files that are not Google documents, ie it counts only files that take space (images, pdf...) with a maximum of 4000 files.
full code below :
function listFilesInFolder() {
var folder = DocsList.getFolderById('0B3qSFd3iikE3MS0yMzU4YjQ4NC04NjQxLTQyYmEtYTExNC1lMWVhNTZiMjlhMmI');
var file;
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
var data = [];
data.push(["Name", "Data", "Size", "url"]);
var filesresult = folder.getFilesByTypeForPaging(DocsList.FileType.OTHER, 4000);
var files = filesresult.getFiles();
Logger.log(files.length);
for (var i in files) {
file = files[i];
data.push([
file.getName(),
file.getDateCreated(),
file.getSize(),
file.getUrl()
]);
}
sheet.getRange(1,1,data.length,data[0].length).setValues(data);
}
Paging is what you're looking for. When you have a large number of results (like 2000 files), you generally divide the request into 'pages', either to show the user page by page or in this case, to stay within the API limits.
The 'token' isn't a big deal.. it's just how your script remembers the page number while it's dealing with the current page.
So there's information about this here: https://developers.google.com/apps-script/reference/docs-list/files-result
The script at the top of the page is quite apt to your situation. Your script becomes something like...
function listFilesInFolder() {
var folder = DocsList.getFolder("Film");
//var contents = folder.getFiles();
var file;
//var data;
var sheet = SpreadsheetApp.getActiveSheet();
sheet.clear();
sheet.appendRow(["Nome", "Data", "Dimensione"]);
var pageSize = 200;
var files = null;
var token = null; // use a null token for the first lookup
do {
var result = DocsList.getAllFilesForPaging(pageSize, token);
files = result.getFiles();
token = result.getToken();
for (var i = 0; i < files.length; i++) {
//Logger.log(files[i].getName());
file = files[i];
if (file.getFileType() == "SPREADSHEET") {
continue;
}
data = [
file.getName(),
file.getDateCreated(),
file.getSize(),
];
sheet.appendRow(data);
}
} while (files.length >= pageSize);
};
I'm not promising this will work.. but I'm sure you can sort it out. Basically the "while loop" on that page replaces the "for loop" from your script. The loop on that page just calls Logger.log(), so you swap that with the sheet.appendRow(data)
I've taken the script suggested by Jonathan Livingston and made some edits.
Now it:
can take a name of a sheet with future report. It can make a new sheet if it doesn't exist,
gives more parameters, including list of editors (e-mails)
Here's the code:
function TESTlistFilesInFolder() {
listFilesInFolder("0B0pifCWzjn-ib0ZWT2x1ekNOWAY", "Files Report");
// ^^^^^^^^ folder ID ^^^^^^^^^ ^sheet Name^
}
// original script: http://stackoverflow.com/a/25730522/5372400
function listFilesInFolder(id, sheetName) {
sheetName = sheetName || id;
var sheet = createSheetIfNotExists(sheetName);
var folder = DriveApp.getFolderById(id);
var contents = folder.getFiles();
sheet.clear();
sheet.appendRow(["Name", "CreatedDate", "Last Updated", "Id", "Url", "Editors", "Viewers", "Owner", "Access", "Permission", "Size"]);
var data = [];
var file;
var info = [];
while(contents.hasNext()) {
data = [];
file = contents.next();
data.push(file.getName());
data.push(file.getDateCreated());
data.push(file.getLastUpdated());
data.push(file.getId());
data.push(file.getUrl());
// convert to string: http://www.w3schools.com/jsref/jsref_join.asp
data.push(getEmails(file.getEditors()).join());
data.push(getEmails(file.getViewers()).join());
data.push(getEmails(file.getOwner()).join());
data.push(file.getSharingAccess());
data.push(file.getSharingPermission());
data.push(file.getSize());
info.push(data);
}
var rows = info.length;
var cols = info[0].length;
var range = sheet.getRange(2,1,rows,cols);
range.setValues(info);
};
function createSheetIfNotExists(name) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
try {ss.setActiveSheet(ss.getSheetByName(name));}
catch (e) {ss.insertSheet(name);}
var sheet = ss.getSheetByName(name);
return sheet;
}
// users: https://developers.google.com/apps-script/reference/base/user
function getEmails(users) {
var emails = [];
var user;
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray(users)) { users = [users]; }
for (var i = 0; i < users.length; i++) {
user = users[i];
emails.push(user.getEmail());
}
return emails;
}

Categories

Resources