Setup flag in Javascript - javascript

Below is a script I am using for a Google Docs Spreadsheet.
These links show what I am doing:
http://i.stack.imgur.com/uGik7.png
http://i.stack.imgur.com/AbKnQ.png
How can I set up a "flag" so that when I run this script a second time, it doesn't add the perviously added stock items?
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Purchase Orders");
var sheet2 = ss.getSheetByName("Inventory");
var data = sheet1.getDataRange();
var i_data = sheet2.getDataRange();
var lastRow = data.getLastRow();
var iLastRow = i_data.getLastRow();
for (i=1;i<=lastRow;i++) {
if (data.getCell(i, 5).getValue() == "stock"){
for (n=1;n<=iLastRow;n++){
if (data.getCell(i,3).getValue() == i_data.getCell(n,3).getValue()) {
i_data.getCell(n, 1).setValue(i_data.getCell(n,1).getValue() + data.getCell(i,2).getValue());
}
}
}
}
}​
I guess I'm trying to do this: Once the item has been added to inventory, the script adds an x to column i of that line. Then when the script is run again, it skips over the lines with an x in column i

Designate a cell to hold the flag value, and have the script check that particular cell for the flag value.

In JavaScript, functions are objects. Objects have properties. So, decorate your function:
function myFunction() {
if (!myFunction.alreadyDoneRunIt) {
alert('bapt uia');
myFunction.alreadyDoneRunIt = true;
}
}
for (var i = 0; i < 10; i++) {
myFunction(); // alerts once
}

Related

OnEdit() google script trigger use in function

I'm working on a small project in Google Apps Scripts using Google spreadsheet / Google Forms.
I want to help students in large class sizes find people to study with by entering the class into a Google Form. From there they would be automatically emailed a list of people taking the same class as them, who are also looking for people in the same class or lecture to study with. The student inputs their name, school Id number, email, class CRN#, Class Name and instructor. Its put into the Google spreadsheet and I manipulate it like a CSV file.
I want to use the onEdit() trigger so that when information is added or edited, an email will be sent out. I'm not understanding how the onEdit() event trigger works.
This is my code for the class sorting:
function studyBudy2() {
var ss =
SpreadsheetApp.openById("1ZxTdRdhy0iR6HH7jB75KL4g-SCr7nPZEilXrzECe7yg").getActiveSheet();
var numOfStu = ss.getLastRow();
/*var range = ss.getRange(2, 4, numOfStu-1);
var values = range.getValues();
// get emails out of spreadsheet
for (var row in values) {
for (var col in values[row]) {
emails = values[row][col]
Logger.log(emails);
// sends emails
MailApp.sendEmail(emails, "pls work","now");
}
}
*/
var theMass = []
var rAnge = ss.getRange(2,1,numOfStu-1,7);
var vAlues = rAnge.getValues()
for (var row in vAlues) {
var student = [];
var buzznumber = vAlues[row][2];
var classCRN = vAlues[row][4];
var class = vAlues[row][5];
var proffessor = vAlues[row][6];
student.push(buzznumber);
student.push(classCRN);
student.push(class);
student.push(proffessor);
theMass.push(student);
}
for (var i = 0; i < numOfStu-2; i++){
var theStudent = theMass[i]
var theCRN = theStudent[1];
var theClass = theStudent[2];
var theProffessor = theStudent[3];
var theBuzznumber = theStudent[0];
Logger.log(theClass);
for (var j= 1; j < numOfStu-1; j++){
if (i+j <= numOfStu-2 && theMass[i+j][1] == theCRN && (i+j != i)){
Logger.log("Youre in the same Section!")
}
else if (i+j <= numOfStu-2 && theMass[j+i][2] == theClass && theProffessor != theMass[j+i][3] && (i+j != i)){
Logger.log("Youre taking the same Course!");
}
else if(j+i <= numOfStu-2 && theClass == theMass[j+i][2] && theProffessor == theMass[j+i][3] && (i+j != i)){
Logger.log("Youre in the same lecture!");
}
else if (j+i > numOfStu-2){
continue;
}
}
}
}
I'm thinking the onEdit() function should be implemented as another function but does it go in another function or in this studyBudy2 function?
function onEdit(e) {
var activeSheet = SpreadsheetApp.openById("1ZxTdRdhy0iR6HH7jB75KL4g-SCr7nPZEilXrzECe7yg").getActiveSheet();
var row = e.range.getRow();
var studentNum = row+1;
}
onEdit is a reserved function name which purpose is to declare a function to be used as a simple trigger.
function onEdit(e){
//do something
}
Besides creating an onEdit simple trigger, we could create a on-edit installable trigger. Functions to be used for installable triggers could be named as we wish but to avoid confusions it's better to avoid using reserved functions names and spreadsheet build-in functions names.
If studyBudy2() function does what you needs to triggered when a edit is made on the spreadsheet, you could rename it as onEdit, declara an onEdit function that call studyBudy2() or create an installable trigger that calls studyBudy2().
Bear in mind that only edits made by users directly on the spreadsheet will fire a simple/installable on edit trigger. If you want something fire when a form response is submitted then you should use a on form submit installable trigger.
For further details please read https://developers.google.com/apps-script/guides/triggers/

