I have a function that creates a form and a destination sheet for responses. I want to then reference that sheet from another function that sends out an email on form submit.
Since the create form and sheet function will be run more than once the sheet ID I need to reference will change. Trying to find ways to get it into my email function as a parameter.
function createform () {
var ss = SpreadsheetApp.create(fname);
var ssID = ss.getId();
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
ScriptApp.newTrigger('makeReport').forForm(form).onFormSubmit().create();
}
function makeReport(thispara) {
//Open Response SS
var responseSS = SpreadsheetApp.openById(thispara).getSheetByName('Sheet1');
var respRange = responseSS.getDataRange();
var respName = respRange.getValues();
}
Related
I have script to generate Google Form and set where the Destination Form Response. After set, I want to rename the Sheet Name, from default Response Sheet Name ( eg. Form Response 1), with custom Sheet Name.
function genarateForm() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('CONSUMEN DATA');
var rowNumber = (sheet.getDataRange().getNumRows())-3;
var myQuestions = sheet.getRange(5,2,rowNumber,1).getValues();
var form = FormApp.create('CUSTOMER BILL');
const formTitle = 'BILL REPORT'
form.setTitle(formTitle)
.setDescription('Fill with customer bill :')
.setAllowResponseEdits(true)
.setAcceptingResponses(true);
for(var i=0;i<rowNumber;i++){
var addItem = form.addTextItem();
addItem.setTitle(pertanyaanKu[i]);
}
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId())
// I want to set the sheet destination response with "CUSTOMER BILL"
}
In order to achieve your goal, how about the following modification?
From:
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId())
To:
form.setDestination(FormApp.DestinationType.SPREADSHEET, ss.getId());
// I added the below script.
SpreadsheetApp.flush(); // This might not be required to be used.
const formUrl = form.getEditUrl().replace("edit", "viewform");
const formSheet = ss.getSheets().find(s => s.getFormUrl() == formUrl);
if (formSheet) {
formSheet.setName("CUSTOMER BILL");
}
When this script is run, the sheet name of a sheet of the created Google Form is changed to "CUSTOMER BILL".
I'm on a project in which I get stuck just on the final step.
let me explain:
my project to filter data and move the filtered data to another spreadsheet. All work properly without issues but something happened and the issue is that I need to input dynamic data as filter and sheet name. I created 2 variables location which will determine the filter and sectionSelect which will determine the sheet name.
my goal is to send the data through the web with its tag to be filtered in the desired sheet.
FYI: the app script is bound to a gsheet.
Here is the code:
function doGet(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
return TagData(e,sheet);
}
function doPost(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
return TagData(e,sheet);
}
function TagData(e) {
var Location = e.parameter.Location; // send from app with respective tag
var sectiontSelect = e.parameter.sectiontSelect; // send from app with respective tag
sheet.append([Location, sectiontSelect])
}
function FilterOnText() {
var ss = SpreadsheetApp.getActive()
var range = ss.getDataRange();
var filter = range.getFilter() || range.createFilter()
var text = SpreadsheetApp.newFilterCriteria().whenTextContains(Location); // the location will be as per the location variable in the TagData function
filter.setColumnFilterCriteria(1, text);
}
function titleAsDate() {
const currentDate = Utilities.formatDate(new Date(), "GMT+4", "dd-MM-yyyy HH:mm:ss");
return SpreadsheetApp.create("Report of the " + currentDate);
}
function copyWithValues() {
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sourceSheet = spreadSheet.getSheetByName(sectionSelect); // fromApp variable will define which sheet the data will be copied (situated in the TagData function)
const temp_sheet = spreadSheet.insertSheet('temp_sheet');
const sourceRange = sourceSheet.getFilter().getRange();
sourceRange.copyTo(
temp_sheet.getRange('A1'),
SpreadsheetApp.CopyPasteType.PASTE_NORMAL,
false);
SpreadsheetApp.flush();
const sourceValues = temp_sheet.getDataRange().getValues();
const targetSpreadsheet = titleAsDate();
const rowCount = sourceValues.length;
const columnCount = sourceValues[0].length;
const targetSheet = targetSpreadsheet.getSheetByName('Sheet1').setName("Report"); // renamed sheet
const targetRange = targetSheet.getRange(1, 1, rowCount, columnCount);
targetRange.setValues(sourceValues);
spreadSheet.deleteSheet(temp_sheet);
}
function MoveFiles(){
var files = DriveApp.getRootFolder().getFiles();
var file = files.next();
var destination = DriveApp.getFolderById("1wan7PLhl4UFEoznmsN_BVa2y4AtFaCOr");
destination.addFile(file)
var pull = DriveApp.getRootFolder();
pull.removeFile(file);
}
function clearFilter() { // clearance of filters applied in first function
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("testo");
sheet.getFilter().remove();
}
Explanation:
Two issues:
TagData does not return anything (as Cooper pointed out)
TagData(e) has only one parameter e but you are passing two parameters TagData(e,sheet) when you call it from the doGet and doPost functions.
Not sure if this will solve all your issues, but it will solve the ones I mentioned above.
Solution:
Remove the return statements from doGet and doPost because of issue 1).
Add the sheet parameter in the TagData function.
Resulting code:
function doGet(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
TagData(e,sheet); // modified
}
function doPost(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
TagData(e,sheet); // modified
}
// added the sheet parameter
function TagData(e,sheet) {
var Location = e.parameter.Location; // send from app with respective tag
var sectiontSelect = e.parameter.sectiontSelect; // send from app with respective tag
sheet.append([Location, sectiontSelect]);
}
// rest of your code..
Or try this:
function doGet(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
var params = JSON.stringify(TagData(e,sheet)); // modified
return HtmlService.createHtmlOutput(params); // added
}
function doPost(e) {
var ss = SpreadsheetApp.openByUrl("sheetURL")
var sheet = ss.getSheetByName(Location);
ContentService.createTextOutput(JSON.stringify(e))
}
// added the sheet parameter
function TagData(e,sheet) {
var Location = e.parameter.Location; // send from app with respective tag
var sectiontSelect = e.parameter.sectiontSelect; // send from app with respective tag
sheet.append([Location, sectiontSelect]);
return { Location: Location, sectiontSelect: sectiontSelect }
}
I have the following code that opens only one tab of a spreadsheet:
const sheetName = SpreadsheetApp.getActiveSheet().getName()
const sheetID = SpreadsheetApp.getActive().getId()
const sheet = SpreadsheetApp.openById(sheetID).getSheetByName(sheetName)
I would like to take the data from this tab and create a new spreadsheet with just that data
Explanation:
I believe your goal is to transfer data between a source spreadsheet file (the one you have the script bound to) to a target spreadsheet by its id.
Solution:
In the comments you can find expalanation on what you need to adjust:
function myFunction() {
const source_ss = SpreadsheetApp.getActive();
const target_ss = SpreadsheetApp.openById("id"); // put the id of the target spreadsheet
const source_sheet = source_ss.getSheetByName('Sheet1'); // put the name of the source sheet
const target_sheet = target_ss.getSheetByName('Sheet1'); // put the name of the target sheet
const data = source_sheet.getDataRange().getValues(); // take the data of the source sheet
target_sheet.getRange(1,1,data.length,data[0].length).setValues(data); // paste the data to the target sheet
}
If your goal is to create the target spreadsheet on the fly, then use this code:
function myFunction() {
const source_ss = SpreadsheetApp.getActive();
const target_ss = SpreadsheetApp.create("target"); // create a target spreadsheet
const source_sheet = source_ss.getSheetByName('Sheet1'); // put the name of the source sheet
const target_sheet = target_ss.getSheetByName('Sheet1'); // only this sheet is available in the target sheet
const data = source_sheet.getDataRange().getValues(); // take the data of the source sheet
target_sheet.getRange(1,1,data.length,data[0].length).setValues(data); // paste the data to the target sheet
}
References:
openById(id):
Opens the spreadsheet with the given ID. A spreadsheet ID can be
extracted from its URL. For example, the spreadsheet ID in the URL
https://docs.google.com/spreadsheets/d/abc1234567/edit#gid=0 is
"abc1234567".
Alternative:
You can also use copyTo() to copy an entire sheet to another spreadsheet:
function copyTab() {
var source = SpreadsheetApp.getActiveSpreadsheet();
var sheet = source.getActiveSheet();
var destination = SpreadsheetApp.create("New Sheet");
sheet.copyTo(destination);
// optional, this deletes the initial Sheet1 in new spreadsheet
var sheet1 = destination.getSheetByName("Sheet1");
destination.deleteSheet(sheet1);
}
References:
copyTo() Spreadsheet
I used Google's Quickstart: Add-on for Google Forms to enable e-mail notifications for respondents of my form. I also added a few lines to send unique code to each respondent and I would like to have these codes stored in responses sheet.
The code below sends the message with code, but it doesn't store code in responses sheet.
function sendRespondentNotification(response) {
var form = FormApp.getActiveForm();
var settings = PropertiesService.getDocumentProperties();
var emailId = settings.getProperty('respondentEmailItemId');
var emailItem = form.getItemById(parseInt(emailId));
var respondentEmail = response.getResponseForItem(emailItem)
.getResponse();
if (respondentEmail) {
var template =
HtmlService.createTemplateFromFile('RespondentNotification');
template.paragraphs = settings.getProperty('responseText').split('\n');
template.kod = (new Date).getTime().toString(16).substring(5);
template.notice = NOTICE;
var message = template.evaluate();
MailApp.sendEmail(respondentEmail,
settings.getProperty('responseSubject'),
message.getContent(), {
name: form.getTitle(),
htmlBody: message.getContent()
});
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var LastRow = sheet.getLastRow();
var cell = sheet.getRange(LastRow, 5);
cell.setValue(template.kod);
}
}
you could use onFormSubmit to generate the unique id and include it in the email for a webapp to use. that id could be something simple like the row number of the response (not in e.values thou) or generate on the fly and write to the responses spreadsheet as a new column. adding columns does not break the form.
In class Spreadsheet there is getFormUrl() which returns the url for the form attached to the spreadsheet, null if there is no form.
But now that you can have a form attached to each sheet, how do you get the ID or Url of the form attached to a given sheet?
You can call getFormUrl on the Spreadsheet, and on each Sheet of the Spreadsheet:
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheets = ss.getSheets();
for (let sheet of sheets) {
let sheetName = sheet.getName();
let formUrl = sheet.getFormUrl();
Logger.log("formUrl1 %s %s", sheetName, formUrl);
if (formUrl) {
Logger.log("formid1 %s", FormApp.openByUrl(formUrl).getId());
}
}
let formUrl = ss.getFormUrl();
Logger.log("formUrl2 %s", formUrl);
if (formUrl) {
Logger.log("formid2 %s", FormApp.openByUrl(formUrl).getId());
}
In my case, the spreadsheet was created by a form (in the Answers section, the green spreadsheet icon), and formUrl2 refers to this form. The formUrl1 of one of the sheets relates also to this form, because this sheet contains the answers of the form. Another sheet has the url of a second Form, because I connected the second form to the same spreadsheet. A third sheet has null as formUrl, because it is not related to a form.
I give an example for you of my script.
Maybe it can help you.
example :
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Sheet1");
var data = ss.getDataRange().getValues(); // Data for pre-fill
var formUrl = ss.getFormUrl(); // Use form attached to sheet
var form = FormApp.openByUrl(formUrl);
var items = form.getItems();
I just took the URL provided by the getFormUrl and assigned letters 49 through 93 to a string. That should provide the Form ID.
var ss=SpreadsheetApp.getActiveSpreadsheet();
var fOrmUrl=ss.getFormUrl();
var sTring="";
for (var i=49; i<93; i++)
{
sTring=sTring + fOrmUrl[i];
}
I've noticed that the sheet.getFormURL() method does not always return the same URL that form.getPublishedUrl() returns. Both URLs are valid, though. To get around the problem, I'm opening the sheet's formUrl and then checking and comparing that form's ID:
var form = FormApp.getActiveForm();
var formId = form.getId();
const matches = spreadSheet.getSheets().filter(function (sheet) {
var sheetFormUrl = sheet.getFormUrl();
if (sheetFormUrl){
return FormApp.openByUrl(sheetFormUrl).getId() === formId;
}
});
const sheet = matches[0]