Trying to modify a script to accept an array - arrays

I found a snowing image script on the web (http://www.jqueryrain.com/?GKBtfF4Q) and I am trying to modify the script to have multiple images.
So far, I figured out that it's necessary to change:
$(document).snow({ SnowImage: "snow.gif" });
to
$(document).snow({ SnowImage:[ "snow.gif", "2.gif", "3.gif", "4.gif"] });
but I am not sure how to make the script accept an array. Any suggestions would be much appreciated! (full disclosure: I am a coding noob)
Edit: pulled the script into JSFiddle: http://jsfiddle.net/px6w1xdm/
function __ShowSnow(settings)
{
var snowsrc = settings.SnowImage;
var no = settings.Quantity;
var dx, xp, yp; // coordinate and position variables
var am, stx, sty; // amplitude and step variables
var i;
etc.

Add this in the loop (above var flake):
var randno = Math.floor(snowsrc.length*Math.random());
var randsnowsrc = snowsrc[randno];
Then change snowsrc to randsnowsrc in this line:
flake.append("<img src='" + randsnowsrc + "'>");

Related

Google Apps Script For Loop Through Array Speed

I have a simple example of a function I am working on. I am trying to loop through a column of unique item IDs. If the item ID is found in the item ID column of another sheet, it pulls adjacent attributes from the data table, and assigns them in the same row. I have a function and it works, however, this is a base example. In reality I need to do this for 1000+ rows, and much larger data sets. It is currently taking 30-60 mins to run. I believe there is a much faster way to do this with arrays and using foreach and getvalues I'm just not sure how to get started. Any help would be greatly appreciated.
function example() {
var list = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("List");
var data = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data")
var listendRow = list.getLastRow();
var dataendRow = data.getLastRow();
var dataid = data.getDataRange().getValue();
for (var i = 2; i <= listendRow; i++) {
for (var j = 2; j <= dataendRow; j++){
var idnum = [list.getRange(i, 2,listendRow).getValue()];
var id = data.getRange(j, 3).getValue();
var name = data.getRange(j, 4).getValue();
var weight = data.getRange(j, 5).getValue();
if (idnum == id){
list.getRange(i, 3).setValue(name);
list.getRange(i, 4).setValue(weight);
}
}
}
}
Here is the link to the sheet:
https://docs.google.com/spreadsheets/d/1PPZKRXhiAAfFG1d-CU02MV_CSrqbdsCsyo_QADz5yiA/edit?usp=sharing
I believe your goal is as follows.
Your script works fine. Under this condition, you want to reduce the process cost of your script.
Modification points:
When I saw your sample Spreadsheet, V8 runtime is not used. Please enable V8 runtime. When V8 runtime is used, the process cost of the script can be reduced.
In your script, getValue and setValue are used in a loop. In this case, the process cost becomes high. Ref
SpreadsheetApp.getActiveSpreadsheet() can be declared one time.
In order to reduce the process cost of your script, how about the following modification?
Modified script:
Before you run this script, please enable V8 runtime.
function example2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var list = ss.getSheetByName("List");
var data = ss.getSheetByName("Data");
var obj = data.getRange("C2:E" + data.getLastRow()).getValues().reduce((o, [a, ...b]) => (o[a] = b, o), {});
var range = list.getRange("B2:B" + list.getLastRow());
var values = range.getValues().map(([b]) => obj[b] || [null, null]);
range.offset(0, 1, values.length, 2).setValues(values);
}
When this script is run, the values are retrieved from "Data" sheet and create an object for searching the ID. And, the values are retrieved from "List" sheet and an array for putting to the sheet is created. And also, the array is put to "List" sheet.
Note:
When you try to use this script without enabling V8 runtime, an error like Syntax error occurs. Please be careful about this.
This modified script is for your sample Spreadsheet. If your actual Spreadsheet is differnt structure from your provided sample one, this modified script might not be able to be used. Please be careful about this.
If you cannot use V8 runtime, please test the following modified script.
function example2b() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var list = ss.getSheetByName("List");
var data = ss.getSheetByName("Data");
var obj = data.getRange("C2:E" + data.getLastRow()).getValues()
.reduce(function (o, [a, b, c]) {
o[a] = [b, c];
return o
}, {});
var range = list.getRange("B2:B" + list.getLastRow());
var values = range.getValues().map(function ([b]) { return obj[b] || [null, null] });
range.offset(0, 1, values.length, 2).setValues(values);
}
References:
getValues()
setValues(values)
reduce()
map()

