Speeding up UrlFetch Google App Scripts? - javascript

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);

Related

Script works in IE but not Chromium

I have a script I am using in a html file my program accesses. it has been using IE as the browser, but the new version no longer uses IE, it uses Chromium. some of the script works, but it gets to a point that it does nothing. no errors just stops. I am guessing there is a difference in the way Chromium handles the script. The script is one I got online and modified. I will include the code below. I use the update option the most "AutomateExcel3" please ignore my code block outs and comments as I was trying to figure sometime else out.
thanks for the help
<script>
//*********************************************INTRODUCTION*****************************************
//When using Web.Link the first thing to do is initialize what's called a handle to Pro/Engineer
// Get Session, Model.
var mGlob = pfcCreate("MpfcCOMGlobal");
var oSession = mGlob.GetProESession();
var CurDwg = oSession.CurrentModel;
var CurWind = oSession.CurrentWindow;
var Base = "P:\ENGINEERING FILES\TPS PRE-PROD ENG\MV-22\excel_file.xls";
function UpdateControls(Opt)
{
bottom.innerHTML = "";
var Cntls="";
if (Opt==1)
{
Cntls = "<H2>To Export:</H2>"+
"<LI>Enter target Excel Files path</LI><LI>Pick \"Dwg Table\"</LI><LI>Pick Drawing Table</LI><P><INPUT id=FileName type=file size=80 value=\""+Base+"\"><BR>"+
"<INPUT id=button1 type=button value=\"Dwg Table\" onclick=\"AutomateExcel1()\">";
}
else if (Opt==2)
{
Cntls = "<H2>To Import:</H2>"+
"<LI>Enter the Excel Files path</LI><LI>Pick \"Next>>>\"</LI><LI>Pick Drawing To Place</LI><P><INPUT id=FileName type=file size=80 value=\""+Base+"\"><BR>"+
"<INPUT id=button1 type=button value=\"Next>>>\" onclick=\"AutomateExcel2()\">";
}
else if (Opt ==3)
{
Cntls = "<H2>To Update:</H2>"+
"<LI>Enter the Excel Files path</LI><LI>Pick \"Dwg Table\"</LI><LI>Pick Drawing Table</LI><P><INPUT id=FileName type=file size=80 value=\""+Base+"\"><BR>"+
"<INPUT id=button1 type=button value=\"Dwg Table\" onclick=\"AutomateExcel3()\">";
}
middle.innerHTML = Cntls;
}
function AutomateExcel1()
{
var MultipleLinesInCells = false;
//Have the user pick a table to export
var SelOptions = pfcCreate("pfcSelectionOptions").Create ("dwg_table");
SelOptions.MaxNumSels = 1;
var Selections = oSession.Select(SelOptions, null);
var Table = Selections.Item(0).SelItem;
//Build a matrix containing the values for the table
var nTableRows = Table.GetRowCount();
var nTableCols = Table.GetColumnCount();
//Start a new Excel Spreadsheet
var oXL;
oXL = new ActiveXObject("Excel.Application");
var oWB = oXL.Workbooks.Add();
var oSheet = oWB.ActiveSheet;
//Loop around the table and dump information to excel
for (i=0;i<nTableRows;i++)
{
for (j=0;j<nTableCols;j++)
{
var Cell = pfcCreate("pfcTableCell").Create(i+1, j+1);
var Mode = pfcCreate("pfcParamMode").DWGTABLE_NORMAL;
try
{
var Val = Table.GetText (Cell,Mode);
var Out="";
if (Val.Count>1)
MultipleLinesInCells = true;
for (k=0;k<Val.Count;k++)
{
if (k>0)
{
if (k<Val.Count)
{
Out = Out + " ";
}
}
Out = Out + Val.Item(k);
}
oSheet.Cells(i+1, j+1).Value = Out;
}
catch(er)
{
//Failure occurs when cells are merged, pro/e doesn't recognize cells that are now merged into another
}
}
}
//Bring up Excel for user to do with what they want.
//oXL.Visible = true;
oXL.UserControl = false;
if (FileName.value==null)
File = Base
else
File = FileName.value;
try
{
oWB.Close(true, File,null);
oXL.Workbooks.Close();
oXL.Quit();
Base = FileName.value;
var Out = "<H2>Success:</H2>Pick here for created document";
if (MultipleLinesInCells)
Out = Out + "<H2>Warning:</H2>The export resulted in some Multi-line cells being concatenated";
bottom.innerHTML = Out;
}
catch(er)
{
var Out = "<H2>Error:</H2>Could Not Write Specified File, please edit path and try again. If not Chuck Norris Might Get Angry!";
bottom.innerHTML = Out;
}
}
function AutomateExcel2()
{
//Have the user pick somewhere
var mousePick = oSession.UIGetNextMousePick ( pfcCreate("pfcMouseButton").MOUSE_BTN_LEFT);
var Orig = mousePick.Position;
//Start Excel
var oXL = new ActiveXObject("Excel.Application");
try
{
var oWB = oXL.Workbooks.Open(FileName.value);
var oSheet = oWB.ActiveSheet;
Base = FileName.value;
}
catch (er)
{
bottom.innerHTML = "<H2>Error:</H2>Could Not Open Specified File, \""+FileName.value+"\" for Import, please edit path and try again";
return;
}
//Start the table instructions
var TableInsts = pfcCreate("pfcTableCreateInstructions").Create (Orig);
var TableSizeType = pfcCreate("pfcTableSizeType").TABLESIZE_BY_NUM_CHARS;
TableInsts.SizeType = TableSizeType;
var columnInfo = pfcCreate ("pfcColumnCreateOptions");
//Look for headers in top row
var nCols=0;
var Val = oSheet.Cells(1,nCols+1).Value;
while (Val!=null)
{
nCols=nCols+1;
Val = oSheet.Cells(1,nCols+1).Value;
var column = pfcCreate ("pfcColumnCreateOption").Create (pfcCreate ("pfcColumnJustification").COL_JUSTIFY_LEFT,Math.round(oSheet.Cells(1,nCols).ColumnWidth+1));
columnInfo.Append (column);
}
//Push column information into Table Instructions
TableInsts.ColumnData = columnInfo;
//Push in the Header row
var rowInfo = pfcCreate ("realseq");
rowInfo.Append (2.0); //title line
TableInsts.RowHeights = rowInfo;
//Now create the table in proe
var CurTable = CurDwg.CreateTable(TableInsts);
//Populate the header information
for (var i=1;i<=nCols;i++)
{
var Val = oSheet.Cells(1,i).Value;
writeTextInCell (CurTable, 1, i, Val);
}
//Populate the rest of the table
var i=2;
var Row = oSheet.Cells(i,1).Value;
while (Row!=null)
{
CurTable.InsertRow (1.0, i-1, false);
for (var j=1;j<=nCols;j++)
{
var Val = oSheet.Cells(i,j).Value;
writeTextInCell (CurTable, i, j, Val);
}
i=i+1;
Row = oSheet.Cells(i,1).Value;
}
//Close down Excel.
oXL.UserControl = false;
oWB.Close(true);
oXL.Workbooks.Close();
oXL.Quit();
Excel.Application.Quit(); // added this to try to close excel
var Out = "<H2>Success:</H2>Excel sheet imported as Pro/E Drawing Table";
bottom.innerHTML = Out;
}
function AutomateExcel3()
{
//Have the user pick a table to update
var SelOptions = pfcCreate("pfcSelectionOptions").Create ("dwg_table");
SelOptions.MaxNumSels = 1;
var Selections = oSession.Select(SelOptions, null);
var Table = Selections.Item(0).SelItem;
//Start Excel
var oXL = new ActiveXObject("Excel.Application");
try
{
var oWB = oXL.Workbooks.Open(FileName.value);
var oSheet = oWB.ActiveSheet;
Base = FileName.value;
}
catch(er)
{
bottom.innerHTML = "<H2>Error:</H2>Could Not Open Specified File, \""+FileName.value+"\" for Update, please edit path and try again.";
return;
}
//Look for headers in top row and check them against the already existing headers
var nProCols = Table.GetColumnCount ();
var nCols=0;
var Val = oSheet.Cells(1,nCols+1).Value;
while (Val!=null)
{
nCols=nCols+2; // default was 1 changed to 2 now it doesn't delete the column if nothing in the first row.
//Check to see if we need to add another column
if (nCols>nProCols)
{
Table.InsertColumn (Math.round(oSheet.Cells(1,nCols).ColumnWidth+1), nCols-1, false);
nProCols=nProCols+1;
}
//Get current XL value
var ValXL = oSheet.Cells(1,nCols).Value;
//Get current ProE value
var cell = pfcCreate ("pfcTableCell").Create (1, nCols);
var mode = pfcCreate("pfcParamMode").DWGTABLE_NORMAL;
try
{
var ValProE = Table.GetText (cell, mode).Item(0);
}
catch(er)
{
var ValProE = "";
}
//Overwrite ProE value with XL value if they are not equal
if (ValProE!=ValXL)
{
ModifyCellText(Table, cell, ValXL);
}
Val = oSheet.Cells(1,nCols+1).Value;
}
//Check to see if any columns are left that need deleting off
//removed code and it appears to work without setting column to 15 above
while (nCols<nProCols)
{
Table.DeleteColumn (nProCols, false);
nProCols=nProCols-1; //default was -1 (changed to -0 and crashed creo)
}
//Populate the rest of the table
var nProRows = Table.GetRowCount();
var nRows = 0;
var Val = oSheet.Cells(nRows+1,1).Value;
while (Val!=null)
{
nRows = nRows + 1;
//Check to see if we need to add another row
if (nRows>nProRows)
{
Table.InsertRow (1, nRows-1, false);
nProRows=nProRows+1;
}
//Loop around all columns for each row
for (i=1;i<=nCols;i++)
{
//Get current XL value
var ValXL = oSheet.Cells(nRows,i).Value;
//Get current ProE value
var cell = pfcCreate ("pfcTableCell").Create (nRows, i);
var mode = pfcCreate("pfcParamMode").DWGTABLE_NORMAL;
try
{
var ValProE = Table.GetText (cell, mode).Item(0);
}
catch(er)
{
var ValProE = "";
}
//Overwrite ProE value with XL value if they are not equal
if (ValProE!=ValXL)
{
ModifyCellText(Table, cell, ValXL);
}
}
Val = oSheet.Cells(nRows+1,1).Value;
}
//Check to see if any rows are left that need deleting off
while (nRows<nProRows)
{
Table.DeleteRow (nProRows, false);
nProRows=nProRows-1;
}
CurDwg.Regenerate ();
//Close down Excel.
oXL.DisplayAlerts = false;
oXL.UserControl = false;
oWB.Close(true);
oXL.Workbooks.Close();
oXL.Quit();
// below code seams to stop excel instance created by from task manager while leaving other instances of excel alone
excel = null;
excelfile = null;
excelsheet = null;
CollectGarbage();
setTimeout("CollectGarbage()",1);
oSheet = null;
oWB = null;
oXL = null;
// below code kills excel from taskmanager but all excel is closed.
var WshShell = new ActiveXObject("WScript.Shell");
var oExec = WshShell.Exec("taskkill /F /IM EXCEL.exe");
CurDwg.UpdateTables ();
var Out = "<H2>Success:</H2>Excel sheet used as basis to update a Pro/E Drawing Table"+
"<p>Note:"+
"<LI>Cell Font and Alignment is Maintained for existing cells</LI>"+
"<LI>Rows can be added and removed - this is likely to require extra formatting</LI>"+
"<LI>There may be problems involving updating tables with merged cells</LI>"+
"<LI>Ensure you check the table for correct format after an update</LI>"+
"<LI>Congratulations Chuck Norris Approves!</LI>"+
"</p>";
bottom.innerHTML = Out;
}
function ModifyCellText(Table, cell, ValXL)
{
try
{
var CellNote = Table.GetCellNote (cell);
var CellNoteInsts = CellNote.GetInstructions (true);
var CellNoteTextLines = CellNoteInsts.TextLines;
var CellNoteTextLine1 = CellNoteInsts.TextLines.Item(0);
var CellNoteTextLine1Texts = CellNoteTextLine1.Texts;
var CellNoteTextLine1Text1 = CellNoteTextLine1Texts.Item(0);
var FontName = CellNoteTextLine1Text1.FontName;
}
catch(er)
{
var FontName = "ariallight.TTF";
}
var lines = pfcCreate("stringseq");
lines.Append (ValXL);
Table.SetText(cell, lines);
var CellNote = Table.GetCellNote (cell);
var CellNoteInsts = CellNote.GetInstructions (true);
var CellNoteTextLines = CellNoteInsts.TextLines;
var CellNoteTextLine1 = CellNoteInsts.TextLines.Item(0);
var CellNoteTextLine1Texts = CellNoteTextLine1.Texts;
var CellNoteTextLine1Text1 = CellNoteTextLine1Texts.Item(0);
//Switch Font
CellNoteTextLine1Text1.FontName = FontName;
CellNote.Modify (CellNoteInsts);
}
function writeTextInCell(table /* pfcTable */, row /* integer */,
col /* integer */, text /* string */)
{
var cell = pfcCreate ("pfcTableCell").Create (row, col);
var lines = pfcCreate ("stringseq");
lines.Append (text);
try{
table.SetText (cell, lines);
}
catch(er)
{
alert (row+" "+col);
}
}
// Function to create the activeX objects that are the interface to Web.Link.
function pfcCreate (className)
{
if (!pfcIsWindows())
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (pfcIsWindows())
return new ActiveXObject ("pfc."+className);
else
{
ret = Components.classes ["#ptc.com/pfc/" + className + ";1"].createInstance();
return ret;
}
}
//Checks what OS is being operated
//IE11 requires more indepth browser testing...
function get_browser_info(){
var ua=navigator.userAgent,tem,M=ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if(/trident/i.test(M[1])){
tem=/\brv[ :]+(\d+)/g.exec(ua) || [];
return {name:'IE',version:(tem[1]||'')};
}
if(M[1]==='Chrome'){
tem=ua.match(/\bOPR\/(\d+)/)
if(tem!=null) {return {name:'Opera', version:tem[1]};}
}
M=M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
if((tem=ua.match(/version\/(\d+)/i))!=null) {M.splice(1,1,tem[1]);}
return {
name: M[0],
version: M[1]
};
}
function pfcIsWindows ()
{
var browser = get_browser_info();
if (browser.name.indexOf ("IE") != -1)
return true;
else
return false;
}
</script>
code worked perfectly in IE but not in the new browser I am forced to use

