Value not returning right - arrays

I am having a issue getting my code to return the correct value.
I am building spreadsheet to help me with cooking for a video game I play. I am trying to track the amount of all the ingredients I have for cooking. I want to be able to update the amount I have from a dashboard rather than go scroll through the list to find each ingredient individually.
Here is what I have setup so far.
I have a page called Updater where I am selecting from a drop down a certain ingredient(cell A2). Next to that drop down is cell for me to enter a new amount of that ingredient that I have(cell B2).
The second page is called Ingredients. This has a 2 columns. Column 1 is a list of the ingredients and in column 2 is the number I currently have on hand.
The script I have written so far can find me the row number, but when I try to get the current amount I have for the ingredient to make sure the code is working, it doesnt return anything in the log.
There is my code
function finalTest(){
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var fs = spreadsheet.getSheetByName("Ingredients");
var ts = spreadsheet.getSheetByName("Updater");
var data = fs.getDataRange().getValues();
var luItem = ts.getRange("A2").getValue();
var newAmt = ts.getRange("B2").getValue();
var rn = 0;
Logger.log(rn);
Logger.log(newAmt);
Logger.log(data);
Logger.log(luItem);
for(var i = 0; i<data.length;i++){
if(data[i][0] == luItem){ //[1] because column B
Logger.log((i+1))
return i+1;
}
}
rn = i;
Logger.log(rn);
var fsr = fs.getRange(rn,2).getValue();
Logger.log(fsr);
}
Right now the logger will return up to where it logs "i", but will not return the new rn or fsr values.
Any help would be greatly appreciated.

A function immediately returns on the return statement. So you can only return one value there - or an object with multiple values inside.
As it looks that you just want to log data out, you would have to do that inside the if, but before the return to reach:
for (var i = 0; i < data.length; i++) {
if (data[i][0] == luItem) {
// first do all the logging
Logger.log(i + 1);
rn = i;
Logger.log(rn);
var fsr = fs.getRange(rn,2).getValue();
Logger.log(fsr);
// and then return from the function
return i + 1;
}
// what should be returned here??
}
Please also note that you should return a value or handle it somehow else when the loop runs through and the condition is never met.
If the return value then is still i + 1, you could make the if-condition instead part of the stop condition of the loop:
var i = 0;
for (; (i < data.length) && (data[i][0] == luItem); i++);
// no loop body needed here!
// do the logging outside the loop
Logger.log(i + 1);
rn = i;
Logger.log(rn);
var fsr = fs.getRange(rn,2).getValue();
Logger.log(fsr);
// and then return from the function
return i + 1;

Related

Replace user in a protected range by script (Google Sheet)

