Concatenation of single quote marks Google Script - javascript

I have three columns of data
selector label option list
time you personally have been engaged with uscan label_1 Arts
time you personally have been engaged with uscan label_2 Children’s Issues
time you personally have been engaged with uscan label_3 Coaching
time you personally have been engaged with uscan label_4 Community Development
time you personally have been engaged with uscan label_5 Conflict
time you personally have been engaged with uscan label_6 Consulting
I am trying to concatenate these columns so that in the 4th column I get
option {
label: "Label_1;
selector: ["time you personally have been engaged with uscan"="Arts"];
}
option {
label: "Label_2;
selector: ["time you personally have been engaged with uscan"="Children’s Issues"];
}
etc
My attempt
result[i] = [""option {label:""" + values[i][0] + "";" + "selector: [" + values[i][0] + ""=" + + values[i][1] + ""];}"];
Foiled by all the single quotes that are required
Thank you
GS
function OptionsList() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("OptionList");
var lr = sheet.getLastRow();
var values = sheet.getRange(2, 1, lr,3).getValues();
var result = [];
//Add items to results
for(var i=0; i<lr; i++){
result[i] = [""option {label:""" + values[i][0] + "";" + "selector: [" + values[i][0] + ""=" + + values[i][1] + ""];}"];
}
//Post back to column 4 starting on row 2
sheet.getRange(2, 4, lr, 1).setValues(result);
}

How about this modification?
Modification points :
About result[i]
" was escaped like \".
Line break was added like \n.
Remove the empty cells by filter().
Modified script :
function OptionsList() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("OptionList");
var lr = sheet.getLastRow();
var values = sheet.getRange(2, 1, lr, 3).getValues();
values = values.filter(function(e){return e[0] && e[1] && e[2]}); // Added
var result = [];
//Add items to results
for(var i=0; i<values.length; i++){ // Modified
result[i] = ["option {\nlabel: \"" + values[i][1] + ";\n" + "selector: [\"" + values[i][0] + "\"=\"" + values[i][2] + "\"];\n}"]; // Modified
}
//Post back to column 4 starting on row 2
sheet.getRange(2, 4, result.length, 1).setValues(result); // Modified
}
Note :
For example, is it required to be " after "Label_1 of label: "Label_1;? If you want, please modify as follows.
+ values[i][1] + "\";\n"
Reference :
filter()
If I misunderstand your question, please tell me. I would like to modify it.

Related

Output in GS accurate but multiple Quote marks being added to output when copy-pasted to a any text editor

