I was trying to get the country name and put it in the temparray, so that I can use the temparray to check the country (line 14). The problem is temparray can only contain one value and upon increasing the array length size by using temparray.length = 4, the heat map won't show up in the page.
The code below is to check duplicate name entry from within the array. If the country name is repeated, it will add the past value and its current value and add it into the data table again as the old row.
var i;
var suq = 0;
var temparray = [""];
var rowcount= 0;
//set the value
for (i = 0; i<count; i++){
var countryname = countryarray[i];
var hostcount = hosthitcount[i];
//document.write("hello");
for (rowcount=0;rowcount<temparray.length;rowcount++){
//check for any repeated country name
if (temparray[rowcount] != countryname){
data.setValue(suq, 0, countryname);
data.setValue(suq, 1, hostcount);
temparray[rowcount] = countryname;
//document.write("win");document.write("<br/>");
suq++;
}else{
//get the hits //rowindex
var pastvalue = data.getValue(rowcount,1);
//add the previous value with current value
var value = parseInt(hostcount)+parseInt(pastvalue);
value+= "";
//document.write(value);
//put it in the table
data.setValue(rowcount,1,value);
// document.write("lose");document.write("<br/>");
}
}
}
I don't really understand what you are trying to do with temparray. It can surely contain more than one element with a temparray.push(countryname). Maybe this JavaScript array reference will help you?
Related
Following a previous question
I want to classify text entries by adding a tag in the next column.
I could do it using regex but it will take too much time writing all conditions like :
if(String(data[i][0]).match(/acme|brooshire|dillons|target|heb|costco/gi))
{
labValues[i][0]='Supermarket';
}
Instead I created a named list with all stores names (in another sheet).
If an entry matches a term in the list, the next column is set to "Supermarket".
I am using this script below... No bugs but nothing happens when executed !
function tagStore() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A2:A655')
var store = range.getValues();
var tag = sheet.getRange('B2:B655');
var tagvalues= tag.getValues();
var storeList= SpreadsheetApp.getActive().getRangeByName("store_list");
for (var i = 0; i<store.length; i++)
{
if(String(store[i][0]).match(storeList))
{
tagvalues[i][0]='Supermarket';
}
}
tag.setValues(tagvalues);
}
Edit:
It is important to use a Regex as the "store" Values are not exactly the same as the "store_list".
Store Values : ["Acme Store", "HEB PLaza", "Dillons Group"...]
Store_List : [acme, heb, dillons...]
Instead of trying to go with the regEx approach there is a more straightforward approach by retrieving the range as a list.
// For a Column
var storeList = SpreadsheetApp.getActive().getRangeByName("store_list").getValues().map(function(r){return r[0];});
// For a Row
var storeList = SpreadsheetApp.getActive().getRangeByName("store_list").getValues()[0];
And then look if the values you are looking for are in this list with indexOf().
Try this:
function tagStore() {
var sheet = SpreadsheetApp.getActiveSheet();
var range = sheet.getRange('A2:A655')
var store = range.getValues();
var tag = sheet.getRange('B2:B655');
var tagvalues= tag.getValues();
var storeList= SpreadsheetApp.getActive().getRangeByName("store_list").getValues().map(function(r){return r[0];});//if it's a column
//var storeList=SpreadsheetApp.getActive().getRangeByName("store_list").getValues()[0];//if it's a row
for (var i=0;i<store.length; i++) {
if(storeList.indexOf(store[i][0])!=-1) {
tagvalues[i][0]='Supermarket';
}
}
tag.setValues(tagvalues);
}
This was difficult to title without examples and context. Here goes...
I have a Google app script which searches through a column of student ids (column A on the compiledDATA sheet) and then sets a value (an award) in column B of the same row. This works fine for a single student id, but I need the script to loop and set the same award value for all of the students in the GroupAwardIDs range which is located on a separate sheet called Group Awards.
Here's a link to my sample spreadsheet.
The values to be set are nonconsecutive, and in actual use there may be over a thousand to be set at a time.
How can I achieve this in a quick and efficient way without running into quota issues?
Here's the script (please excuse all the comments - it helps me keep track):
function AwardGroup() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var StarLog = sheet.getSheetByName("compiledDATA");
var GroupAward = sheet.getRangeByName("GroupAward").getValue();
var GroupAwardIDs = sheet.getRangeByName("GroupAwardIDs").getValue(); // THESE ARE THE IDS OF STUDENTS WHO WILL RECEIVE THE AWARD. HOW DO SET VALUES FOR ALL AND ONLY THESE IDS?
var IDs = sheet.getRangeByName("StudentIDs").getValues(); // all of the student IDs
for (var i = 0; i < IDs.length; i++) {
if (IDs[i] == "123461") { // THIS WORKS IF HARDCODE A SINGLE ID
var rowNumber = i+3; // find row and add 3 to compensate for GroupAward range staring at row 3
var StarLogCurrent = StarLog.getRange("B"+rowNumber).getValue(); // locates students award log cell using A1 notation
var appendAward = GroupAward.concat(StarLogCurrent); // prepends new award to previous awards
StarLog.getRange("B"+rowNumber).setValue(appendAward); //write new star log
}
}
}
You want to put GroupAward ("'Group Awards'!B3") to the column "B" of "compiledDATA" with the same row, when StudentIDs ("compiledDATA!A3:A1000") and GroupAwardIDs ("'Group Awards'!B7:B1002") are the same. If my understanding is correct, how about this modification? I think that there are several solutions for your situation. So please think of this as one of them.
Modification points :
Retrieve all GroupAwardIDs.
Remove empty elements in GroupAwardIDs.
Search IDs using GroupAwardIDs and put GroupAward when the IDs is the same with GroupAwardIDs.
Put the values with GroupAward.
Modified script :
Please modify as follows.
From :
var GroupAwardIDs = sheet.getRangeByName("GroupAwardIDs").getValue(); // THESE ARE THE IDS OF STUDENTS WHO WILL RECEIVE THE AWARD. HOW DO SET VALUES FOR ALL AND ONLY THESE IDS?
var IDs = sheet.getRangeByName("StudentIDs").getValues(); // all of the student IDs
for (var i = 0; i < IDs.length; i++) {
if (IDs[i] == "123461") { // THIS WORKS IF HARDCODE A SINGLE ID
var rowNumber = i+3; // find row and add 3 to compensate for GroupAward range staring at row 3
var StarLogCurrent = StarLog.getRange("B"+rowNumber).getValue(); // locates students award log cell using A1 notation
var appendAward = GroupAward.concat(StarLogCurrent); // prepends new award to previous awards
StarLog.getRange("B"+rowNumber).setValue(appendAward); //write new star log
}
}
To :
var GroupAwardIDs = sheet.getRangeByName("GroupAwardIDs").getValues(); // Modified
var IDs = sheet.getRangeByName("StudentIDs").getValues();
// I modified below script.
GroupAwardIDs = GroupAwardIDs.filter(String);
var res = IDs.map(function(e){
return GroupAwardIDs.filter(function(f){
return f[0] == e[0]
}).length > 0 ? [GroupAward] : [""];
});
sheet.getRange("compiledDATA!B3:B1000").setValues(res);
If I misunderstand your question, please tell me. I would like to modify it.
Edit :
You want to add GroupAward to the original values at column B. I understood what you want to do like this. If my understanding is correct, please modify to as follows. In this sample, I used ", " as the delimiter.
var GroupAwardIDs = sheet.getRangeByName("GroupAwardIDs").getValues(); // Modified
var IDs = sheet.getRangeByName("StudentIDs").getValues();
// I modified below script.
var columnB = sheet.getRange("compiledDATA!B3:B1000");
var valColB = columnB.getValues();
GroupAwardIDs = GroupAwardIDs.filter(String);
var res = IDs.map(function(e, i){
return GroupAwardIDs.filter(function(f){
return f[0] == e[0]
}).length > 0 ? [valColB[i][0] ? GroupAward + ", " + valColB[i][0] : GroupAward] : [valColB[i][0]]; // Modified
});
columnB.setValues(res);
I'm having an issue pulling the correct values out of a for loop in Google Sheets.
Here's my code:
Note: this is a snippet from a larger function
function sendEmails() {
var trackOriginSheet = SpreadsheetApp.getActiveSpreadsheet().getName();
var getMirSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Miranda");
//Set a new object to hold conditional data
var holdingData = new Object();
//Create function to get values from origin sheet
var returnedValues = function (trackOriginSheet) {
//Load dynamic variables into an object via returnedValues()
if (trackOriginSheet === getMirSheet) {
var startMirRow = 2; // First row of data to process
var numRowsMir = 506; // Number of rows to process
// Fetch the range of cells A2:Z506
var dataRangeMir = getMirSheet.getRange(startMirRow, 1, numRowsMir, 26);
// Fetch values for each cell in the Range.
var dataMir = dataRangeMir.getValues();
for (var k in dataMir) {
var secondRowMir = dataMir[k];
var intRefDescMir = secondRowMir[3];
var intAdminActionsMir = secondRowMir[4];
//Push returned data to holdingData Object
holdingData.selectedData = secondRowMir;
holdingData.refDesc = intRefDescMir;
holdingData.adminActions = intAdminActionsMir;
}
}
}
Here's a copy of the sheet I'm working on
What I need to have happened here first, is track the origin sheet, then create an object to hold data returned from the returnedValues() function. Later, I'll call the properties of this object into a send email function.
The problem is that I need to be able to pull data from the selected sheet dynamically (the "Miranda" sheet in this case.) In other words, when a user selects the "Yes" option in column I of the Miranda sheet, the first thing this script needs to do is pull the values of the variables at the top of the for loop within the same row that the user selected "Yes." Then, I'm pushing that data to a custom object to be called later.
It's apparent to me, that I'm doing it wrong. There's, at least, something wrong with my loop. What have I done? :)
EDIT:
After reviewing the suggestion by VyTautas, here's my attempt at a working loop:
for (var k = 0; k < dataMir.length; k++) {
var mirColI = dataMir[k][8];
var mirRefDesc = dataMir[k][2];
var mirAdminActions = dataMir[k][3];
var mirDates = dataMir[k][4];
if (mirColI === "Yes") {
var activeRowMir = mirColI.getActiveSelection.getRowIndex();
//Pull selected values from the active row when Yes is selected
var mirRefDescRange = getMirSheet.getRange(activeRowMir, mirRefDesc);
var mirRefDescValues = mirRefDescRange.getValues();
var mirAdminActionsRange = getMirSheet.getRange(activeRowMir, mirAdminActions);
var mirAdminActionsValues = mirAdminActionsRange.getValues();
var mirDatesRange = getMirSheet.getRange(activeRowMir, mirDates);
var mirDatesValues = mirAdminActionsRange.getValues();
var mirHoldingArray = [mirRefDescValues, mirAdminActionsValues, mirDatesValues];
//Push mirHoldingArray values to holdingData
holdingData.refDesc = mirHoldingArray[0];
holdingData.adminActions = mirHoldingArray[1];
holdingData.dates = mirHoldingArray[2];
}
}
Where did all that whitespace go in the actual script editor? :D
You already correctly use .getValues() to pull the entire table into an array. What you need to do now is have a for loop go through dataMir[k][8] and simply fetch the data if dataMir[k][8] === 'Yes'. I also feel that it's not quite necessary to use for (var k in dataMir) as for (var k = 0; k < dataMir.length; k++) is a lot cleaner and you have a for loop that guarantees control (though that's probably more a preference thing).
You can also reduce the number of variables you use by having
holdingData.selectedData = mirData[k]
holdingData.refDesc = mirData[k][2] //I assume you want the 3rd column for this variable, not the 4th
holdingData.adminActions = mirData[k][3] //same as above
remember, that the array starts with 0, so if you mirData[k][0] is column A, mirData[k][1] is column B and so on.
EDIT: what you wrote in your edits seems like doubling down on the code. You already have the data, but you are trying to pull it again and some variables you use should give you an error. I will cut the code from the if, although I don't really see why you need to both get the active sheet and sheet by name. If you know the name will be constant, then just always get the correct sheet by name (or index) thus eliminating the possibility of working with the wrong sheet.
var titleMirRows = 1; // First row of data to process
var numRowsMir = getMirSheet.getLastRow(); // Number of rows to process
// Fetch the range of cells A2:Z506
var dataRangeMir = getMirSheet.getRange(titleMirRows + 1, 1, numRowsMir - titleMirRows, 26); // might need adjusting but now it will only get as many rows as there is data, you can do the same for columns too
// Fetch values for each cell in the Range.
var dataMir = dataRangeMir.getValues();
for (var k = 0; k < dataMir.length; k++) {
if (dataMir[k][7] === 'Yes') { //I assume you meant column i
holdingData.refDesc = dataMir[k] //this will store the entire row
holdingData.adminActions = dataMir[k][3] //this stores column D
holdingData.dates = dataMir[k][4] //stores column E
}
}
Double check if the columns I have added to those variables are what you want. As I understood the object stores the entire row array, the value in column called Administrative Actions and the value in column Dates/Periods if Applicable. If not please adjust accordingly, but as you can see, we minimize the work we do with the sheet itself by simply manipulating the entire data array. Always make as few calls to Google Services as possible.
I'm writing the following code (a test as of now) using Google Scripts to pass data from one spreadsheet to another. The passing of the code is working just fine, however my second For loop – which I intend to use to detect duplicate values and avoid passing those rows over – is not working.
Checking the logs I see that even though the "i" and "j" values are correctly being passed inside the If block, the "if(sheetsIDHome[i] == sheetsIDTarget[j])" statement is never triggering, even when I confirm that both values are the same.
Any help would be greatly appreciated, thank you in advance!
function move(){
var homeBook = SpreadsheetApp.getActiveSpreadsheet();
var sheet = homeBook.getSheets()[0];//Sheet where my Home data is stored
var limit = sheet.getLastRow(); //number of rows with content in them
var evento = sheet.getRange(2, 1, limit-1).getValues(); //Even titles array
var descript = sheet.getRange(2,2,limit-1).getValues(); //Event Descriptions array
var tags = sheet.getRange(2,3,limit-1).getValues(); //Tags array
var sheetsIDHome = sheet.getRange(2,4,limit-1).getValues(); //ID's array
var targetBook = SpreadsheetApp.openById("1t3qMTu2opYffLmFfTuIbV6BrwsDe9iLHZJ_ZT89kHr8"); // Traget Workbook
var target = targetBook.getSheets()[0]; //Sheet1, this is my Target sheet
if (target.getLastRow() > 1){
var sheetsIDTarget = target.getRange(2, 4,target.getLastRow()-1).getValues();}
else{
var sheetsIDTarget = target.getRange(2, 4, 1).getValues();}
var targetRow = target.getLastRow()+1; //Target row to start pasting content
for (var i = 0; i < evento.length; i++) { //Loops throught every value from my Home sheet in order to pass it to my Target Sheet
var isKlar = 1; //This works as a switch, data passing will not activate if isKlar set to 0
Logger.log("Switch is: "+isKlar);
for(var j = 0; j < sheetsIDTarget.length; j++){ //While having a certain "i" value in place, will loop though all my values in my target array using the counter "j"
if(sheetsIDHome[i] == sheetsIDTarget[j]){ //If the ID of my curent row from Home matches any of the values in my target sheet, my "isKlar" switch should turn off and the break loop will be exited.
Logger.log("If Activated");
isKlar = 0;
break;}
else{Logger.log("ID's: "+sheetsIDHome[i] + " vs " + sheetsIDTarget[j]);}
}
if(isKlar === 1){ //data passing will not activate if isKlar set to 0
//pass data to the Target sheet
target.getRange(targetRow,1).setValue(evento[i]);
target.getRange(targetRow,2).setValue(descript[i]);
target.getRange(targetRow,3).setValue(tags[i]);
target.getRange(targetRow,4).setValue(sheetsIDHome[i]);
targetRow++; //select the next available row in ny Target sheet
}
}
}
Edit. - Right now I'm testing both ID arrays with the same numbers (e.g. 1, 2, 3, 4). The log inside my else statement does show the correct values being read for both arrays... I thought it was a scope issue, but now I'm not sure where the problem is.
the issue is a sheet range.getValues() returns an array of arrays, not an array of values.
values[0] is the first row, and values[0][0] is the first value in that first row. rework your code knowing this.
i'm new to javascript and jquery and was wondering if someone could let me in on why this isn't working correctly.
i have a drop-down box that a user selects a value from, then "Processes." When processed the value of the drop-down as well as a textbox is stored in an array. I want the user to be able to then basically store the same drop-down selection and textbox data in the array again but now in a new value pair.
First store would be
TestArray[0][0] = "Textbox Value"
If "Processed" again, it would be
TestArray[1][0] = "Textbox Value"
that way I can parse through later and figure how many times the user "Processed" the drop-down selection;
var oneClickReport = $("#reportName").val();
if(oneClickReport == "Sample Report One"){
var arrayOneCount = reportOneArray.length;
var totalHouseholds = 0;
$("#reportChecks span:visible").each(function(){
if($(this).find(':checkbox').prop('checked')){
var HHName = $(this).text();
reportOneArray.push(HHName);
arrayTest[arrayOneCount][totalHouseholds] = HHName;
}
totalHouseholds += 1;
});
for(i = 0; i < arrayOneCount; i+=1){
alert(arrayTest[0][i]);
}
}
But when trying to "Process" for the second time, I receive the error of;
SCRIPT5007: Unable to set property '0' of undefined or null reference
on line;
arrayTest[arrayOneCount][totalHouseholds] = HHName;
You need to initialize your array. I'm not sure what exactly you want to do but you need an array like this
var arrayTest = []
And you will need to initialize subsequent value like
arrayTest[1] = []
Then you can access your array
arrayTest[1][0] = []
I made an example for you
var oneClickReport = $("#reportName").val();
var arrayTest = [] # You may need to put this elsewhere
if(oneClickReport == "Sample Report One"){
var arrayOneCount = reportOneArray.length;
var totalHouseholds = 0;
$("#reportChecks span:visible").each(function(){
if($(this).find(':checkbox').prop('checked')){
var HHName = $(this).text();
reportOneArray.push(HHName);
if(!arrayTest[arrayOneCount]){ arrayTest[arrayOneCount] = []; }
arrayTest[arrayOneCount][totalHouseholds] = HHName;
}
totalHouseholds += 1;
});
for(i = 0; i < arrayOneCount; i+=1){
alert(arrayTest[0][i]);
}
}
your problem with var arrayOneCount = reportOneArray.length; and you're not changing this value