here my specific case:
I have some range protected in google sheets
I need to replace some specific Editor if is editor of those range (var Editor2Replace and Editor2Add are emails)
Logically I tried to, for each sheet:
Cycle (FOR) of all the protected range (counter p)
For each protected range catch current editors and have it in array
Of the Editors read the email ==> this is what generate the mistake
Cycle (FOR) all the editors looking if someone of those is == Editor2Replace (that
is an email)
Here the code, but something is logically wrong, I doubt in what is an array and what not..
var Protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var p = 0; p < Protections.length; p++) {
var Protection_Desc = Protections[p].getDescription();
var Protection_Editors = [];
var Protection_Editors = [Protections[p].getEditors()];
for (var r = 0; r < Protection_Editors.length; r++){
var Protection_Email[r] = [Protection_Editors[r].getEmail()];
if (Protection_Idontknow == Editor2Replace){
Protections[p].addEditor = Editor2Add;
Protections[p].removeEditor = Editor2Replace;
var Protection_Range = Protections[p].getRange();
var Protection_Row = Protection_Range.getRow();
var Owner1 = sheet.getRange(Protection_Row,5).getValue();
var Owner2 = sheet.getRange(Protection_Row,6).getValue();
if (Owner1 == Editor2Replace){
sheet.getRange(Protection_Row,5).setValue(Editor2Add);
}
if (Owner2 == Editor2Replace){
sheet.getRange(Protection_Row,6).setValue(Editor2Add);
}
}
}
Many thanks for hepling
There were a lot of issues in your script and I will enumerate them one by one. Also, I was able to replace a user in the protected sheet by modifying your script.
Issues:
Duplicate declaration
var Protection_Editors = [];
var Protection_Editors = [Protections[p].getEditors()];
Storing the returned value (array) in another array (which should not be done in your issue, it doesn't help you with anything)
var Protection_Editors = [Protections[p].getEditors()];
...
var Protection_Email[r] = [Protection_Editors[r].getEmail()];
Newly declared variable having an index (which I don't understand why)
var Protection_Email[r] = [Protection_Editors[r].getEmail()];
Variable not declared Protection_Idontknow
if (Protection_Idontknow == Editor2Replace){
Incorrect usage of methods addEditor and removeEditor
Protections[p].addEditor = Editor2Add;
Protections[p].removeEditor = Editor2Replace;
Below code should fix those issues (added some comments):
Code:
var Protections = sheet.getProtections(SpreadsheetApp.ProtectionType.RANGE);
for (var p = 0; p < Protections.length; p++) {
var Protection_Desc = Protections[p].getDescription();
// returned value of getEditors is already an array, return as is
var Protection_Editors = Protections[p].getEditors();
for (var r = 0; r < Protection_Editors.length; r++) {
var Protection_Email = Protection_Editors[r].getEmail();
// compare current email with the one you want to replace
if (Protection_Email == Editor2Replace) {
// add new and remove the one to replace
Protections[p].addEditor(Editor2Add);
Protections[p].removeEditor(Editor2Replace);
}
}
}
Note:
I have removed anything that were unrelated to the replacement of editors.
Reference:
Protection

Can I create array based on field names that exist in PDF?

I am trying to count the number of a specific field which is not empty and would like to use an array to store the field names based on whether they exist in the PDF form.
My code looks like this so far and it works as long as the field names in the array exists, if that field does not exist then the code breaks.
The SiteDeficiency_DeficiencyNumber_# could have 0 instances or anywhere up to 50 instances or so.
I did find that you can check if a name exists with this code but I can't seem to get it to work.
Any help is appreciated. I have coded simple things but maybe this is just too advanced for me.
This is what my code looks like so far:
var aFields = new Array("SiteDeficiency_DeficiencyNumber_1",
"SiteDeficiency_DeficiencyNumber_2",
"SiteDeficiency_DeficiencyNumber_3",
"SiteDeficiency_DeficiencyNumber_4",
"SiteDeficiency_DeficiencyNumber_5",
"SiteDeficiency_DeficiencyNumber_6");
var count = 0;
for (i = 0; i < aFields.length; i++) {
if (this.getField(aFields[i]).valueAsString != "") count++
}
event.value = count;
I tried incorporating this too
if(document.forms[0].SiteDeficiency_DeficiencyNumber_1)
{
...
}
I would really like the array at the beginning to populate with only the SiteDeficiency_DeficiencyNumber_# fields that exist and then have the array looped through to count which fields are not blank.
I tried doing this but still does not work.
var aFields = [];
for(i = 1; i <101; i++)
{
if(document.forms[0].("SiteDeficiency_DeficiencyNumber_"+i).valueAsString.length > 0) //Checks if field exists
{
aFields.push("SiteDeficiency_DeficiencyNumber_"+i); //adds field name to array
}
}
var count = 0;
for (a = 0; a < aFields.length; a++) {
if (this.getField(aFields[a]).valueAsString != "") count++ //counts field if not empty
}
event.value = count;
Try this code:
var count = 0;
for(var i = 0; i < this.numFields; i++)
{
if (this.getNthFieldName(i).indexOf("SiteDeficiency_DeficiencyNumber")!= -1){
if (this.getField(this.getNthFieldName(i)).valueAsString != "")
count = count +1
}
}
event.value = count;
The first if statement will check if name of the field contain string SiteDeficiency_DeficiencyNumber. If SiteDeficiency_DeficiencyNumber is present in the field naem then it will check the field value and increment accordingly.
Don't forget to upvote! let me know if you need anything else

Detecting and using collision detection between two different arrays to remove instances of them

I'm currently creating a small flash game using ActionScript and after receiving help for another issue I had on here, I've encountered another one when moving onto a different part of it.
This is the code I currently have:
var asteroidSpeed = 5;
var soundExplosion:Sound = new ExplosionSound();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
var newLaser:Array = new Array();
function onKDown(e:KeyboardEvent):void {
keys[e.keyCode] = true;
if (e.keyCode == 32) {
/*laser.x = player.x + player.width/2 - laser.width/2;
laser.y = player.y;
addChild(laser);*/
for (var count=0; count < 4; count++) {
newLaser[count] = new shipLaser();
newLaser[count].x = player.x + player.width/2 - newLaser.width/2;
newLaser[count].y = player.y;
addChild(newLaser[count]);
}
}
}
var spawnTimer:Timer = new Timer(3000); //timer will tick every 3 seconds
spawnTimer.addEventListener(TimerEvent.TIMER, spawn, false, 0, true); //let's run the spawn function every timer tick
spawnTimer.start();
var spawnPoints:Array = [0,100,200,300,400,500,550]; //your list of spawn x locations
var spawnAmount:int = 4; //how many asteroids to have on the screen at once (you could increase this over time to make it more difficult)
var asteroids:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your asteroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)
spawn(); // calling it immediately
//calling this will spawn as many new asteroids as are needed to reach the given amount
function spawn(e:Event = null):void {
if(asteroids.length >= spawnAmount) return; //let's not bother running any of the code below if no new asteroids are needed
spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints
var spawnIndex:int = 0;
var a:asteroidOne; //var to hold the asteroid every loop
while (asteroids.length < spawnAmount) {
a = new asteroidOne();
a.x = spawnPoints[spawnIndex];
spawnIndex++; //incriment the spawn index
if (spawnIndex >= spawnPoints.length) spawnIndex = 0; //if the index is out of range of the amount of items in the array, go back to the start
a.y = -50;
asteroids.push(a); //add it to the array/vector
addChild(a); //add it to the display
}
}
player.addEventListener(Event.ENTER_FRAME, obstacleMove);
function obstacleMove(evt:Event):void {
for (var i:int = 0; i < asteroids.length;i++) {
asteroids[i].y += asteroidSpeed;
if (asteroids[i].y > stage.stageHeight || asteroids[i].x > stage.stageWidth || asteroids[i].x < -asteroids[i].width || asteroids[i].y < -asteroids[i].height) {
//object is out of the bounds of the stage, let's remove it
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
continue; //move on to the next iteration in the for loop
}
if (player.hitTestObject(asteroids[i])) {
trace("HIT");
removeChild(asteroids[i]);
asteroids.splice(i,1);
removeChild(player);
// will add end-game trigger here soon.
}
}
}
function randomizeArray(a:*, b:*):int {
return (Math.random() < .5 ) ? 1 : -1;
}
player.addEventListener(Event.ENTER_FRAME, laserCollision);
function laserCollision(evt:Event):void {
for (var i in newLaser) {
for (var a in asteroids) {
if (asteroids[a].hitTestObject(newLaser[i])) {
trace("BOOM!");
var soundExplosion:Sound = new ExplosionSound();
var channel1:SoundChannel = soundExplosion.play();
removeChild(newLaser[i]);
removeChild(asteroids[a]);
}
}
}
}
addEventListener(Event.ENTER_FRAME, laserEnter);
function laserEnter(event:Event):void {
for (var i in newLaser) {
newLaser[i].y -= laserSpeed;
// Moves the laser up the screen
if(newLaser[i].y == 0) {
removeChild(newLaser[i]);
}
}
}
What I want to do is when an instance from the newLaser array collides with an instance of the asteroids array, to remove both from the scene / indexes (but only the two that collided and not all of the ones on the scene).
Currently, when a laser hits an asteroid, it removes the asteroid but not the laser and one of the asteroids on the current row stops moving and then the next row of asteroids spawns but does not move down.
I get this error too:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at _8_fla::MainTimeline/obstacleMove()
Any help would be greatly appreciated.
You error, is likely because you are running 3 separate enter frame handlers in the same scope, and removing items from arrays and display lists (that are referenced in multiple enter frame handlers). So you asteroid is removed from the display list in one, and then you try to remove it again in another.
There are also a whole lot of other issues with your code that will cause errors and undesired results. Things like for(var i in newLasers) - in that kind of loop, i will refer to the actual laser object not the index of the array. I've re-factored your code and added lots of code comments to hopefully give you an idea of where you were going wrong:
var spawnTimer:Timer = new Timer(3000); //timer will tick every 3 seconds
var spawnPoints:Array = [0, 100, 200, 300, 400, 500, 550]; //your list of spawn x locations
var spawnAmount:int = 4; //how many asteroids to have on the screen at once (you could increase this over time to make it more difficult)
var asteroidSpeed = 5;
var asteroids:Vector.<asteroidOne> = new Vector.<asteroidOne>(); //the array for your asteroids - changed to vector for possible performance and code hint improvement (basically the same as Array but every object has to be of the specified type)
var lasers:Vector.<shipLaser> = new shipLaser(); //the array of lasers
var maxLasers:int = 4; //the maximum amount lasers allowed at any given time
var soundExplosion:Sound = new ExplosionSound();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
player.addEventListener(Event.ENTER_FRAME, gameLoop);
spawnTimer.addEventListener(TimerEvent.TIMER, spawn, false, 0, true); //let's run the spawn function every timer tick
spawnTimer.start(); //start the spawn timer
spawn(); // calling it immediately
function onKDown(e:KeyboardEvent):void{
if (e.keyCode == 32) {
//create ONE laser per button push (instead of 4 identical lasers)
if(lasers.length < maxLasers){ //if player hasn't reached the maximum amount of lasers available
var tmpLaser:shipLaser = new shipLaser();
tmpLaser.x = player.x + player.width / 2 - tmpLaser.width / 2;
tmpLaser.y = player.y;
addChild(tmpLaser);
lasers.push(tmpLaser);
}
}
}
//calling this will spawn as many new asteroids as are needed to reach the given amount
function spawn(e:Event = null):void {
if (asteroids.length >= spawnAmount)
return; //let's not bother running any of the code below if no new asteroids are needed
spawnPoints.sort(randomizeArray); //lets randomize the spwanPoints
var spawnIndex:int = 0;
var a:asteroidOne; //var to hold the asteroid every loop
while (asteroids.length < spawnAmount)
{
a = new asteroidOne();
a.x = spawnPoints[spawnIndex];
spawnIndex++; //incriment the spawn index
if (spawnIndex >= spawnPoints.length)
spawnIndex = 0; //if the index is out of range of the amount of items in the array, go back to the start
a.y = -50;
asteroids.push(a); //add it to the array/vector
addChild(a); //add it to the display
}
}
function gameLoop(e:Event):void {
//LOOP through all the asteroids, give it a label (asteroidLoop) so we can break/continue it inside other loops
asteroidLoop: for (var i:int = 0; i < asteroids.length; i++) {
//check if asteroid is out of bounds
if (asteroids[i].y > stage.stageHeight || asteroids[i].x > stage.stageWidth || asteroids[i].x < -asteroids[i].width || asteroids[i].y < -asteroids[i].height) {
//object is out of the bounds of the stage, let's remove it
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
continue; //forget the rest of the code below and move on to the next iteration in the for loop since the asteroid is gone
}
//check if any lasers are colliding with this asteroid
for (var j:int = lasers.length-1; j >= 0;j--) { //iterate over all lasers backwards
if (asteroids[i].hitTestObject(lasers[j])){
trace("BOOM!");
var soundExplosion:Sound = new ExplosionSound();
var channel1:SoundChannel = soundExplosion.play();
//remove the asteroid
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
//remove the laser
removeChild(lasers[j]);
lasers.splice(j, 1);
continue asteroidLoop; //break completely out of this inner for-loop (lasers) since the asteroid in the outer loop was removed, and move on to the next asteroid
}
}
//check if this asteroid collides with the player
if (player.hitTestObject(asteroids[i])){
trace("HIT");
//remove the asteroid
removeChild(asteroids[i]); //remove it from the display
asteroids.splice(i, 1); //remove it from the array/vector
removeChild(player);
spawnTimer.stop(); //stop spawning new asteroids
//will add end-game trigger here soon.
break; //break completely out of the asteroid loop if it's game over (as there's no point in checking the rest of the asteroids)
}
//we've made it this far, so let's just move this asteroid
asteroids[i].y += asteroidSpeed;
}
for (var i:int = lasers.length-1; i >= 0;i--) { //iterate backwards
lasers[i].y -= laserSpeed;
// Moves the laser up the screen
if (lasers[i].y <= 0){ //make this less than or equal to 0
removeChild(lasers[i]); //remove the laser from the display list
lasers.splice(i, 1); //remove the laser from the array
}
}
}
function randomizeArray(a:*, b:*):int {
return (Math.random() < .5) ? 1 : -1;
}

How to create object array in ext js4 and set values to it?

I am working in extjs4 MVC. Where i am getting stuck at a point*.Which is how to define object array in extjs4 and set values to it as well as retrieve values from that object.*I am tried but not yet solved.
Suppose I have Qusetion paper.Which displays some question with there options.I have got qustion with proper selected option.But I am not succeed to store it in proper models instance.I know how to store single record to particular model instance.But I dont know how to store repetative values to a particular model object.How I solve this probelm.
1) here is my some contrller file code
temp:function()
{
var obj = Ext.create('Demo.model.Poll');
for(var i=0;i<4;i++)
{
var inputs = document.getElementsByName(i);
var radio = "";
for (var j = 0; j < inputs.length; j++) {
if (inputs[j].checked) {
name = inputs[j].name;
value = inputs[j].value;
//console.log("questionId="+name +" value="+ value);
check.set('poll',name);
check.set('option',value);
}// End of if statment
}// End of inner for loop
}//End of outer for loop
//Here I am going to display values inside object
console.log("----------------------------------");
for(var i=0;i<4;i++)
{
console.log(i);
console.log(check.get('poll'));
console.log(check.get('option'));
}
//Is it possible to save object array to server side in single save method
// obj.save();
}// End of temp function
2) And after running this code i got last set value to model.In firebug i got this result.
for exampl.
3
England
3
England
3
England
3
England
please give me some suggestion
Try,
var myObj = [];
for(.....)
{
myObj.push(
{
'poll' : name,
'option' : value
});
}
to access,
var i;
for(i=0; i<myObj.length; i++)
{
console.log(myObj[i].poll);
console.log(myObj[i].option);
}
I have found the solution to my question and here is the answer.
//code for getting question name and value from view and send to server side in a asingle request
check:function()
{
//creating objects in javascript
var storeObject=this.getStore('qb.QbquestionoptionStore');
for(var i=0;i<=4;i++)
{
var inputs = document.getElementsByName(i);
var radio = "";
for (var j = 0; j < inputs.length; j++) {
if (inputs[j].checked) {
name = inputs[j].name;
value = inputs[j].value;
console.log("questionId="+name +" value="+ value);
var check = Ext.create('Balaee.model.qb.QbquestionoptionModel');
check.set('questionId',name);
check.set('option',value);
storeObject.add(check);
//console.log("User Infooooooooo: option="+check.get('option')+"questionId="+check.get('questionId'));
}// End of if statment
}// End of inner for loop
}//End of outer for loop
// code to display data in store object
for(var i=0;i<4;i++)
{
var record=storeObject.getAt(i);
console.log("record no="+i);
console.log("Qusetion Id="+record.get('questionId'));
console.log("Option="+record.get('option'));
console.log();
}
storeObject.sync();
}// End of check function

Iterating over an array in packages

I want to create a handlebars helper that works like {{#each}} but gives me the possibility to specify a number so that every n iterations some additional code is run.
The reason I need this is that I need to spit out the content in rows of three items, so every three items I need to open and close a new container div.
Of course I could simply let backbone format the array in packages of three items and iterate over that using {{#each}} but I thought it would be more elegant to create a helper so that I can say something like
{{#each_pack data 3}}
<div class="container">
{{#each pack_items}}
<span>{{content}}</span>
{{/each}}
</div>
{{/each_pack}}
I'm not entirely sure how to do this.
How do I make pack_items available to the inside block?
I solved this in a way that lets me use the exact same syntax I just proposed.
Here is the code:
window.Handlebars.registerHelper('each_pack', function(context, packsize, fn){
var ret = '';
/*
Function that creates packages of size
packsize from a given array
*/
var packagify = function(array, packsize){
var i = 0;
var length = array.length;
var returnArray = [];
var pack = [];
while(i < length){
/*
If this is not the first entry,
if this is the packsize-d entry
or this is the last entry,
push the pack to the return array
and create a new one
*/
if(((i % packsize) == 0 && i != 0) || (i == (length - 1))){
returnArray.push(pack);
pack = [];
}
pack.push(array[i]);
i++;
}
return returnArray;
}
var packArray = packagify(context,packsize);
for(var i = 0; i < packArray.length; i++){
var pack = packArray[i];
this['pack_items'] = pack;
ret = ret + fn(this);
}
delete this['pack_items'];
return ret;
});

Resources