I am using a Script by #Tanaike
Concatenation of single quote marks Google Script
The output in Google sheets look correct but when I copy and paste the output into any other text editor there are multiple added quote marks
How do I keep this addition of quote marks from happening, I cannot see in the code anything that is causing this other than possible the use of \n
Thanks
Here is a google sheet with Script
https://docs.google.com/spreadsheets/d/16MXnuMzjQErH3fxxmuwAXqmJ-6XB_HbwrnHQhS1VeyU/edit?usp=sharing
Image of the column from google Sheet
Options List when pasted into a text editor
"option {
label: ""label_1"";
selector: [""time you personally have been engaged with uscan""=""Arts""];
}"
"option {
label: ""label_2"";
selector: [""time you personally have been engaged with uscan""=""Children’s
Issues""];
}"
"option {
label: ""label_3"";
selector: [""time you personally have been engaged with uscan""=""Coaching""];
}"
etc..
GS
function OptionsList() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("OptionList");
var lr = sheet.getLastRow();
var values = sheet.getRange(2, 1, lr, 3).getValues();
values = values.filter(function(e){return e[0] && e[1] && e[2]});
var result = [];
//Add items to results
for(var i=0; i<values.length; i++){ // Modified
result[i] = ["option {\nlabel: \"" + values[i][1] + "\";\n" + "selector: [\"" + values[i][0] + "\"=\"" + values[i][2] + "\"];\n}"]; // Modified
}
//Post back to column 4 starting on row 2
sheet.getRange(2, 4, result.length, 1).clear
sheet.getRange(2, 4, result.length, 1).setValues(result);
}
This will output your output list to a single cell E2 so you only have to copy from the formula bar once
I think I got your ranges correct
function OptionsListToCell() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("OptionList");
var lr = sheet.getLastRow();
var values = sheet.getRange(2, 4, lr, 4).getValues();
values = values.filter(function(e){return e[0]});
var temp = ""
//Add items to temp
for(var i=0; i<values.length; i++){ // Modified
temp = temp + [values[i] + "\n"];
}
var cell = sheet.getRange("E2");
//Clear cell
cell.activate();
sheet.getActiveRangeList().clear({contentsOnly: true, skipFilteredRows: true});
//Write value to cell
cell.setValue(temp);
}
I used Jersy One solution to add the output to an HTML window
This is the solution I am using but I am giving credit to Jersy One
function OptionsList_POPUP() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Opt");
var lr = sheet.getLastRow();
var values = sheet.getRange(2, 1, lr, 3).getValues();
values = values.filter(function(e){return e[0] && e[1] && e[2]});
var result = [];
//Add items to results
for(var i=0; i<values.length; i++){ // Modified
result[i] = ["option {<br />label: \"" + values[i][1] + "\";<br />" + "selector: [\"" + values[i][0] + "\"=\"" + values[i][2] + "\"];<br />}<br />"];
}
var temp = ""
for(var i=0; i<result.length; i++){ // Modified
temp = temp + [result[i] + "\n"];
}
//Output to Html
var htmlOutput = HtmlService
.createHtmlOutput(temp)
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(510)
.setHeight(500);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Opt');
//Post back to column 4 starting on row 2
//sheet.getRange(2, 4, result.length, 1).clear
//sheet.getRange(2, 4, result.length, 1).setValues(result);
}

JavaScript Looping Variables on Left Side of Equal Sign

