Google Form Script Population - javascript

I am trying to populate a google form with questions scraped from a google sheet. Currently when I run my code I am getting the questions created, but only 25% or so actually have the string, the rest are simply blank. The questions that appear correctly change every time I run the script. It is seemingly random.
function formPopulation() {
var ss = SpreadsheetApp.openById("--");
var sheet = ss.getSheetByName('Tracker');
var auditTool = ss.getSheetByName('Audit Tool');
var validatorInfo = ss.getSheetByName('Validator Info');
//Sheet Info
var rows = auditTool.getLastRow(); //Number of Rows
var columns = auditTool.getLastColumn(); //Number of Columns
var startRow = 1;
var startColumn = 1;
var dataRange = auditTool.getRange(startRow, startColumn, rows, columns);
//getRange(first row of data, first column of data, last row of data, last column of data)
var data = dataRange.getValues();
//Sets working range of script
var form = FormApp.openById("--");
var item = form.addListItem();
var entityName = "";
var arrayOfEntities = [];
var newEntity = '';
for (var i = 4; i < columns; i++) {
//4 because that is where entity names begin
entityName = data[i][2];
Logger.log('entityName: ' + entityName);
newItem = item.createChoice(entityName);
arrayOfEntities.push(newItem);
};
item.setTitle("Select Entity").setChoices(arrayOfEntities);
var requirement = "";
var arrayOfRequirements = [];
var newRequirement = '';
for (var j = 5; j < rows; j++) {
//5 because that is where Requirements begin
if (data[0][j] != null) {
requirement = data[0][j];
if (requirement != "" || requirment != null){
requirement = "question #" + j;
Logger.log('requirement: ' + requirement);
form.addMultipleChoiceItem().setTitle(requirement).setChoiceValues(['Complete', 'Incomplete']);
};
};
};
};
The first question is supposed to be a multiple choice item where each 'entity' is an option. The remainder of the questions are supposed to be whether each 'requirement' is marked complete or incomplete.
Here is the spreadsheet I am working from