Loop over a couple of columns

very beginning with Google sheet.
I managed to create the function I need:
function happy() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.getRange('C5').activate();
spreadsheet.getCurrentCell().setFormula('=G4');
spreadsheet.getRange('H4').activate();
var current_e15=spreadsheet.getRange('E15').getValue();
spreadsheet.getCurrentCell().setValue(current_e15);
spreadsheet.getRange('C5').activate();
spreadsheet.getCurrentCell().setFormula('=G5');
spreadsheet.getRange('H5').activate();
var current_e15=spreadsheet.getRange('E15').getValue();
spreadsheet.getCurrentCell().setValue(current_e15);
...
...
...
The function is reading from the G[i] column, assign it to C5, read the result produced by the new value in E15 and put that value in the cell H[i].
Obviously this can be done over a loop over i instead of copy past this same block and changing G4 by G5 and H4 by H5 etc..
I just don't know how to say it in this langage.
I tried this that is obviously not working.
function happyloop() {
var spreadsheet = SpreadsheetApp.getActive();
var CellsG = spreadsheet.getRange('G4:G15');
var CellsH = spreadsheet.getRange('H4:H15');
for (var i = 0; i < CellsG.length; i++) {
spreadsheet.getRange('C5').activate();
spreadsheet.getCurrentCell().setFormula('=CellsG[i]');
spreadsheet.getRange(CellsH[i]).activate();
var current_e15=spreadsheet.getRange('E15').getValue();
spreadsheet.getCurrentCell().setValue(current_e15);
}
};
I'd be glad to get help with how to properly this function in google sheet language.
Thanks if you can help :)
I finally get to this that is working.
If there is a more elegant way to do it please correct me.
Thank you
function happyloop() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
for (var i = 4; i < 16; i++) {
sheet.getRange('C5').activate();
var current_Gi=sheet.getRange(i,7).getValue();
sheet.getCurrentCell().setValue(current_Gi);
sheet.getRange(i,8).activate();
var current_e15=sheet.getRange('E15').getValue();
sheet.getCurrentCell().setValue(current_e15);
}
}
I took your working answer and made minor changes in it to achieve a more elegant way as you requested. The original scripts runs in 4.5 seconds, while this modified version runs in 2.5 seconds. This is the optimized version:
function happyLoop() {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getSheets()[0];
var C5 = sheet.getRange('C5');
var E15 = sheet.getRange('E15').getValue();
for (var i = 4; i < 16; i++) {
C5.setValue(sheet.getRange(i, 7).getValue());
sheet.getRange(i, 8).setValue(E15);
}
}
I changed the variable names to make it clearer to me, but that isn't a speed improvement. To achieve more speed I took out of the for loop everything that doesn't depend on the i iterator. Notice also how I nested each method call.
To improve this code even more I'll have to understand your original scenario. A big possible improvement is to use the .setValues just once in the full code, because it is the slowest method and here it gets called in every iteration. Finally, I want to share the Apps Script best practices with you. Please, don't hesitate to ask me for deeper clarification.

how to change filename of exported SSRS report

I have created SSRS report and want to change the name of file with adding Date to it. I really appreciate your help.
Already tried https://reportsyouneed.com/ssrs-adding-date-to-exported-filenames/ solution and it doesn't work.
An easy alternative might be
An alternative approach to creating unique files for every delivery is to include a timestamp in the file name. To do this, add the #timestamp variable to the file name (for example, CompanySales#timestamp). With this approach, the file name is unique by definition, so it will never be overwritten.
See https://learn.microsoft.com/en-us/sql/reporting-services/subscriptions/file-share-delivery-in-reporting-services?view=sql-server-ver15
I got a perfect solution for this Issue.
This link works (very well) only if there is no parameter required before export.
Code in this link try to get the file name when you click on the file, means when download not ready and report looking for initial inputs.
But my file has date parameters in the beginning to input.
So I modify the code to wait till download is available and added to the end of "C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportManager\js\ReportingServices.js" file
function ModifyExportFileName(){
var rv=null;
var r= null;
var today =new Date();
var day= ("0" + today.getDate()).slice(-2);
var month = ("0"+ (today.getMonth() + 1)).slice(-2);
var year = ("0"+ today.getFullYear()).slice(-2);
var text= "DD";
try{
rv=this.$find("ctl31");
r=rv._getInternalViewer();
var url=r.ExportUrlBase;
var i = url.indexOf("FileName=");
}
catch(err)
{
//console.log(err);
setTimeout(ModifyExportFileName,2000);
return;
}
if(r==null)
{
setTimeout(ModifyExportFileName,2000);
return;
}
else
{
var url=r.ExportUrlBase;
var i = url.indexOf("FileName=");
var j = url.indexOf("&",i+1);
var oldFileName= url.substring(i+9,j);
var filename=text.concat(year,month,day)
r.ExportUrlBase= url.substring(0,i) + 'FileName=' + filename+ url.substring(j);
}
//console.log(filename);
setTimeout(ModifyExportFileName,2000);
}
ModifyExportFileName();
I need date as a filename so date is added as "filename". you can change it as required