I'm looping through results and writing them out to html.
I want to increment the number 1 on the lest side of the equal sign - the binding -
A_Inside_Bus_1_div, A_Inside_Bus_2_div, A_Inside_Bus_3_div etc..
How should I go about that?
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_1_div.innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_1_Comments_div.innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Do it like this:
var A_Inside_Bus_div = [];
var A_Inside_Bus_Comments_div = [];
Before you continue the rest, like editing .innerHTML, you need to create those objects. Only after that you can do something like:
for (var i = 0; i <= 4; i++) {
A_Inside_Bus_div[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
A_Inside_Bus_Comments_div[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is just an idea how you "should go" about that, as you said.
If those variables are actually the IDs of DIVsm and you're depending on the fact that IDs are turned into global varables, you can use document.getElementById() to access them.
for (var i = 0; i <= 4; i++) {
document.getElementById('A_Inside_Bus_' + (i+1) + '_div').innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
document.getElementById('A_Inside_Bus_' + (i+1) + '_Comments_div').innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
Don't do this. Trying to make variable names to do what you're trying to do just leads to needlessly messy code down the road.
Stick all your elements into arrays:
var elems = [
A_Inside_Bus_1_div
A_Inside_Bus_2_div
...
];
var comments = [
A_Inside_Bus_1_Comments_div
A_Inside_Bus_2_Comments_div
...
];
Then just index the arrays:
for (var i = 0; i <= 4; i++) {
elems[i].innerText = i + ". " + snapshot.child("0/A_Inside_Bus " + i).val();
comments[i].innerText = snapshot.child("0/A_Inside_Bus " + i + " Comments").val();
}
This is an example of how you could do it with your current setup. Note though, it could be cleaned up. If each element of the elems array always has a partner in comments, it would make more sense to group them together in an object, and only have 1 array.
Also note that populating the arrays in a loop makes more sense. I just hardcoded the arrays here for the sake of brevity. I'm not sure how you're creating the elements originally. They should probably be created and put straight into the array instead of naming them and adding them later.
There are a couple ways you could go about doing this, but they tend to involve some pretty bad habits, like using eval or attaching variables to the global object so you can access them with a string:
var a = 1;
window['a']; //1
But there are better alternatives, the most common is probably storing them in equal-length arrays:
var divs = [div1, div2, div3];
var items = ['cat', 'dog', 'fish'];
items.forEach(function(element, index){
divs[index].innerText = items[i];
});
You could also look at building out a single array of objects:
var objects = [{div: div1, item: 'cat'}, {div: div2, item: 'dog'}, {div: div3, item: 'fish'}];
for object in objects {
object.div.innerText = object.item;
}

Code runs too slow

I'm trying to run a code that copies values from one spreadsheet and copies them to another, however the order is not the same(hard to make it an array). In some cases it also prints 'Unknown' and in some it also formats some cells. However it makes way to much time to finish. Is there a way to improve it?
function move() {
var sss = SpreadsheetApp.openById('xx');
var sourceSheet = sss.getSheetByName('CJ_Products');
var destinationSheet = sss.getSheetByName('Product2');
var lastRow = sourceSheet.getRange(sourceSheet.getLastRow(), 1,1,1).getRow()
var i = 1
while(i<=lastRow){
var rowInt = destinationSheet.getRange(destinationSheet.getLastRow()+1, 4,1,1).getRow() //get row number
destinationSheet.getRange('A' + rowInt).setFormula('=Month(D'+rowInt+')')
destinationSheet.getRange('B' + rowInt).setFormula('=Weekday(D'+rowInt+')')
destinationSheet.getRange('C' + rowInt).setFormula('=Day(D'+rowInt+')')
destinationSheet.getRange('D' + rowInt).setValue(sourceSheet.getRange('A'+i).getValues()) //move from the source to destination
destinationSheet.getRange('E' + rowInt+':F'+rowInt).setValue('Unknown') //set to Unknown
destinationSheet.getRange('H' + rowInt+':J'+rowInt).setValue('Unknown')
destinationSheet.getRange('J' + rowInt).setValue('CJ')
destinationSheet.getRange('K' + rowInt).setValue(sourceSheet.getRange('B' +i).getValues())
destinationSheet.getRange('L' + rowInt).setValue(sourceSheet.getRange('E' +i).getValues())
destinationSheet.getRange('M' + rowInt).setValue(sourceSheet.getRange('F' +i).getValues())
destinationSheet.getRange('N' + rowInt).setValue(sourceSheet.getRange('J' +i).getValues())
destinationSheet.getRange('S' + rowInt).setValue(sourceSheet.getRange('G' +i).getValues())
destinationSheet.getRange('T' + rowInt).setValue(sourceSheet.getRange('H' +i).getValues())
destinationSheet.getRange('O' + rowInt).setFormula('=S'+rowInt+'*GOOGLEFINANCE("currency:EURUSD")')
destinationSheet.getRange('P' + rowInt).setFormula('=T'+rowInt+'*GOOGLEFINANCE("currency:EURUSD")')
destinationSheet.getRange('Q' + rowInt).setFormula('=P'+rowInt+'/T'+rowInt)
destinationSheet.getRange('O' + rowInt+':Q'+rowInt).setNumberFormat('0.00$')
i = i+1
}
}
The code should be optimised:
You do all calculations in a loop
You use getValue and setValue instead of faster functions getValues, setValues
Instead of this concentrate your loop to do a single call:
var rowInt = destinationSheet.getRange(destinationSheet.getLastRow()+1, 4,1,1).getRow()
try to figure out how to find the first row outside the loop and then increment this value:
var rowStart = destinationSheet.getRange(destinationSheet.getLastRow()+1, 4,1,1).getRow();
for (var row = rowStart; row <= lastRow, row++)
{
// some code...
}
Use arrays and then copy the value from arrays into ranges:
var formulas = [];
for (var row = rowStart; row <= lastRow, row++)
{
// some code...
formulas.push(['=Month(D'+ row + ')']);
}
var rangeToPateFormulas = destinationSheet.getRange('A' + rowStart + ':A' + lastRow);
rangeToPateFormulas.setFormulas(formulas);
And so on. See more info:
https://developers.google.com/apps-script/reference/spreadsheet/range
https://developers.google.com/apps-script/guides/support/best-practices

insert space after and before in string at specific index multiple times javascript p5.js

str = '12512';
indexes = [0, 3]
lngth = 2;
result should be: str = ' 12 5 12 '
How do I add spaces there, knowing the character length, and index at which they are located?
I tried to do it with
for (i=0; i<indexes.length; i++){
var spb = [str.slice(0, indexes[i]), " ", str.slice(indexes[i])].join('');
var spa = [str.slice(0, indexes[i]+lngth), " ", str.slice(indexes[i]+lngth)].join('');
console.log(spb);
console.log(spa);
}
It seems to work, though the output is like this, cause i needed to search for each index:
spa 12 512
spb 12512
spa 12512
spb 125 12
How to make output like this ' 12 5 12 '
You need to iterate backwards
for (i = indexes.length - 1; i >= 0; i--) {
str = str.slice(0, indexes[i] + lngth) + " " + str.slice(indexes[i] + lngth);
str = str.slice(0, indexes[i]) + " " + str.slice(indexes[i]);
}
Why?
Otherwise the indices gets mixed up, for example after inserting one space all following indices are shifted by one. Iterating backwards avoids this.

Return values from rows in a 2d array with a specific value - list results in HTML inside Google Script

I am trying to list three values from each row that contains a specific value in the "Status" column within coded HTML inside a Google Script function. When I run the sendDailyDigest function below, it times out. I am assuming a have some type of error in the for loop inside the html message variable, but I can't seem to figure it out.
I am relatively new to scripting and would be grateful for someone pointing me in the right direction.
Thank you!
function sendDailyDigest() {
var ss = SpreadsheetApp.openById(PRIMARY_SPREADSHEET_ID);
var sheet = ss.getSheets()[0];
var lastRow = sheet.getLastRow();
var data = getRowsData(sheet);
// Count how many requests are awaiting approval
var numSubmitted = 0;
for (var i = 2; i < lastRow; i++) {
if (sheet.getRange(i, getColIndexByName("Status")).getValue() == "SUBMITTED") {
numSubmitted++;
}
}
var message = "<HTML><BODY>"
+ "<P>" + "The following requests await your approval."
+ "<P>" + "\xa0"
+ "<P>" + "<table><tr><td><b>Request ID</b></td><td><b>Requested By</b></td><td><b>Start Date</b></td></tr>"
// List each request pending approval
for (var j = 0; j < data.length; ++j) {
var row = data[j];
row.rowNumber = j + 2;
if (row.status == "SUBMITTED") {
"<tr><td>" + row.rowNumber + "</td><td>" + row.username + "</td><td>" + row.firstDay + "</td></tr>"
}
}
+ "</table>"
+ "</HTML></BODY>";
GmailApp.sendEmail('username#domain.com', numSubmitted + 'Leave Requests Awaiting Approval', '', {htmlBody: message});
}
function getColIndexByName(colName) {
var ss = SpreadsheetApp.openById(PRIMARY_SPREADSHEET_ID);
var sheet = ss.getSheets()[0];
var numColumns = sheet.getLastColumn();
var row = sheet.getRange(1, 1, 1, numColumns).getValues();
for (i in row[0]) {
var name = row[0][i];
if (name == colName) {
return parseInt(i) + 1;
}
}
return -1;
}
/////////////////////////////////////////////////////////////////////////////////
// Code reused from Reading Spreadsheet Data using JavaScript Objects tutorial //
/////////////////////////////////////////////////////////////////////////////////
// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
// - sheet: the sheet object that contains the data to be processed
// - range: the exact range of cells where the data is stored
// This argument is optional and it defaults to all the cells except those in the first row
// or all the cells below columnHeadersRowIndex (if defined).
// - columnHeadersRowIndex: specifies the row number where the column names are stored.
// This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData(sheet, range, columnHeadersRowIndex) {
// etc.
The most obvious error I see right now is that you are using the .getLastRow() method, which always times out, even if your code is functional. Instead, try using .getMaxRows(). I used to use the .getLastRow() method at first, but then realized that it doesn't work for some reason. When I used the .getMaxRows() method, the for loop did not time out on me.

Categories

Resources