you have a typo:
if (requirement != "" || requirment != null){
should be 'requirement'

Here in last forloop
requirement = "question #" + j;
Please verify, is it ok ? or you should use
requirement = "question #" + j + ' ' +data[0][j];

Related

Deleting row in one sheet if cell value is found in another sheet

I am trying to delete rows if cell value is found in another sheet via App Script. But the code is not going through complete data in history sheet.
function deleteOld1() {
var app = SpreadsheetApp;
var orderSheet = app.getActiveSpreadsheet().getSheetByName("RC"); \sheet where to look
var historySheet = app.getActiveSpreadsheet().getSheetByName("OB"); \sheet from which data has to be deleted
var lastRow = historySheet.getLastRow();
var lastRow1 = orderSheet.getLastRow();
var poNO = orderSheet.getRange("A2:A" + lastRow);
var myRange = historySheet.getRange("A2:A" + lastRow1);
var row = poNO.getRow();
var col = poNO.getColumn();
var data = myRange.getValues();
var data1 = poNO.getValues();
if (col>= poNO.getColumn() && col <= poNO.getColumn() && row>= poNO.getRow() && row <= poNO.getRow()){
for (i=0; i<data.length; i++) {
for (j=0; j<data1.length; j++){
if(data[i][0] == data1[j][0]){
historySheet.deleteRow(i+2);
}
}
}
}
}
Please go through this code and help

Speeding up UrlFetch Google App Scripts?

The goal is to run through about 10,000 lines of links. Determine which have page numbers > 3 and highlight the first column. I have all of this done, but the problem is that it takes Url Fetch too long, I run into a maximum run time error. Is there anyway I can speed up this code so I can run through the 10,000 lines?
function readColumns() {
//program is going to run through column 3 by going through the amount of rows, truncating last three characters to see if pdf, then highlighting first column
var sheet = SpreadsheetApp.getActiveSheet();
var columns = sheet.getDataRange();
var rowNum = columns.getNumRows();
var values = columns.getValues();
var html;
var htmlString;
for(var i = 1; i <= rowNum; i++){
var columnLogger = values[i][2];
try{
html = UrlFetchApp.fetch(values[i][2],
{
muteHttpExceptions: true,
}
);
}catch(e){
Logger.log("Error at line " + i);
var error = true;
}
htmlString = html.getContentText();
var index = htmlString.indexOf("Pages") + 6;
var pageNumber = parseInt(htmlString.charAt(index),10);
var lastChars = "" + columnLogger.charAt(columnLogger.length-3) + columnLogger.charAt(columnLogger.length-2) + columnLogger.charAt(columnLogger.length-1);
if((error) || (!lastChars.equals("pdf") && values[i][6].equals("") && !pageNumber >= 3)){
//goes back to first column and highlights yellow
var cellRange = sheet.getRange(1, 1, rowNum, 3)
var cell = cellRange.getCell(i+1, 1)
cell.setBackground("yellow");
}
}
}
Edit - short scripts:
function foreverCall(){
var start = 1480;
for(;;){
readColumns(start);
start = start + 100;
}
}
function readColumns(start) {
//program is going to run through column 3 by going through the amount of rows, truncating last three characters to see if pdf, then highlighting first column
var sheet = SpreadsheetApp.getActiveSheet();
var columns = sheet.getDataRange();
var rowNum = columns.getNumRows();
var values = columns.getValues();
var html;
var htmlString;
var error;
for(var i = start; i < start+100; i++){
if(loop(values, error, html, htmlString, rowNum, sheet, columns, i)){
var cellRange = sheet.getRange(1, 1, rowNum, 3)
var cell = cellRange.getCell(i, 1)
cell.setBackground("yellow");
}
}
}
function loop(values, error, html, htmlString, rowNum, sheet, columns, i){
var columnLogger = values[i][2];
var lastChars = columnLogger.slice(-4);
if(!lastChars.equals(".pdf") && values[i][6].equals("")){
return true;
}else{
try{
error = false
html = UrlFetchApp.fetch(values[i][2].toString());
if(html == null){
error = true;
}
}catch(e){
Logger.log("Error at line " + i);
error = true;
}
if(!error){
htmlString = html.getContentText();
var index = htmlString.indexOf("Pages") + 6;
var pageNumber = parseInt(htmlString.charAt(index),10);
}
//goes back to first column and highlights yellow
if(error || !pageNumber >= 3){
return true;
}
}
return false;
}
You can replace this:
var lastChars = "" + columnLogger.charAt(columnLogger.length-3) + columnLogger.charAt(columnLogger.length-2) + columnLogger.charAt(columnLogger.length-1);
With this:
var lastChars = columnLogger.slice(-3);
You could also initiate the fetch script from an html sidebar or dialog to run short batches and then return back to the success handler which could then initiate another batch depending upon the return value. The return value could also be used to start the next batch at the next row. It would actually take longer to run but you could probably stay well under the script limit by keeping your batches small.
You can replace with the line with
var lastChars = columnLogger.slice(-3);

Returning cell value based on Radio selection

The goal I am trying to achieve is to retrieve a cell value based on a form radio selection and update a text area.
Process: User opens dialog box. They select a field office. Onclick runs the function check. After check runs google.script.run.withSuccessHandler(addSignatureLine).getSignatureLine(cellElement); is supposed to run and update the textarea with the Id 'AdditionalMessage' with the signature line retrieved from .getSignatureLine.
Here are two functions of the html code:
<script>
function addSignatureLine(signatureLine){
document.getElementById('AdditionalMessage').value = '\n\n'signatureLine;
};
function updateSignatureLine() {
var cellElement = document.getElementById('ET');
console.log('cellElement: ' + cellElement);
google.script.run.withSuccessHandler(addSignatureLine)
.getSignatureLine(cellElement);
};
function check() {
var ele = document.getElementsByName('fieldOfficeET');
var flag = 0;
for (var i = 0; i < ele.length; i++) {
if (ele[i].checked)
flag = 1;
}
if (flag == 1)
document.getElementById('Submit').disabled = false;
};
</script>
Here is the getSignatureLine.gs script
function getSignatureLine(cellObject) {
var ss = SpreadsheetApp.openById('googleSheetId');
var sheet = ss.getSheetByName('AMS Contact Information');
var firstRow = 2;
var lastRow = 10;
var dataRange = sheet.getRange(firstRow, 1, lastRow, 11);
var dataValues = dataRange.getValues();
for (var key in cellObject) { //Loop through all the data in the form
Logger.log('key: ' + key);
Logger.log('value: ' + cellObject[key]);
}
//Determines the row the Field Office is in
for (var rr = 0; rr < dataValues.length; rr++) {
if (dataValues[rr][0] == cellObject.fieldOfficeET) {
var r = rr + 2
break;
}
}
var signatureLine = sheet.getRange(r, 11).getValue();
Logger.log("signatureLine: " + signatureLine)
return signatureLine;
}
There is a problem with this line:
document.getElementById('AdditionalMessage').value = '\n\n'signatureLine;
I would try:
document.getElementById('AdditionalMessage').value = '\n\n' + signatureLine;
Add a plus sign to concatenate the text.

How do I bold one line in a Google Docs Script?

I'm writing a script to parse a Google Sheet and format the cells nicely on a Doc. I'd like the cell data from column 1 to always be bold and the cell data from column 6 to always be Italic. The problem is, after appending a paragraph to the document body, the attribute changes are applied to the entire document. Is there a way to bold/italicize the cell data before appending it to the doc body?
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var doc = DocumentApp.create("Smogon Formatted");
var docBody = doc.getBody();
for (var i = 2; i <= numRows; i++) {
for (var j = 1; j <= numCols; j++){
var cellData = rows.getCell(i, j).getValue()
// Format data based on column
if (j == 1) {
docBody.appendParagraph(cellData).editAsText().setBold(true);
} else if (j == 2 || j == 3) {
var imgFormula = rows.getCell(i, j).getFormula();
var imgUrl = getImageUrl(imgFormula);
docBody.appendParagraph("[img]" + imgUrl + "[/img]");
} else if (j == 6) {
docBody.appendParagraph(cellData).editAsText().setItalic(true);
} else {
docBody.appendParagraph(cellData);
}
}
}
};
EDIT: Try #2, using the setAttributes method
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var numCols = rows.getNumColumns();
var values = rows.getValues();
var doc = DocumentApp.create("Smogon Formatted");
var docBody = doc.getBody();
for (var i = 2; i <= numRows; i++) {
for (var j = 1; j <= numCols; j++){
var cellData = rows.getCell(i, j).getValue()
// Format data based on column
if (j == 1) {
docBody.appendParagraph(cellData).setAttributes(style1);
} else if (j == 2 || j == 3) {
var imgFormula = rows.getCell(i, j).getFormula();
var imgUrl = getImageUrl(imgFormula);
docBody.appendParagraph("[img]" + imgUrl + "[/img]");
} else if (j == 6) {
docBody.appendParagraph(cellData).setAttributes(style2);
} else {
docBody.appendParagraph(cellData);
}
}
}
};
// Style definitions as global variables
var style1= {};
style1[DocumentApp.Attribute.BOLD] = true;
var style2= {};
style2[DocumentApp.Attribute.ITALIC] = true;
If you use style attributes you can assign a style to every paragraph very easily, you can actually do it for any document element...
Here is a basic example code to show how it works :
(doc here)
function exportToDoc(){
var doc = DocumentApp.openById('16i----L53WTDpzuLyhqQQ_E');// or create a new doc (but not while you test it :-)
var body = doc.getBody();
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getDataRange().getValues();
for (var i in values){
var rowData = values[i].join(' + ');
if (i == 1) {
body.appendParagraph(rowData).setAttributes(style2);
} else if (i == 2 ) {
body.appendParagraph(rowData).setAttributes(style1)
}
}
doc.saveAndClose();
}
// Style definitions as global variables
var style1 = {};// style example 1
style1[DocumentApp.Attribute.FONT_SIZE] = 10;
style1[DocumentApp.Attribute.FONT_FAMILY] = DocumentApp.FontFamily.CONSOLAS;
style1[DocumentApp.Attribute.FOREGROUND_COLOR] = "#444400";
var style2 = {};// style example 2
style2[DocumentApp.Attribute.FONT_SIZE] = 16;
style2[DocumentApp.Attribute.FONT_FAMILY] =DocumentApp.FontFamily.ARIAL_NARROW;
style2[DocumentApp.Attribute.FOREGROUND_COLOR] = "#005500";
//
example random data result :

