I'm trying to do something which I thought would be extremely simple but is baffling me for some reason: I've got a function that's pushing a bunch of IDs of locations into an array and I don't want it to push these values in if they're null (the script allows user input from a Google Sheet so it's possible they'll input an incorrect value that won't get matched to an ID).
I've tried this so far:
for (var i = 0; i <= startEndDifference; i++) {
if (objectLocationInputStart != null) {
objectLocationIdsArray.push(locationMatch(objectLocationInputStart));
}
objectLocationInputStart = objectLocationInputStart + 1
}
but null values are still pushing to the array.
For context, this is referring to two cells in a Google sheet with a starting number and an ending number, and the for loop picks up all the numbers in between and matches them to an ID using the function. Everything it does is working perfectly other than passing in the null values.
Related
I want to import rows from one google sheet to the other, however source sheet imports a number of empty rows. Now I use a filter function to get rid of these rows but they will not disappear, can anyone tell me why?
var a = SpreadsheetApp.openByUrl("url").getSheetByName("Admin Use Only").getRange(4,1,6,21).getValues();
var b = SpreadsheetApp.getActive().getSheetByName('Credit_Detail');
b.getRange(b.getLastRow() +1, 1, a.length,21).setValues(a);
//filter function below:
var otarget=b.getRange(2,1,b.getLastRow()-1, 26).getValues();
var data=otarget.filter(function(r){
return !r.every(function(cell){
return cell === "";});
});
Logger.log(data);
b.getRange("A2:Z").clearContent();
b.getRange(3,1,data.length,data[0].length).setValues(data);
here's how I would do it. First, create an variable to store the array of the source. then run a for loop scanning the first column for empties. something like: for (var i = 0, i < data.length; i++) { if (data[i][0] != '') { XXXX } }
XXXX means that you can either put a code to create a new set of array which can be passed to the target sheet at once or use append row to transfer non blank rows to the target sheet one by one.
Note: Creating a new array to store non-empty rows would speedup the execution time if you are dealing with large data, thousands of rows.
I need help with matching two arrays. I have TypeScript in the example code, but it can be understood since its about array operations more or less.
In short:
I have two arrays; myItems[] and allItems[]. myItems[] can only hold maximum 4 values.
I want to first check if the items in myItems[] is 4, AND/OR exist in the other array allItems[].
If NOT: populate myItems[] with values from allItems[] (until it contains 4 values) and/or replace the items that is missing (relative to allItems[]) with other items in allItems[] (I'm trying to use default values instead of randomly taking values in my example code).
Description:
I have a widgets (quick links) module that show 4 links at a time, but there are in total 20 different links (or more). All links is stored in a list and each has its own unique ID. In code, all links is extracted and returned in an array (like the allItems[] in above example).
The user can save the links he/she wants to show in the widget. The user settings is stored and returned as an array with the ID of the links that the user have saved. Like the myItems[] above,
Problem:
I have a solution that check the length of the myItems[], and if needed populates items from the allItems[] one. However, it does NOT check if the items in the user array exist in allItems[] and then populates it with the default links. In practical it means that the user can save links and it will be shown in the widget as intended. BUT if a link is removed in the list (which will then be removed in the allItems array) only 3 items will be shown as the myItems[] doesn't check with the allItems[] array to see if it exists there.
Code:
public async getUserWidgets(): Promise<Widget[]> {
let allWidgets = await this.getAllWidgets(); //Array with all the links ID from the list
let userRepository = new UserProfileRepository(this.absoluteWebUrl);
let userSettings = await
userRepository.getUserExtensionValues(this.context); //Extracting the user Settings which contains the ID of the saved linksvar
result:Widget[] = []; //the array where the result will go in
//if the user doesnt have any saved links, or if the user have less than 4 saved links
if (userSettings == null || userSettings.QuickLinksWidgets == null ||
userSettings.QuickLinksWidgets.length < 4)
{result = allWidgets.filter((w) => {return w.defaultWidget;}).slice(0,4);
}
else {var ids =userSettings.QuickLinksWidgets;
for (let i = 0; i < 4; i++) {
let id = '' + ids[i];let w = allWidgets.filter((e) => { return e.id == id;});
if (w.length == 0) {
continue;}
result.push(w[0]);}}
return new Promise<Widget[]>(async (resolve) => {resolve(result);});}
A simple way to check if an array holds a value is using the includes() method.
for(let value of myitems){
if(allitems.includes(value)){
console.log("Duplicate")
}
}
The above code will loop through each value in your myitems array and test if that value is in the allitems array.
Google sheets has an option which is selectable from the top menu to separate text into columns when specifying a character. It's possible use a comma or other characters.
I am looking for a script which can do this process automatically for a given column. There are numerous scripts available to do this but I have not been able to accomplish my task using them.
I am using an application on Android which allows me to scan a qr code and send the string of information to Google sheets.
A sample of the information would appear as : 464839|362|2840|927|72|617
I need to separate this information into separate columns when the information is sent to sheets. The process should be automatic.
I have a snip of code which I've found searching however it doesn't work for me.
var range = SpreadsheetApp.getActiveRange();
var cell = range.getCell(1, 1); // Gets the cell A1
var cellValue = cell.getValue(); // Gets the value of the cell A1
var cellArray = cellValue.split("|"); // Splits the cell value by ',' and stores it in array.
//Iterate through the array
for(var i = 0; i < cellArray.length; i++){
Logger.log(cellArray[i]);
}
I'm not very code savvy, please help.
Below would be a code that you place on an installable trigger that runs at a regular interval and iterates through the values of each row in column A and tries to split the value with the pipe symbol and the replace then write those split values along the columns in that row. If this has already been done in the past the function will error when it tries to split the values because no pipe symbol exists but the try/catch will catch that error and allow the function to continue through the loop.
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("NameOFSheet"); //Change "NameOFSheet to the actual name of the sheet.
var col1Values = sheet.getSheetValues(1, 1, sheet.getLastRow(), 1) //Gets 2d (2 dimensional) array of the Values in Column 1 (getSheetValues(startRow, startColumn, numRows, numColumns)_
var splitVals = []; //Instantiate an empty 1d array variable
//Iterate through the 2d array and set the values
for(var i = 0; i < col1Values.length; i++){
try{
splitVals = col1Values[i][0].split("|"); //Creates a 1d array of values split at every occurrence of the pipe symbol ("|").
//If there is no pipe symbol (which would be the case if this operation has already happened then the array will be blank because .split will throw an error which will get "caught" in the try catch and the row will be skipped
//Iterate over the splitVals array and set the values of the columns along the row (i+1) that you are in.
for(var col = 0; col < splitVals.length; col++){
sheet.getRange(i+1, col+1).setValue(splitVals[col])
}
}catch(e){}
}
}
I commented the code for explanation. I would recommend reading up on 2 dimensional arrays to help you understand them and the code above better.
I have the below code to get all the "Names" given in an IE form, one after the other using javascript. This script suppose to use the IE DOM explorer to get the value.
There would be one or more values that would match the query below at any given time. Therefore, I'll have to use a "For Loop" to get and assign the value to a variable one after the other. I would like to find the maximum number of occurrence to use in the For loop, by getting the value from $('tr.background-light:last').text(). This will contain a number and a name. I am stripping the number only by splitting it cnt=cnt.split(".",1) and assigning this to a variable.
Then using that as my maximum number to loop and trying to assign the value to an array. But it isn't running.
javascript:(function()
{
ver item;
var cnt=$('tr.background-light:last').text(); //getting the last background-light value which will contain the total number of Affected Client's
cnt=cnt.split(".",1); // Stripping just the number out from the above variable
for (var i =0; i <cnt.length; i++)
{
item= $("tr.background-light:eq("+i+")").text(); //looping through to get each affected client info
alert(item)
};
})();
OK, I'm missing something here and I just can't seem to find it because the logic seems correct to me, but I'm certain I'm not seeing the error.
var VisibleMarkers = function() {
var filtered = _.reject(Gmaps.map.markers, function(marker) {
return marker.grade != $('.mapDataGrade').val() && !_.contains(marker.subjects,$('.mapDataSubjects').val())
});
return filtered
}
I'm using underscore.js and jQuery to simplify my javascript work.
So right now, I'm checking by means of selects which data gets to be rejected and then I display the filtered markers on the (google) map (if it helps at all, this is using gmaps4rails which is working perfectly fine, its this bit of javascript that's making me lose the last of the hairs on my head).
Currently, the code functions 100% correctly for the ".mapDataGrade" select, but the ".mapDataSubjects" isn't. Now the markers object has a json array of the subjects (this is for students) and each item in the array has its ID. Its this ID that I am supposed to be checking.
Can someone see what I'm doing wrong?
If there's more info that needs to be included, please let me know.
This is on plain javascript on a RoR application using gmaps4rails
Now the markers object has a json array of the subjects (this is for students) and each item in the array has its ID. Its this ID that I am supposed to be checking.
_.contains compares a values, but it sounds like you want your iterator to compare a value to an object's "id" property. For that, _.some would work; it's like contains, except that, instead of comparing values, you can write the comparison as a function:
Returns true if any of the values in the list pass the iterator truth test.
Here's how you'd use it:
!_.some(marker.subjects, function(subject) {
return subject.id == $('.mapDataSubjects').val();
})
If I'm right, the whole line should be like this:
return marker.grade != $('.mapDataGrade').val() &&
// check that none of the subjects is a match
!_.some(marker.subjects, function(subject) {
// the current subject is a match if its ID matches the selected value
return subject.id == $('.mapDataSubjects').val();
});