Javascript HTML include results in duplicate includes in random places

This problem has me absolutely stumped. I'm trying to include HTML snippets with Javascript and it works, but for some reason it decides to also include duplicate snippets in various other locations.
Here is a screenshot of what I mean:
It also varies the number and location of these random includes.
This is the function I use to include. It searches through the document and finds div elements with the attribute include="x.html"
function include() {
var allElements;
var fileName;
var includeRequest;
allElements = document.getElementsByTagName("*");
for (var i = 0; i < allElements.length; i++) {
if (allElements[i].getAttribute("include")) {
fileName = allElements[i].getAttribute("include");
includeRequest = new XMLHttpRequest();
includeRequest.open("GET", fileName, true);
includeRequest.onreadystatechange = function() {
if (includeRequest.readyState == 4 && includeRequest.status == 200) {
allElements[i].removeAttribute("include");
allElements[i].innerHTML = includeRequest.responseText;
include();
delete includeRequest;
includeRequest = null;
}
}
includeRequest.send();
return;
}
}
}
This is the function that gets tags from an html file containing articles, and adds them to the list of tags in the box on the right. As you can see, in one place the footer is added to the list instead of the tag. I don't know why.
function getTags() {
var taglist = document.getElementById("taglist");
var tagsRequest = new XMLHttpRequest();
tagsRequest.open("GET", "blogstubs.html", true);
tagsRequest.responseType = "document";
tagsRequest.onreadystatechange = function() {
if (tagsRequest.readyState == 4 && tagsRequest.status == 200) {
var tagsResponse = tagsRequest.responseXML;
var tags = tagsResponse.getElementsByClassName("tag");
var tags = getUnique(tags);
var len = tags.length;
for (var i = 0; i < len; i++) {
var li = document.createElement("li");
li.appendChild(tags[i]);
taglist.appendChild(li);
}
delete tagsRequest;
tagsRequest = null;
}
}
tagsRequest.send();
}
Javascript only solution please. Ideas?
I copied your website (I hope you don't mind) and tested it with my changes, it seems to be working now without this bug. Here's what I did:
1) I created a new function, don't forget to change the name to whatever you prefer:
function newFunction(allElements, includeRequest) {
allElements.removeAttribute("include");
allElements.innerHTML = includeRequest.responseText;
include();
delete includeRequest;
includeRequest = null;
}
2) I changed the include() function to look like this:
function include() {
var allElements;
var fileName;
var includeRequest;
allElements = document.getElementsByTagName("*");
for (var i = 0; i < allElements.length; i++) {
if (allElements[i].getAttribute("include")) {
var element = allElements[i];
fileName = element.getAttribute("include");
includeRequest = new XMLHttpRequest();
includeRequest.open("GET", fileName, true);
includeRequest.onreadystatechange = function() {
if (includeRequest.readyState == 4 && includeRequest.status == 200) {
return newFunction(element, includeRequest);
}
}
includeRequest.send();
return;
}
}
}
I think the problem was caused by async nature of AJAX requests, like I said in the comment. So you need to pass the variables to your AJAX call instead of using the global scope, that's why you need this new callback function.
In other words, in the original code the AJAX variable allElements[i] wasn't in sync with your loop's allElements[i], so while in your loop it would be 5, in AJAX function (which executed separately and not in order with the loop) it would be 3, 6 or whatever else. That is why it would append the html to the element that seems random. Think of AJAX as of someone who doesn't care about the order of your loops, someone who really doesn't like to wait while someone else is counting and does everything in his own order.