Compare value to another spreadsheet using array loop and write new values

Hello all I'm having trouble implementing array loops in my project... Here is what I want to do.
I have a spreadsheet called "Red Book" this sheet gets updated regularly once the staff have updated it I have a column where they can select to submit the data they've just entered on that specific row (editing this column calls an onEdit function).
The data will then be written to another spreadsheet (different file) called "Raw Data"
For each submit I have a unique identifier. I need the onEdit code to do the following...
Iterate through the column A to find the unique identifier
Once found update the data in columns 1 through 5
Below is the script I have so far:
function TransferToAppData(e) {
var destFile = SpreadsheetApp.openById('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
var destSheet = destFile.getSheetByName("Raw App Data");
var ss = e.source;
var s = ss.getActiveSheet();
var uniConstRng = s.getRange("A1");
var uniqueConstVal = uniConstRng.getValue();
var NextOpenRow = destSheet.getLastRow() + 1;
var ActiveRow = e.range.getRow();
Logger.log(ActiveRow);
var uniqueVal = s.getRange(ActiveRow,1).getValue();
var add = s.getRange(ActiveRow,2).getValue();
var name = s.getRange(ActiveRow,3).getValue();
var dt = s.getRange(ActiveRow,5).getValue()
if (uniqueVal == "") {
s.getRange(ActiveRow,1).setValue(uniqueVal + 1);
uniConstRng.setValue(uniqueVal + 1);
var transferVals = s.getRange(ActiveRow,1,1,5).getValues();
Logger.log(transferVals);
destSheet.getRange(NextOpenRow,1,1,5).setValues(transferVals);
destSheet.getRange(NextOpenRow, 6).setValue("Applicant");
}
else {
var destLastRow = destSheet.getLastRow();
var destDataRng = destSheet.getRange(2,1,destLastRow,5)
var destValues = destDataRng.getValues();
var sourceValues = s.getRange(ActiveRow,1,1,5).getValues();
for( var i = 0; i < destValues.length; ++i){
if (destValues([i][0])==uniqueVal) {
for(n=0;n<destValues[0].length;++n){
///I"m stuck!!!
}
}
}
}
}
As you can see I have the first array loop going, but I'm having trouble figuring out how to do a second loop that iterates only on the row where the unique value is found and write the source data to ONLY to row where the unique value was found not the whole sheet.
I figured it out...
Below is the code and here is how it works...
When values in certain columns are edited this code is fired.
1--It finds the unique identifier located in the row which was edited.
2--Compares that identifier with a column of unique identifiers in another spreadsheet.
3--When a match is found it writes the change to the new spreadsheet and exits the loop
function TransferToAppData(e) {
var destFile = SpreadsheetApp.openById('1V3R2RnpA8yXmz_JDZSkBsK9tGR2LjHZp52p5I1CuQvw');
var destSheet = destFile.getSheetByName("Raw App Data");
var ss = e.source;
var s = ss.getActiveSheet();
var uniqueConstRng = s.getRange("A1");
var uniqueConstVal = uniqueConstRng.getValue();
var NextOpenRow = destSheet.getLastRow() + 1;
var ActiveRow = e.range.getRow();
var uniqueVal = s.getRange(ActiveRow,1).getValue();
if (s.getRange(ActiveRow,2).getValue() == "" || s.getRange(ActiveRow,3).getValue()=="" || s.getRange(ActiveRow,4).getValue()=="" || s.getRange(ActiveRow,5).getValue()=="") {
s.getRange(ActiveRow,13).clearContent();
Browser.msgBox("Address, Name, Date Entered & Rent are required fields!");
} else{
if (uniqueVal == "") {
s.getRange(ActiveRow,1).setValue(uniqueConstVal + 1);
uniqueConstRng.setValue(uniqueConstVal + 1);
var transferVals = s.getSheetValues(ActiveRow,1,1,5);
destSheet.getRange(NextOpenRow,1,1,5).setValues(transferVals);
destSheet.getRange(NextOpenRow, 6).setValue("Applicant");
}
else {
var destLastRow = destSheet.getLastRow();
var destValues = destSheet.getSheetValues(2,1,destLastRow,5);
var sourceValues = s.getSheetValues(ActiveRow,1,1,5);
for(var i = 0; i < destValues.length; ++i){
if (destValues[i][0]===uniqueVal) {
destSheet.getRange(i+2,1,1,5).setValues(sourceValues);
break;
}
}
}
s.sort(1,false);
destSheet.sort(1,false);
}
}

Categories

Resources