Copy values to next column(if blank) in the same row. If not blank, copy to the second column(if blank) in same row. Repeat

Disclaimer: Im very new to google scripts. I jumbled together this code with mixed success.
When I run the script, it works fine with the first two attempts. Then it doesnt work after that because column Q now has values in other cells within the column and the script is technically correct but not running at intended. I need to ignore column Q cells that are not blank and still run the script to copy P values to the other cells in column Q.
Also, when column Q with in the same row is not blank, I need to copy the value from column P to column R (if blank). Rinse and Repeat script...
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ();
var source = ss.getRange ("Sheet1!P2:P");
var destSheet = ss.getSheetByName("Sheet1");
var destRange = destSheet.getRange('Q2:Q')
var destRange2 = destSheet.getRange('R2:R')
if (destRange.isBlank()) {
source.copyTo (destRange, {contentsOnly: true});
source.clear ();
}
if (destRange2.isBlank()) {
source.copyTo (destRange2, {contentsOnly: true});
source.clear ();
}
}
You need to do the blank check for each cell separately
However, if you do it wiht the Apps Script method isBlank() - this will make your code a bit slow.
I suggest you to
retreive the existing values both in the source and destination ranges with getValues
check for each of the destinations values either those are empty and replace the empty values through source values
assign the modified values back to the sheet with setValues
Sample code:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange.setValues(destValues)
destRange2.setValues(dest2Values)
source.clear ();
}
UPDATE
If you want to copy to column Q and R alternately, you can use script properties to save the run count of the script and execute different code blocks for odd and even number.
Sample:
function copyVals () {
var ss = SpreadsheetApp.getActiveSpreadsheet ()
var sheet = ss.getSheetByName("Sheet1")
var lastRow = sheet.getLastRow()
var source = sheet.getRange ("P2:P" + lastRow)
var destSheet = sheet
var destRange = destSheet.getRange('Q2:Q' + lastRow)
var destRange2 = destSheet.getRange('R2:R' + lastRow)
var sourceValues = source.getValues().flat()
var destValues = destRange.getValues()
var dest2Values = destRange2.getValues()
var scriptProperties = PropertiesService.getScriptProperties()
var myProperty = scriptProperties.getProperty('timesCalled')
if (!myProperty){
myProperty = "1"
}
myProperty = JSON.parse(myProperty)
var isOdd = myProperty % 2
if(isOdd){
sourceValues.forEach(function(value, i){
console.log("i" + i)
if (destValues[i][0] == "") {
destValues[i][0] = value
}
})
destRange.setValues(destValues)
} else{
sourceValues.forEach(function(value, i){
if (dest2Values[i][0] == "") {
dest2Values[i][0] = value
}
})
destRange2.setValues(dest2Values)
}
source.clear ()
myProperty++
scriptProperties.setProperty('timesCalled', JSON.stringify(myProperty))
}