Compare two arrays in Apps Script not working

I´m a newbie to apps script, I want to do a price comparison script, I got two columns one column gets data via blockspring addon and import.io, this provide info about a website, one column name of the product and the other the price of this product. I want some way to notice me when price change, so I create a script that copy the values of this two columns , store them , and when i trigger it , it get the data from both columns and compare it , now for the test I have a simple alter box that tells me if some data changes.
For now , I was able to wrote a script that get the values and compare it , but for some unknown reason it does not work.
This is my script. Maybe in the future I would like to alert what data in particular changes, but this is my first script son I try to take it easy.
This is the spreadsheet I´m working with
https://docs.google.com/spreadsheets/d/1HleYu-dCbUReOH-7SnEFipJa6E9wEcEzasQ7ns2tXso/edit?usp=sharing
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source1 = ss.getRange("A15:A105");
var source2 = ss.getRange("B15:B105");
var source3 = ss.getRange("A16:A105").getValues();
var source4 = ss.getRange("E16:E105").getValues();
var source5 = ss.getRange("E15:E105");
if (source5.isBlank()) {
source1.copyTo(ss.getRange("E15:E105"), {contentsOnly: true});
source2.copyTo(ss.getRange("F15:F105"), {contentsOnly: true});
Browser.msgBox('VALUES COPIED !', Browser.Buttons.OK);
}
if (source3 == source4) {
Browser.msgBox('NOTHING CHANGES !', Browser.Buttons.OK);
}
else {
Browser.msgBox('SOMETHING CHANGES!', Browser.Buttons.OK);
}
}
It is not possible to compare arrays by == method. You need to traverse through each and every element and do a comparison.
var Inspector = false;
for(var i=0;i<source3.length;i++)
{
if(source3[i][0].toString() != source4[i][0].toString())
{
Inspector = true;
}
}
if(Inspector)
{
Browser.msgBox('SOMETHING CHANGES!', Browser.Buttons.OK);
}
else
{
Browser.msgBox('NOTHING CHANGES !', Browser.Buttons.OK);
}
You can't compare ranges like that because they are 2-dimensional arrays. I modified your code and included a function to compare 2 columns. It won't work for ranges with more columns but it's easy to enhance it if you need it.
function moveValuesOnly() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var source1 = ss.getRange("A15:A105");
var source2 = ss.getRange("B15:B105");
var source3 = ss.getRange("A16:A105").getValues();
var source4 = ss.getRange("E16:E105").getValues();
var source5 = ss.getRange("E15:E105");
if (source5.isBlank()) {
source1.copyTo(ss.getRange("E15:E105"), {contentsOnly: true});
source2.copyTo(ss.getRange("F15:F105"), {contentsOnly: true});
Browser.msgBox('VALUES COPIED !', Browser.Buttons.OK);
}
function equalColumns(col1, col2) {
if (col1.length !== col2.length) return false;
var equal = true;
for (var i = 0; i < col1.length; i ++) {
if (col1[i][0] !== col2[i][0]) {
equal = false;
break;
}
};
return equal;
}
if (equalColumns(source3,source4)) {
Browser.msgBox('NOTHING CHANGES !', Browser.Buttons.OK);
}
else {
Browser.msgBox('SOMETHING CHANGES!', Browser.Buttons.OK);
}
}

