I would like to create a MCQ from an existing spreadsheet that has this type of data :
Question Choice 1 (correct answer) Choice 2 Choice 3 Choice 4
Question 1 a b c d
Question 2 d a b c
Question 3 b a b c
Thank you for your answer Chris, but this code :
function createForm(){
var form = FormApp.create('New Form');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2, 1, sheet.getLastRow());
var values = range.getValues();
for (var i = 0; i < values.length; i++) {
form.addMultipleChoiceItem()
.setTitle(values[i][1])
.setChoiceValues([values[i][2],values[i][3],values[i][4]]); //Make another loop here if your Answers counts are different
}
}
displays unfilled questions, something like this :
Form1
But what I would like to create should look like this at the end :
Form2
https://developers.google.com/apps-script/reference/forms/
var form = FormApp.create('New Form');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2, 1, sheet.getLastRow());
var values = range.getValues();
for (var i = 0; i < values.length; i++) {
form.addMultipleChoiceItem()
.setTitle(values[i][1])
.setChoiceValues([values[i][2],values[i][3],values[i][4]]); //Make another loop here if your Answers counts are different
}
Here what i have came out as a soultion :
function createForm(){
var form = FormApp.create('New Form');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange(2, 1, sheet.getLastRow());
var values = range.getValues();
var ansRange1 = sheet.getRange(2, 2, sheet.getLastRow());
var ansValues1 = ansRange1.getValues();
var ansRange2 = sheet.getRange(2, 3, sheet.getLastRow());
var ansValues2 = ansRange2.getValues();
var ansRange3 = sheet.getRange(2, 4, sheet.getLastRow());
var ansValues3 = ansRange3.getValues();
var ansRange4 = sheet.getRange(2, 5, sheet.getLastRow());
var ansValues4 = ansRange4.getValues();
for (var i = 0; i < (values.length)-1; i++) {
form.addMultipleChoiceItem()
.setTitle(values[i])
.setChoiceValues([ansValues1[i],ansValues2[i],ansValues3[i], ansValues4[i] ]); //Make another loop here if your Answers counts are different
}
}
But I'm still strugling how to make a correct answer and to give a number of point to the correct answer : without having to these two steps manually from forms.
So if someone can help me figure that out he is more than welcome!
Related
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Welcome");
var targetSheet = ss.getSheetByName("Done");
var startRow = 2;
var lr = sheet.getLastRow();
var dataRange = sheet.getRange(startRow, 1, lr-1, 6);
var data = dataRange.getValues();
var colNumber = sheet.getLastColumn()-1;
var delRows = [];
for (var i = 0; i < data.length; i++) {
var row = data[i];
var id = row[0];
var emailAddress = row[1];
var date = row[2];
var city = row[3];
var bccmail = row[6];
var Sender = 'XXXXXX';
var reply = 'xxxxxx#xxxxxxx.com';
if (emailAddress.match('#') === null){
continue;
};
var subject = row[4];
var message = "Hey " + id + ", welcome in the team " + row[5];
MailApp.sendEmail(emailAddress, subject, message, {bcc: bccmail,name: Sender,replyTo: reply});
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
var sourceRange = sheet.getRange(i+startRow, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
delRows.push(i+startRow);
}
delRows.reverse().forEach(ri=>{sheet.deleteRow(ri)});
Almost all the script works fine. When it comes to sendEmail, I have tried to follow these guidelines and use sendEmail(recipient, subject, body, options). 2 out of 3 options work fine but BCC doesn't work at the moment. Do you know what I am doing wrong? Can BCC be a variable?
The problem is in this line:
var bccmail = row[6];
dataRange is defined as a range with only 6 columns. data is a 2D array with the values of dataRange. row is a 1D array with a single row of data. JavaScript array indexes only start at 0, so the values are in row[0] to row[5].
Please check your sheet in which column does the bcc string is defined and count the index from 0.
Reference:
Arrays in JavaScript
How to use macros to import multi-column data from Google spreadsheets to auto trigger mails using sendEmails ? I tried tweaking the code given in google for one column containing a single alphabetic message.
function sendEmails()
{ var sheet = SpreadsheetApp.getActiveSheet(); var startColumn = 2; var numColumns = 6; var dataRange = sheet.getRange(startColumn, 1, numColumns, 4); var data = dataRange.getValues(); for (var i in data)
{ var Column = data[i]; var emailAddress = Column[0]; var Sl_No = Column[1]; var Insured_Name =Column[2]; var Policy_No = Column[3]; var subject = ('Sending emails from a Spreadsheet'); MailApp.sendEmail(emailAddress, subject, (Sl_No,Insured_Name,Policy_No)); } } –
I am very very very new to all this. I need help, I am trying to use script editor to get the date statically stamped in one column when something is entered in a different column. I figured how to do this for one tab but I need this to happen on multiple tabs in the same sheet and I'm struggling to get it to work. Is there one code that will work for this? This is the script I was using for one tab:
/**
* Creates a Date Stamp if a column is edited.
*/
//CORE VARIABLES
// The column you want to check if something is entered.
var COLUMNTOCHECK = 9;
// Where you want the date time stamp offset from the input location. [row, column]
var DATETIMELOCATION = [0,-8];
// Sheet you are working on
var SHEETNAME = 'Sheet 2'
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//checks that we're on the correct sheet.
if( sheet.getSheetName() == SHEETNAME ) {
var selectedCell = ss.getActiveCell();
//checks the column to ensure it is on the one we want to cause the date to appear.
if( selectedCell.getColumn() == COLUMNTOCHECK) {
var dateTimeCell = selectedCell.offset(DATETIMELOCATION[0],DATETIMELOCATION[1]);
dateTimeCell.setValue(new Date());
}
}
}
Thank you for your time in advance.
To proceed with the function on multiple sheets, you can check for the sheet name in an array of acceptable names.
function onEdit() {
var colToCheck = 9;
// Offset from the input [row, column]
var dateOffset = [0, -8];
// Sheets to proceed on
var sheetNames = ['Sheet 2', 'Sheet 3'];
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getName();
if (sheetNames.indexOf(name) > -1) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == colToCheck) {
var dateTimeCell = cell.offset(dateOffset[0], dateOffset[1]);
dateTimeCell.setValue(new Date());
}
}
}
References
Arrays
indexOf()
EDIT ONE
If you want multiple options, you could set them up in arrays. The order of the elements in the arrays must match.
This code assumes that the timestamp is always on the same row.
function onEdit() {
var sheetNames = ['Sheet 2', 'Sheet 3'];
var colsToCheck = [9, 15];
var colOffsets = [-8, -4];
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getSheetName();
var index = sheetNames.indexOf(name);
if (index > -1) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == colsToCheck[index]) {
var dateTimeCell = cell.offset(0, colOffsets[index]);
dateTimeCell.setValue(new Date());
}
}
}
EDIT TWO
For those of you who would prefer objects
function onEdit() {
var sheets = {
'Sheet 2': {
checkCol: 9,
offset: -8
},
'Sheet 3': {
checkCol: 15,
offset: -4
}
};
var sheet = SpreadsheetApp.getActive().getActiveSheet();
var name = sheet.getSheetName();
var settings = sheets[name];
if (settings) {
var cell = sheet.getActiveCell();
var col = cell.getColumn();
if (col == settings.checkCol) {
var dateTimeCell = cell.offset(0, settings.offset);
dateTimeCell.setValue(new Date());
}
}
}
Im trying to send multiple attachments using Google Spreadsheet but I get the following error "Cannot retrieve the next object: iterator has reached the end."
It does work, because it sends the e-mail to the first email-address in the list, but it fails for the second one.
I have seen similar questions here about it, but no solutions resolve my issue.
Here is the script:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1;
var numRows = 2;
var dataRange = sheet.getRange(startRow, 1, numRows, 2);
var file1 = DriveApp.getFilesByName('Maandbrief December.pdf');
var file2 = DriveApp.getFilesByName('Weekendbrief 7-9 december.pdf');
var data = dataRange.getValues();
for (i in data) {
var row = data[i];
var emailAddress = row[0];
var message = row[1];
var subject = "Maandbrief December en weekendbrief 7-9 december";
MailApp.sendEmail({to:emailAddress, subject:subject, body:message, attachments: [file1.next(), file2.next()]})
}}
Thank you for your help.
Try this:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1;
var numRows = 2;
var dataRange = sheet.getRange(startRow, 1, numRows, 2);
var files1 = DriveApp.getFilesByName('Maandbrief December.pdf');
while(files1.hasNext()){var file1=files1.next();}
var files2 = DriveApp.getFilesByName('Weekendbrief 7-9 december.pdf');
while(files2.hasNext()){var file2=files2.next();}
var data = dataRange.getValues();
for (var i=0;i<data.length;i++) {
var row = data[i];
var emailAddress = row[0];
var message = row[1];
var subject = "Maandbrief December en weekendbrief 7-9 december";
MailApp.sendEmail({to:emailAddress, subject:subject, body:message, attachments: [file1, file2]})
}
}
or this:
function sendEmails() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 1;
var numRows = 2;
var dataRange = sheet.getRange(startRow, 1, numRows, 2);
var n1=0;
var n2=0;
var files1 = DriveApp.getFilesByName('Maandbrief December.pdf');
while(files1.hasNext()){var file1=files1.next();n1++;}
var files2 = DriveApp.getFilesByName('Weekendbrief 7-9 december.pdf');
while(files2.hasNext()){var file2=files2.next();n2++}
var data = dataRange.getValues();
if(n1==1 && n2==1){
for (var i=0;i<data.length;i++) {
var row = data[i];
var emailAddress = row[0];
var message = row[1];
var subject = "Maandbrief December en weekendbrief 7-9 december";
MailApp.sendEmail({to:emailAddress, subject:subject, body:message, attachments: [file1, file2]});
}
}else{
throw('More than one file with given name.');
}
}
I am trying to get a script going that will automatically delete rows with a date over 3 days old (4 days on)
I found this script that I was hoping to be able to adapt:
function DeleteOldEntries() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
//give your sheet name below instead of Sheet1
var sheet = ss.getSheetByName("Foglio1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var currentDate = new Date();
var oneweekago = new Date();
oneweekago.setDate(currentDate.getDate() - 7);
for (i = lastrow; i >= 2; i--) {
var tempdate = sheet.getRange(i, 1).getValue();
if (tempdate < oneweekago) {
sheet.deleteRow(i);
}
}
}
But there seems to be an error in the script itself that I need to figure out before adapting it to 4 days instead of 7 (that part is easy)
My sheet has 3 columns with the date in column C if that info is helpful
"date in column C, if that info is helpful"
It is indeed ! instead of trying to get a date in column A as it it done in this line :
var tempdate = sheet.getRange(i, 1).getValue();
you should look at the value in column C like this :
var tempdate = sheet.getRange(i, 3).getValue();
but to be more efficient you should do these comparisons at array level, try it like below and it will run much faster ...
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Foglio1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();
var oneweekago = new Date();
oneweekago.setDate(currentDate.getDate() - 7);
for (i=lastrow;i>=2;i--) {
var tempdate = values[i-1][2];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if(tempdate < oneweekago)
{
sheet.deleteRow(i);
}
}
}
It will be much much faster if your rows are in order of date, newest at the top and you delete all the rows at once and not one at a time.
function deleteOldData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("CallHub1");
var datarange = sheet.getDataRange();
var lastrow = datarange.getLastRow();
var values = datarange.getValues();// get all data in a 2D array
var currentDate = new Date();
var daysago = new Date().setDate(currentDate.getDate() - 3);
var yearago = new Date().setDate(currentDate.getDate() - 365);
for (i=lastrow;i>=2;i--) {
var tempdate = values[i-1][0];// arrays are 0 indexed so row1 = values[0] and col3 = [2]
if(tempdate < daysago) {
if(tempdate < yearago) {continue;}
sheet.deleteRows(1, i);
break;
}
}
}