Loop grabbing data its not supposed to and using it

So I've been working on this code that will check a google sheet for a date two weeks from now and send a reminder. The first time I run the code, it works great. The problem is, the second time I run the code it ignores the duplicate checker and then sends an email using data from a row that has already been sent. I'm trying to figure out A) why is it doing that, and B) how do I fix it.
function sendEmails3() {
var today = new Date();
today.setDate(today.getDate() + 14); // Today's date, without time
today = today.toLocaleDateString();
var EMAIL_SENT = "EMAIL_SENT";
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2; // First row of data to process
var numRows = sheet.getLastRow() - 1; // Number of rows to process
// Fetch the range of cells A2:B999
var dataRange = sheet.getRange(startRow, 1, numRows, 999)
// Fetch values for each row in the Range.
var data = dataRange.getValues();
for (var i = 0; i < data.length; ++i) {
var row = data[i];
var emailAddress = row[0]; // First column
var firstName = row[1]; // Second column
var lastName = row[2]; // Third column
var event1 = row[4];
var event2 = row[6];
var event3 = row[8];
var emailSent = row[9];
var sheetDate1 = row[13].toLocaleDateString();
var sheetDate2 = row[14].toLocaleDateString();
var sheetDate3 = row[15].toLocaleDateString();
Logger.log(sheetDate1)
if (sheetDate1 == today) {
var event = event1;
var sheetDate = sheetDate1;
} else if (sheetDate2 == today) {
var event = event2;
var sheetDate = sheetDate2;
} else if (sheetDate3 == today) {
var sheetDate = sheetDate3;
var event = event3;
}
if (sheetDate != today) {
continue;
}
Logger.log(sheetDate)
Logger.log(event)
Logger.log(emailAddress)
if (emailSent != "EMAIL_SENT") { // Prevents sending duplicates
var subject = "Reminding you that your " + event + " is coming up on " +
sheetDate + "!";
MailApp.sendEmail(emailAddress, subject, "", {
htmlBody: slsdf
});
sheet.getRange(startRow + i, 10).setValue(EMAIL_SENT);
// Make sure the cell is updated right away in case the script is interrupted
SpreadsheetApp.flush();
var sheetDate = "";
Logger.log(sheetDate)
var event = "";
}
}
}
please ignore the garbage in the part where its supposed to be emailing html, it's juts a huge pile of html and shouldn't effect anything.

Google Form Script Population

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];

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