Google Apps Script Replace and update cell within a range

I have a Google spreadsheet that I'm trying to remove the word "woo" within a range of cells
So far I've managed to loop through the results and log the results, however I haven't figured how to update that information in the spreadsheet itself.
Any guidance would be welcomed
Thank you
function myFunction () {
var ss = SpreadsheetApp.getActiveSheet().getRange('B:B')
var data = ss.getValues();
for (var i = 0; i < data.length; i++) {
var text = data[i].toString();
var finaltext = text.replace(/woo/g, "");
data[i] = finaltext;
Logger.log(data[i]);
}
}
Use setValues()
Notes:
Usually ss is used as a shorthand for spreadsheet, as it's used on the code for a range it's better to use range as a variable name.
setValues() returns a 2D array, so data[i] returns an array of row values rather than a cell value. To get/set cell values, use data[i][0] notation.
Considering the above replace
var ss = SpreadsheetApp.getActiveSheet().getRange('B:B')
by
var range = SpreadsheetApp.getActiveSheet().getRange('B:B')
then add the following line after the for block.
range.setValues(data);
Regarding text var declaration, replace
var text = data[i].toString();
to
var text = data[i][0].toString();
Using open ended references like B:B could lead to problems. To avoid them be sure to keep the sheet rows at minimum or better instead of using an open ended reference use something like B1:B10.

image array and .src - image not changing

I have created an array which is being used to store a series of .gif images and I'm just trying to test everything out by using document.getElementById to change the .src value but when I change it and load the page the image stays the same as it was before.
function setImage()
{
var images = new Array();
images[0] = anemone.gif;
images[1] = ball.gif;
images[2] = crab.gif;
images[3] = fish2.gif;
images[4] = gull.gif;
images[5] = jellyfish.gif;
images[6] = moon.gif;
images[7] = sail.gif;
images[8] = shell.gif;
images[9] = snail.gif;
images[10] = sun.gif;
images[11] = sunnies.gif;
images[12] = whale.gif;
var slots = new Array();
slots[0] = document.getElementById("slot" + 0);
slots[1] = document.getElementById("slot" + 1);
slots[2] = document.getElementById("slot" + 2);
slots[0].src = "snail.gif";
document.getElementById('slot0').src = images[0];
alert(images.length);
}
I can't understand why the image wont change, but I know it has to be something very simple. I've been wasting hours trying to get this one thing to change but nothing works. can anyone please point out the error of my ways?
There are a couple of issues with your code:
Your filenames need to be Strings, so they'll have to be quoted (also you can simplify the Array creation):
var images = ['anemone.gif', 'ball.gif', 'crab.gif', 'fish2.gif', 'gull.gif', 'jellyfish.gif', 'moon.gif', 'sail.gif', 'shell.gif', 'snail.gif', 'sun.gif', 'sunnies.gif', 'whale.gif'];
Also make sure you are getting your slot-elements right, quote all the attributes like:
<img id="slot0" class="slot" src="crab.gif" width="120" height="80">
When you create the slots-Array you can do it like this (no need to concat the ID string):
var slots = [document.getElementById('slot0'), document.getElementById('slot1'), document.getElementById('slot2')];
Finally make sure you call your function when the document has loaded / the DOM is ready. If you don't want to use a framework like jQuery your easiest bet is probably still using window.onload:
window.onload = setImage; //note that the parens are missing as you want to refer to the function instead of executing it
Further reading on Arrays, window.onload and DOMReady:
https://developer.mozilla.org/de/docs/DOM/window.onload
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
javascript domready?

Resources