How to search a cell in Google Sheets that has multiple words for a specific word and return a result?

Here's what I'm trying to accomplish:
A project manager fills out a Google Form. It spits the result to a spreadsheet, and I want to manipulate that data.
The first question/cell is what social media the product is using, with a multiple choice checkbox.
If someone checks off Facebook and Twitter, the cell returns "Facebook, Twitter" and I'm having trouble searching the cell for "Twitter" since it's not first.
Here's what I have so far:
function testplan() {
var mainsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var testplan = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestPlan");
var socialData = mainsheet.getRange(3, 3).getValues();
var socialDataText = socialData.length;
var fbSocial = "Facebook";
var twitSocial = "Twitter";
for (var i = 0; i < socialDataText; i++) {
if (socialData[i][0] == fbSocial) {
testplan.getRange("A15").setValue("User can log into the app with Facebook.");
testplan.getRange("A16").setValue("User can share content from the app with Facebook.");
} {
return 0;
};
};
for (var i = 0; i < socialDataText; i++) {
if (socialData[i][0] == twitSocial) {;
testplan.getRange("A17").setValue("User can log into the app with Twitter.");
testplan.getRange("A18").setValue("User can share content from the app with Twitter.");
} {
return 0;
};
};
The first command to look for "Facebook" works, because it's the first bit of text. But anything after it isn't able to be found. I've searched a lot and have found things that are close, but nothing that works the way I'm expecting it to. It's probably a command or something really obvious that I'm not seeing.
try
function testplan() {
var mainsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var testplan = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestPlan");
var socialData = mainsheet.getRange(3, 3).getValues();
var socialDataText = socialData.length;
var fbSocial = "Facebook";
var twitSocial = "Twitter";
for (var i = 0; i < socialDataText; i++) {
if (socialData[i][0].indexOf(fbSocial) > -1) {
testplan.getRange("A15").setValue("User can log into the app with Facebook.");
testplan.getRange("A16").setValue("User can share content from the app with Facebook.");
};
if (socialData[i][0].indexOf(twitSocial) > -1) {;
testplan.getRange("A17").setValue("User can log into the app with Twitter.");
testplan.getRange("A18").setValue("User can share content from the app with Twitter.");
};
};
};
for simplicity

getOptions() for loop not working

The following code throws error. I try to get (alert) the value and options of an Optionset in MS CRM 2013, It successfully shows all the things but after that it shows error. i attached the screen shot that error
function GetOptionsetLable()
{
var OptionSetControl = Xrm.Page.getAttribute("test_613a");
for(var intCounter=0; OptionSetControl .getOptions().length; intCounter++)
{
var backendvalue=OptionSetControl .getOptions()[intCounter].value;
alert(backendvalue.toString());
}
}
function GetOptionsetLable()
{
var OptionSetControl = Xrm.Page.getAttribute("test_613a");
for(var intCounter=0; OptionSetControl .getOptions().length; intCounter++)
{
var backendvalue=OptionSetControl .getOptions()[intCounter].value;
alert(backendvalue.toString());
}
}
Your for loop will never end because you don't tell it when to stop.
OptionSetControl.getOptions().length
should be:
intCounter < OptionSetControl.getOptions().length
Full code:
function GetOptionsetLable()
{
var OptionSetControl = Xrm.Page.getAttribute("test_613a");
for(var intCounter=0; intCounter < OptionSetControl.getOptions().length; intCounter++)
{
var backendvalue=OptionSetControl.getOptions()[intCounter].value;
alert(backendvalue.toString());
}
}
Remember that the value property contains the optionset numeric value, and the .text property the label.
you can also use a shorter for condition:
var options = Xrm.Page.getAttribute("test_613a").getOptions();
for (var i in options) {
alert(options[i].value);
}
I also created a library, you can find here:
OptionSet JavaScript Helper Library

Categories

Resources