Execute a second function when the first complete - javascript

I have a GS code with three different functions that are activated with a form submission.
The first function:
function processForm(formObject){
if(formObject.RecId && checkID(formObject.RecId)){
updateData(getFormValues(formObject),globalVariables().spreadsheetId,getRangeByID(formObject.RecId));
}else{
appendData(getFormValues(formObject),globalVariables().spreadsheetId,globalVariables().insertRange);
var form = FormApp.create(formObject.nombre)
.setAllowResponseEdits(false)
.setCollectEmail(false)
.setDescription(formObject.fechaprev)
.setRequireLogin(false)
.setShowLinkToRespondAgain(false);
var newname = formObject.nombre;
form.setDestination(FormApp.DestinationType.SPREADSHEET, globalVariables().spreadsheetId);
}
When this first function completes I need to run this other two functions:
function ordenarData(formUrl){
var ss = SpreadsheetApp.openById(globalVariables().spreadsheetId);
var sheetNameArray = [];
var sheets = ss.getSheets();
for (var i = 0; i < sheets.length; i++) {
sheetNameArray.push(sheets[i].getName());
}
var ordenado = sheetNameArray.sort();
for( var j = 0; j < sheets.length; j++ ) {
ss.setActiveSheet(ss.getSheetByName(sheetNameArray[j]));
ss.moveActiveSheet(j + 1);
var last_element = sheetNameArray[sheetNameArray.length - 1];
Logger.log(last_element);
}
completarData(formUrl,last_element);
}
function completarData(formUrl,last_element){
var ss = SpreadsheetApp.openById(globalVariables().spreadsheetId);
var hojaData = ss.getSheetByName("Data")
var celdaNEv = "=COUNT(\'"+ last_element + "\'\!\A\:\A\)";
var celdaSatisf = "=IFERROR((AVERAGE(\'"+ last_element +"\'\!\C\:\C)/10);0)";
var celdaPEv = '=IFERROR(O'+ hojaData.getLastRow() +'/N' + hojaData.getLastRow() +';0)';
var celdaPAs = '=IFERROR(N'+hojaData.getLastRow()+'/M'+hojaData.getLastRow()+';0)';
var celdaForm = "<a href=" + formUrl + " target='_blank' class='btn btn-primary btn-xs'><i class='fas fa-file-alt'></i></a>";
var celdaTh = '=IFERROR(ROUND(L'+hojaData.getLastRow()+'*N'+hojaData.getLastRow()+'; 0);0)';
var celdaMhr = '=IFERROR(ROUND(T'+hojaData.getLastRow()+'/M'+hojaData.getLastRow()+'; 2);0)';
var formulas = [
[celdaNEv, celdaSatisf, celdaPEv, celdaPAs, celdaForm, celdaTh, celdaMhr]
];
var formatos = [
["###", "0.00%", "0.00%", "0.00%", "", "####", "0.00"]
];
var cell = hojaData.getRange("O"+hojaData.getLastRow()+":U"+hojaData.getLastRow()+"").setNumberFormats(formatos);
cell.setValues(formulas);
}
As you can see, the first function generates a GForm and set the destination to an existing ssheet. Then, with ordenarData() I want to order the sheets and get the name of the last tab. My problem is that if a link processForm() to the second function, they run at the same time and theres no time to generate the new tab, so the function does not work fine.
How can I set that the function ordenarData() runs only when processForm() has finished?
If you know any other way to get the name of the Tab which is generate with FormApp.create().setDestination it will be also okay for me.

Solve!
SpreadsheetApp.flush() works fine for me: getSheets() Google Apps Script multiple calls issue

Related

Bootstrap modal populated by selected row in table data

The code below works fine on my computer, however when I am trying it on different workstations it does not work unless you do a hard refresh SHIFT + F5 then it will work but, when the page is reloaded it will go back to not working. Any help if you can tell me where this script is wrong would be greatly appreciated.
function run() {
var table = document.getElementById('call-logs-table');
var rows = table.rows;
for (var i=0; i<rows.length; i++) {
rows[i].onclick = function (event) {
var cells = this.cells;
var person_contacted = cells[0].innerHTML;
var date = cells[1].innerHTML;
var c_purpose = cells[2].innerHTML;
var c_notes = cells[3].innerHTML;
var sales_rep = cells[4].innerHTML;
var timestamp = cells[5].innerHTML;
var potential = cells[6].innerHTML;
var catalog_num = cells[7].innerHTML;
var dateplanner_num = cells[8].innerHTML;
var calendar_num = cells[9].innerHTML;
document.getElementById('call-log-title').innerHTML = 'Call Log Entered at ' + timestamp + ' by ' + sales_rep;
document.getElementById('lbl_contact').innerHTML = person_contacted;
document.getElementById('lbl_date').innerHTML = date;
document.getElementById('lbl_catalogs').innerHTML = catalog_num;
document.getElementById('lbl_calendars').innerHTML = calendar_num;
document.getElementById('lbl_planners').innerHTML = dateplanner_num;
document.getElementById('lbl_purpose').innerHTML = c_purpose;
document.getElementById('lbl_notes').innerHTML = c_notes;
document.getElementById('lbl_potential').innerHTML = potential;
};
}
}
window.onload = function() { run(); }

google script loop copy to loop row

Hi sorry this is probably a very newbie question, I am teaching myself and can't figure out how to google the answer to this one.
I have a loop in google sheets that goes through each field and updates some cells which pull info from a website that I then need to copy across into each row of the loop. It seems to be working through the loop okay however when trying to copy i cant get it into the correct row.
Im sure its something very simple hoping someone out there can point me in the right direction. I'm pretty sure its to do with the code at line 34 but can't figure out how to correct it.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var i = 0
for (i; i < len; i++) {
var row = data[i];
var player = row[4]
var prop = row[6]
var number = row[7]
var overodds = row[8]
var underodds = row[9]
var overreq = row[10]
var underreq = row[11];
if(prop = "Points"){
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('B1').activate();
ss.getRange("B1").setValue(player);
ss.getRange('AB5').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(overreq).activate();
ss.getRange('Stats!AB5').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
ss.setActiveSheet(ss.getSheetByName('Stats'), true);
ss.getRange('AB6').activate();
ss.setActiveSheet(ss.getSheetByName('Loop'), true);
ss.getRange(underreq).activate();
ss.getRange('Stats!AB6').copyTo(ss.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
}
}
}
Modifications of the original code:
Corrected an error in line 24. In your original post, you are using = (assignment operator) to compare your variables. However, you want to use == (equality operator).
Added missing semicolons. Although not necessary, makes for good, consistent style and may prevent some errors.
Moved i declaration inside the for-loop. Makes for cleaner, safer code.
Modified for-loop body so that it uses ranges and setValue(), getValue() methods to copy data.
function myLoop() {
var ui = SpreadsheetApp.getUi();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var Lsheet = ss.setActiveSheet(ss.getSheetByName('Loop'), true);
var rangeData = Lsheet.getDataRange();
var lastColumn = rangeData.getLastColumn();
var lastRow = rangeData.getLastRow();
var dataRange = Lsheet.getRange(2,1, lastRow-1, lastColumn-1);
var data = dataRange.getValues();
var len = data.length;
var statsSheet = ss.getSheetByName('Stats');
var loopSheet = ss.getSheetByName('Loop');
for (var i = 0; i < len; i++) {
var row = data[i];
var player = row[4];
var prop = row[6];
var number = row[7];
var overodds = row[8];
var underodds = row[9];
var overreq = row[10];
var underreq = row[11];
if (prop == "Points") {
statsSheet.getRange('B1').setValue(player);
loopSheet.getRange(overreq).setValues(
statsSheet.getRange('AB5').getValues()
);
loopSheet.getRange(underreq).setValues(
statsSheet.getRange('AB6').getValues()
);
}
}
}
Could you try this:
var currentRow = ss.getActiveRange().getRow();
var currentCol = ss.getActiveRange().getColumn();
.
.
.
ss.getRange('State!AB5').copyTo(ss.getRange(currentRow+1, currentCol),
SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

Cant call Jquery function in if loop

my first ever question pretty sure I'm being a bit daft here, but am a beginner and would appreciate your help.
Im working on a webpage where there is a html table listing several columns of data.
When the page loads it runs a jquery script which counts the different types of "incidents" and plots them in another table which then another jquery script populates a graph.
I have a third script (javascript) which after a button is clicked, runs an if loop, which looks at the data in the first column and if it does not match the criteria then the row is deleted.
So far so good, the issue is that I want the script which populates the table for the graph to run again, but Im not sure how to call it from my if loop.
Ive put the two scripts below, basically I want to call the 1st script in the second script.
$(function () {
var NumFireAlarms = $("#incidents tr:contains('Fire Alarm')");
$("#result").html(NumFireAlarms.length + " Fire Alarm");
var firealarms = NumFireAlarms.length;
document.getElementById("no_of_incident_type").rows[1].cells[1].innerHTML = firealarms
var NumLockout = $("#incidents tr:contains('Lockout Out of Office Hours')");
$("#result").html(NumLockout.length + " Lockout Out of Office Hours");
var lockouts = NumLockout.length;
document.getElementById("no_of_incident_type").rows[2].cells[1].innerHTML = lockouts
var NumLockoutDayTime = $("#incidents tr:contains('Lockout Day Time')");
$("#result").html(NumLockout.length + " Lockout Day Time");
var lockoutsDayTime = NumLockoutDayTime.length;
document.getElementById("no_of_incident_type").rows[3].cells[1].innerHTML = lockoutsDayTime
var NumSensitiveIncident = $("#incidents tr:contains('Sensitive Incident')");
$("#result").html(NumSensitiveIncident.length + " Sensitive Incident");
var SensitiveIncident = NumSensitiveIncident.length;
document.getElementById("no_of_incident_type").rows[4].cells[1].innerHTML = SensitiveIncident
});
function filterForGraph() {
var incident_category = document.getElementById("Incident_Category").value;
var start_date = document.getElementById("start_date").value;
var end_date = document.getElementById("end_date").value;
var staff_type = document.getElementById("Job_Title").value;
var i;
var count = 0;
var table_length = document.getElementById("incidents").rows;
var TL = table_length.length;
for (i = TL - 1; i >= 1; i--)
{
var category_column = document.getElementById("incidents").rows[i].cells.item(0).innerHTML;
var date_column = document.getElementById("incidents").rows[i].cells.item(1).innerHTML;
var staff_colunm = document.getElementById("incidents").rows[i].cells.item(8).innerHTML;
if (category_column === incident_category)
{
alert("yay")
count++
}
else if (category_column !== incident_category)
{
alert("boo")
document.getElementById("incidents").deleteRow(i);
//CALL FIRST SCRIPT HERE??
}
}
}
I removed a few bits of code that did not seem to do anything, but I'm sure you can put them back. I think you might want something like this:
function updateTable(){
var elResult = document.getElementById("result");
var elNumIncidentType = document.getElementById("no_of_incident_type");
var firealarms: document.querySelectorAll("#incidents tr:contains('Fire Alarm')").length;
var lockouts: document.querySelectorAll("#incidents tr:contains('Lockout Out of Office Hours')").length;
var lockoutsDayTime: document.querySelectorAll("#incidents tr:contains('Lockout Day Time')").length;
var sensitiveIncident: document.querySelectorAll("#incidents tr:contains('Sensitive Incident')").length;
elResult.innerHTML = "";
elResult.innerHTML += "<div>" + firealarms + " Fire Alarm</div>";
elResult.innerHTML += "<div>" + lockouts + " Lockout Out of Office Hours</div>";
elResult.innerHTML += "<div>" + lockoutsDayTime + " Lockout Day Time</div>";
elResult.innerHTML += "<div>" + sensitiveIncident + " Sensitive Incident</div>";
elNumIncidentType.rows[1].cells[1].innerHTML = firealarms;
elNumIncidentType.rows[2].cells[1].innerHTML = lockouts;
elNumIncidentType.rows[3].cells[1].innerHTML = lockoutsDayTime;
elNumIncidentType.rows[4].cells[1].innerHTML = sensitiveIncident;
}
function filterForGraph() {
var elIncidents = document.getElementById("incidents");
var incident_category = document.getElementById("Incident_Category").value;
var table_length = document.getElementById("incidents").rows.length;
for (var i = table_length - 1; i >= 1; i--) {
var currentIncident = elIncidents.rows[i].cells;
var category_column = currentIncident.item(0).innerHTML;
if (category_column != incident_category) { elIncidents.deleteRow(i); }
}
updateTable();
}
$(function(){ updateTable(); });
Hi JonSG tried your code and it didnt work not sure why, but it gave me some ideas to work with and I think Ive cracked it
function Populate_Incident_No_Table() {
//previously function called updateTable
$(function () {
var NumFireAlarms = $("#incidents tr:contains('Fire Alarm')").length;
document.getElementById("no_of_incident_type").rows[1].cells[1].innerHTML = NumFireAlarms
var NumLockout = $("#incidents tr:contains('Lockout Out of Office Hours')").length;
document.getElementById("no_of_incident_type").rows[2].cells[1].innerHTML = NumLockout
var NumLockoutDayTime = $("#incidents tr:contains('Lockout Day Time')").length;
document.getElementById("no_of_incident_type").rows[3].cells[1].innerHTML = NumLockoutDayTime
var NumSensitiveIncident = $("#incidents tr:contains('Sensitive Incident')").length;
document.getElementById("no_of_incident_type").rows[4].cells[1].innerHTML = NumSensitiveIncident
});
}
function filterForGraph() {
var incident_category = document.getElementById("Incident_Category").value;
var i;
var TL = document.getElementById("incidents").rows.length;
for (i = TL - 1; i >= 1; i--)
{
var category_column = document.getElementById("incidents").rows[i].cells.item(0).innerHTML;
if (category_column !== incident_category)
{
document.getElementById("incidents").deleteRow(i);
}
}
Populate_Incident_No_Table();
drawGraph();
}
I think the issue was how I was trying to call the functions. So what I've done to achieve what I wanted (please excuse any bad terminology / phrasing).
First I tried to name the function $(function updateTable(){ this did not work when I then tried to call the function like this updateTable();
Second thing I tried was putting the updateTable() function "inside" a function and call that function. This has worked for me I dont know why.
Thanks for your help without it I would not have thought to try what I did

ActiveXObject Number of rows counter

I have this piece of code:
function GetData(evt){
var adresses = new Array();
var j = 0;
var excel = new ActiveXObject("Excel.Application");
var fil = document.getElementById("file");
var excel_file = excel.Workbooks.Open(fil.value);
var excel_sheet = excel.Worksheets(1);
for(var i=2;i<500;i++){
var morada = excel_sheet.Range("E"+ i );
var localidade = excel_sheet.Range("C"+ i );
var pais = excel_sheet.Range("A"+i);
adresses[j] = (morada + ", " + localidade + ", " + pais);
j++;
}
for(var k = 0; k<j; k++) {
codeAddress(adresses[k]);
}
}
It receives an excel file and processes the data like I want. The thing is, it is very hard coded.
For instant, in this for:
for(var i=2;i<500;i++)
I am using 500, but I would like to use the number of rows in the sheet. I have already tried a few things like rows.count and whatever and I gave some alerts to see the results, but I just can't find the one who tells me the number of rows.
Anyone know how to do it?
Try that :
excel_sheet.UsedRange.Rows.Count
Does it works ?

Google Apps Script: How to get this code run after UI is closed?

This may seem a very newbie question, but I'm stuck with it. I've got this code to show a check list in a UI and insert the paragraphs of one or more documents into another target document:
var fact_list = [ ["Kennedy Inauguration", "politics", "tZwnNdFNkNklYc3pVUzZINUV4eUtWVWFSVEf"], ["Pericles’ Funeral Oration", "politics", "sdgrewaNkNklYc3pVUzZINUV4eUtW345ufaZ"], ["The Pleasure of Books", "culture", "1234rFszdgrfYc3pVUzZINUV4eU43usacd"], ["I Am The First Accused (Nelson Mandela)", "law", "34rsgadOsidjSZIswjadi95uydnfklsdks"] ];
function showList() {
var mydoc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
var panel = app.createVerticalPanel().setId('panel');
// Store the number of items in the array (fact_list)
panel.add(app.createHidden('checkbox_total', fact_list.length));
// add 1 checkbox + 1 hidden field per item
for(var i = 0; i < fact_list.length; i++){
var checkbox = app.createCheckBox().setName('checkbox_isChecked_'+i).setText(fact_list[i][0]);
var hidden = app.createHidden('checkbox_value_'+i, fact_list[i]);
panel.add(checkbox).add(hidden);
}
var handler = app.createServerHandler('submit').addCallbackElement(panel);
panel.add(app.createButton('Submit', handler));
app.add(panel);
mydoc.show(app);
}
function submit(e){
var numberOfItems = e.parameter.checkbox_total;
var itemsSelected = [];
// for each item, if it is checked / selected, add it to itemsSelected
for(var i = 0; i < numberOfItems; i++){
if(e.parameter['checkbox_isChecked_'+i] == 'true'){
itemsSelected.push(e.parameter['checkbox_value_'+i]);
}
}
var app = UiApp.getActiveApplication();
ScriptProperties.setProperties({'theses': itemsSelected}, true);
app.close();
return app;
}
function importTheses(targetDocId, thesesId, thesesType) { // adapted from Serge insas
var targetDoc = DocumentApp.openById(targetDocId);
var targetDocParagraphs = targetDoc.getParagraphs();
var targetDocElements = targetDocParagraphs.getNumChildren();
var thesesDoc = DocumentApp.openById(thesesId);
var thesesParagraphs = thesesDoc.getParagraphs();
var thesesElements = thesesDoc.getNumChildren();
var eltargetDoc=[];
var elTheses=[];
for( var j = 0; j < targetDocElements; ++j ) {
var targetDocElement = targetDoc.getChild(j);
// Logger.log(j + " : " + type);// to see targetDoc's content
eltargetDoc[j]=targetDocElement.getText();
if(el[j]== thesesType){
for( var k = 0; k < thesesParagraphs-1; ++k ) {
var thesesElement = thesesDoc.getChild(k);
elTheses[k] = thesesDoc.getText();
targetDoc.insertParagraph(j, elTheses[k]);
}
}
}
}
But when I call these functions inside my main function, I got a red message (in my language): service not available: Docs and, after the UI from showList() is closed, nothing more happens with my code (but I wanted the main functions continues to run). I call these functions this way:
if (theses == 1){
showList();
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
}
showURL(docName, link); // Shows document name and link in UI
So, how can I fix that? How can I get the code run until the line showURL(docName, link);?
showList();
This function creates only Ui.
You are setting the script properties only in the Server Handler which executes on the click of submit button. Since then:
ScriptProperties.getProperty('theses');
will hold nothing. So you need to call these lines:
var thesesArrays = ScriptProperties.getProperty('theses');
for (var i = 0; i < thesesArrays.lenght(); i++){
var thesesId = ScriptProperties.getProperty('theses')[i][2];
var thesesType = ScriptProperties.getProperty('theses')[i][1];
importTheses(target, thesesId, thesesType);
}
Inside server handler or put them inside a method and call the method from the server Handler.

Categories

Resources