Script : set in bold highest value - javascript

I got an array in Google Sheet that looks something like this :
+-----+---------+------------+------------+------------+-----+
| | A | B | C | D | ... |
+-----+---------+------------+------------+------------+-----+
| 0 | | Mission #1 | Mission #2 | Mission #3 | ... |
+-----+---------+------------+------------+------------+-----+
| 1 | Item #1 | 100 | 250 | 250 | ... |
+-----+---------+------------+------------+------------+-----+
| 2 | Item #2 | 200 | 1000 | 500 | ... |
+-----+---------+------------+------------+------------+-----+
| 3 | Item #3 | 300 | 3000 | 800 | ... |
+-----+---------+------------+------------+------------+-----+
| ... | ... | ... | ... | ... | ... |
+-----+---------+------------+------------+------------+-----+
I want to create a script that bold the highest value for each item. But there is a problem, as you can see, some items get the same value in different missions, what I need is in this case, only the "most right" needs to be bold.
So what I expect to do :
+-----+---------+------------+------------+------------+-----+
| | A | B | C | D | ... |
+-----+---------+------------+------------+------------+-----+
| 0 | | Mission #1 | Mission #2 | Mission #3 | ... |
+-----+---------+------------+------------+------------+-----+
| 1 | Item #1 | 100 | 250 | **250** | ... |
+-----+---------+------------+------------+------------+-----+
| 2 | Item #2 | 200 | **1000** | 500 | ... |
+-----+---------+------------+------------+------------+-----+
| 3 | Item #3 | 300 | **3000** | 800 | ... |
+-----+---------+------------+------------+------------+-----+
| ... | ... | ... | ... | ... | ... |
+-----+---------+------------+------------+------------+-----+
** = is bold
So I started to think :
var Item1High = max(b1;d1);
For each row (X1) if value == Item1High then set to bold
But at this state the most difficult part is to set in bold only the most right value (So the highest value of row)
And I'm stuck at this state.
Could you help me with that ?
I'm using Google Sheet Script in JavaScript.
Thanks !

You want to set the bold type to the maximum value in each row of Google Spreadsheet.
For example, when the column "B" and "C" is the same value and the maximum value, you want to set the bold to the column "C".
You want to achieve this using Google Apps Script.
The flow of this sample script is as follows.
Flow:
Retrieve all values from the sheet.
Create text styles.
Set the created text styles.
Sample script:
Before you run the script, please set the sheet name.
function myFunction() {
const sheetName = "Sheet1";
// 1. Retrieve all values from the sheet.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const range = sheet.getDataRange();
const values = range.getValues();
values.shift();
// 2. Create text styles.
const tempStyle = SpreadsheetApp.newTextStyle().setBold(false).build();
const bold = SpreadsheetApp.newTextStyle().setBold(true).build();
const styles = values.map(r => {
r.shift();
let ar = Array(r.length).fill(tempStyle);
ar[r.lastIndexOf(Math.max(...r))] = bold;
return ar;
});
// 3. Set the created text styles.
range.offset(1, 1, styles.length, styles[0].length).setTextStyles(styles);
}
References:
newTextStyle()
setTextStyles()
Added:
In this sample script, the selected range is used.
function myFunction() {
const sheetName = "Sheet1";
const selectRange = "B2:D4"; // Please set the range you want to use.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const tempStyle = SpreadsheetApp.newTextStyle().setBold(false).build();
const bold = SpreadsheetApp.newTextStyle().setBold(true).build();
const range = sheet.getRange(selectRange);
const values = range.getValues();
const styles = values.map(r => {
let ar = Array(r.length).fill(tempStyle);
ar[r.lastIndexOf(Math.max(...r))] = bold;
return ar;
});
range.setTextStyles(styles);
}

Related

Dexiejs - Filtering returns single value

My dexiedb structure looks like below.
const db = new Dexie('shipment-execution');
db.version(1).stores({
root: '++id,shipmentid,stopid',
})
My IndexedDB will look like below
| id| shipmentid| stopid|
| 1 | 6000001 | 10 |
| 2 | 6000001 | 20 |
| 3 | 6000001 | 30 |
| 4 | 6000002 | 10 |
| 5 | 6000002 | 20 |
I am trying to get all the data which has shipmentid equal to 6000001. Each time it is returning only one record (the first record ).
db.root.where({shipmentid : '6000001'}).toArray().then((d)=>{
console.log(d);
})
output is only fetching the first record
| id| shipmentid| stopid|
| 1| 6000001 | 10 |
Please let me know, what I am doing wrong.

Restrict Find and Replace function using map() to single column in a 2d array JavaScript

I am working in Google sheets
I have a find and replace function gotten from here. It works great when the array is made from a single column of data
But, in certain instances in which I want to use my function I have all my data sitting in an array which is being passed from prior processing, the data if printed to the page looks like
| Id | Segment |Other Column| etc..
|----|--------------------|------------|
| 1 | AAA AA|AA|CaaL AA |stuff |
| 2 | AAA-AA|AA|CaaL |stuff |
| 3 | AAA, AA|AA|AA |AA |
| 4 | AA |stuff |
| 5 | AA AA | |
| 6 | AA, AA |AA |
| 7 | |stuff |
| 8 | CaaL |stuff |
| 9 | AA |stuff |
I only want to replace data in the Segment column
| Id | Segment ||Other Column| etc..
|----|-------------------|------------|
| 1 | AAA AA|zz|CaaL AA |stuff |
| 2 | AAA-AA|zz|Bob |stuff |
| 3 | AAA, AA|zz|zz |AA |
| 4 | zz |stuff |
| 5 | AA AA | |
| 6 | AA, AA |AA |
| 7 | |stuff |
| 8 | Bob |stuff |
| 9 | zz |stuff |
As it is the AA in the Other Column (could be in any column, I have no way of knowing) is being replaced which I do not want
Can the findReplace function be restricted to a single column in values updating that only that column in values ?
I have tried getting the column array I want to restrict values to with
function getColumn(matrix, col, startrow){
var column = [];
for(var i=startrow; i<matrix.length; i++){
column.push(matrix[i][col]);
}
return column;
}
and then attempting to restrict the input to this column
function fr(input) {
const aCOL = getColumn(values,2,0)
return input.aCOL.map(c => c.replace(regex, (x) => map[x]));
AND
return input.map(c => c.aCOL.map(y => y.replace(regex, (x) => map[x])));
}
I get Cannot read property 'map' of undefined
Thanks
function findReplace(values) {
var search_for = ["AA", "Caal"];
var replace_with = ["zz", "yy"];
var map = {};
search_for.forEach(function(item, i) {
map[item] = replace_with[i];
});
//map = { AA: 'zz', Caal: 'yy' };
const regex = new RegExp("(?<![^|])(?:" + search_for.join("|") + ")(?![^|])", "g");
range.setValues(values.map(fr));
function fr(input) {
return input.map(c => c.replace(regex, (x) => map[x]));
}
}
The code you got from your previous question works fine if you just change the range you're retrieving. So instead of creating a function to extract the column into an array, you can just adjust the range.
If the column you want to replace ('Segment') is the second one, then you can do the following changes.
From:
const col = ss.getRange(2, 3, ss.getLastRow()).getValues();
...
ss.getRange(2, 3, ss.getLastRow()).setValues(col.map(fr));
To:
const col = ss.getRange(2, 2, ss.getLastRow()).getValues();
...
ss.getRange(2, 2, ss.getLastRow()).setValues(col.map(fr));

Automatically increment value by search /compare and match two columns in Google Sheets Script

I currently have to manually enter Sheet1 column B, but I'd like to auto increment it every time the script runs.
I am using a Google Sheets script.
This part is working.
How it works:
Sheet2 column A is a drop down list imported from Sheet1 column A
if Sheet2 column B is anniversary of todays date Sheet 2 column F is automated to be 'reset'
the working script then deletes the rows in Sheet 2 where F is 'reset' and adds new rows for each to the bottom
Currently using this script
function writeupReset() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Sheet2');
var r = s.getRange('C:C');
var v = r.getValues();
for(var i=v.length-1;i>=0;i--){
if(v[0,i]=='reset'){
s.insertRowsAfter(251,1);
s.deleteRow(i+1);
}
}
}
Example of the working bits using todays date - 6/2/20
Sheet1 Sheet2 (before script) Sheet2 (after script)
A B A B C A B C
|---------------| |-------------------------| |-------------------------|
1 | name | resets | 1 | name | date | delet | 1 | name | date | delet |
|---------------| |-------------------------| |-------------------------|
2 | bill | 1 | 2 | bill | 6/2/19 | reset | 2 | alex | 9/5/19 | |
|---------------| |-------------------------| |-------------------------|
3 | mark | 5 | 3 | alex | 9/5/19 | | 3 | adam | 11/6/19 | |
|---------------| |-------------------------| |-------------------------|
4 | holy | 2 | 4 | adam | 11/6/19 | | 4 | tony | 12/1/19 | |
|---------------| |-------------------------| |-------------------------|
5 | tony | 0 | 5 | mark | 6/2/19 | reset | 5 | | | |
|---------------| |-------------------------| |-------------------------|
6 | alex | 2 | 6 | tony | 12/1/19 | | 6 | | | |
|---------------| |-------------------------| |-------------------------|
7 | june | 1 | 7 | | | | 7 | | | |
|---------------| |-------------------------| |-------------------------|
8 | jack | 0 | to 252 rows (last two hidden) to 252 rows (last two hidden)
|---------------|
9 | adam | 2 |
|---------------|
So how can I edit the script to automatically increment Sheet1 column B when the script deletes those 'reset' rows in Sheet1?
I believe your goal as follows.
You want to increase the values of the column "B", that the name is the same , in "Sheet1" when the rows with reset in "Sheet2" are deleted by the script.
In your case, the same names are included in the column "A" in "Sheet2".
You want to achieve this by modifying your script in your question.
For this, how about this answer?
Modification points:
In this case, it is required to know the values of "Sheet1" and compare them with the values of "Sheet2". The flow is as follows.
Delete rows in "Sheet2".
At that time, an object including the information of the deleted rows is created.
Increase values of the column "B" in "Sheet1".
The values of the column "B" are updated using the object, and the updated values are put to the sheet.
When above points are reflected to your script, it becomes as follows.
Modified script:
function writeupReset() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// 1. Delete rows in Sheet2.
var s = ss.getSheetByName('Sheet2');
var r = s.getRange('A1:C' + s.getLastRow()); // Modified
var v = r.getValues();
var obj = {}; // Added
for(var i=v.length-1;i>=0;i--){
if(v[i][2] == 'reset') { // Modified
s.insertRowsAfter(251,1);
s.deleteRow(i+1);
var name = v[i][0] // Added
obj[name] = obj[name] ? obj[name] + 1 : 1; // Added
}
}
// I added below script.
// 2. Increase values of the column "B" in Sheet1.
var sheet = ss.getSheetByName("Sheet1");
var range = sheet.getRange("A2:B" + sheet.getLastRow());
var values = range.getValues().map(([a, b]) => ([obj[a] ? b += obj[a] : b]));
range.offset(0, 1, values.length, 1).setValues(values);
}
Note:
In this modified script, it supposes that each value of the column "A" in "Sheet1" is the unique value in all values. From your question, I could understand like this.
If the sheet names of "Sheet1" and "Sheet2" are different from your actual situation, please modify them.
If your actual situation is different from the structure of your sample values in your question, this modified script might not work. So please be careful this.
References:
map()
setValues(values)

Determine if two coordinates are within desired radius

I'm working on aggregating my city's main big intersections with my city's collision data. What am trying to accomplish is to determine the number of accidents which happened in and around the intersection within a 20 meters radius.
Luckily, I'm already far off in the project and I have two tables in my database intersections and collisions
My intersections table:
--------------------------------------------
| id | city | Latitude | Longitude |
--------------------------------------------
| 1 | 1 | 34.44444 | 84.3434 |
--------------------------------------------
| 2 | 1 | 42.4666667 | 1.4666667 |
--------------------------------------------
| 3 | 1 | 32.534167 | 66.078056 |
--------------------------------------------
| 4 | 1 | 36.948889 | 66.328611 |
--------------------------------------------
| 5 | 1 | 35.088056 | 69.046389 |
--------------------------------------------
| 6 | 1 | 36.083056 | 69.0525 |
--------------------------------------------
| 7 | 1 | 31.015833 | 61.860278 |
--------------------------------------------
MY collisions table:
--------------------------------------------
| id | cause | Latitude | Longitude |
--------------------------------------------
| 1 | 1 | 44.44444 | 81.3434 |
--------------------------------------------
| 2 | 1 | 32.4666667 | 1.4666667 |
--------------------------------------------
| 3 | 1 | 42.534167 | 63.078056 |
--------------------------------------------
| 4 | 1 | 46.948889 | 62.328611 |
--------------------------------------------
| 5 | 1 | 45.088056 | 61.046389 |
--------------------------------------------
| 6 | 1 | 46.083056 | 63.0525 |
--------------------------------------------
| 7 | 1 | 41.015833 | 69.860278 |
--------------------------------------------
Note: Some fields were omitted for simplicity sake
As you can see, both tables posses latitude and longitude fields. Now to determine if intersection and collision coordinates are close, I thought of using a MySQL query that takes an id of an intersection which then queries the collisions table to get all collisions within 20 meters of the intersection.
What is this query (in MySQL or in Sequelize)?
Here's what I have now (it's in Sequelize using a MySQL database)
// api/collisions/{intersection_id}/count
exports.intersection_accident_count = (req, res) => {
intersection.findOne({where: {equipement: req.params.intersection_id}}).then(intersection => {
let intersectionLongitude = intersection.longitude;
let intersectionLatitude = intersection.latitude;
collision.count({where: {
longitude: {
$gt: intersectionLongitude
},
latitude: {
$gt: intersectionLatitude
},
}}).then(count => {
res.status(200).json({'number_of_accidents': count});
});
});
};
You should start with straightforward way:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_Distance_Sphere(POINT(i.Longitude, i.Latitude), POINT(c.Longitude, c.Latitude)) < #dist
)
This should give you results, however the query will not use any indexes at all and if you have many records it would be very slow.
You should think of adding geometry data types in your table:
ALTER TABLE `collisions` ADD COLUMN `Location` POINT;
UPDATE `collisions` SET Location = POINT(Longitude, Latitude);
ALTER TABLE `intersections` ADD COLUMN `Location` POINT;
UPDATE `intersections` SET Location = POINT(Longitude, Latitude);
You can add trigger so the Location will be populated automatically when you updating Longitude/Latitude.
Then:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_Distance_Sphere(i.Location, c.Location) < #dist
)
This would be a bit faster.
If you'd like to make it even faster, you can add another geometry poligon Area column into your intersection table and 'pre-build' areas (can be round for accuracy or square for speed).
After that you will be able to do something like this:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_WITHIN(c.Location, i.Area)
)

Hide rows in table A that appear in table B

I have Table (Employees) A:
+----+---------+
| ID | NAME |
+----+---------+
| 1 | ROBERT |
| 2 | JAMES |
| 3 | RICHARD |
| 4 | KANYE |
| 5 | DYLAN |
| 6 | JOHN |
| 7 | JEAN |
| 8 | LOKI |
| 9 | ADAM |
+----+---------+
And Table (Employees) B:
+----+---------+
| ID | NAME |
+----+---------+
| 1 | ROBERT |
| 2 | JAMES |
| 3 | RICHARD |
| 4 | KANYE |
| 5 | DYLAN |
+----+---------+
Those people are my "employees". The names from table B are all the employees on my database and the names from table A are all the employees that I've assigned to project n°1.
I would like to HIDE all names in Table B that already appear in Table A because I don't want to re-assign the same employee to project n°1.
How can I resolve this using jQuery?
a clientside check would be:
function compareLists(listA, listB){
var resultList = [];
listA.forEach(function(itemA){
listB.forEach(function(itemB){
if (itemB.name !== itemA.name)resultList.push(itemB);
}
}
return resultList;
}
or at the serverside (database):
select * from table_b where name not in (select name from table_a)
greetings
Normally you should do that on the server side using SQL as already answered. However, since you ask about javascript. This is the way to filter it at client side:
//collect list of names in A
var table = document.getElementById("TableA");
var names = []
for (var i = 0, row; row = table.rows[i]; i++) {
names.push(row.celss[1]);
}
//check names in B
table = document.getElementById("TableB");
for (var i = 0, row; row = table.rows[i]; i++) {
if(jQuery.inArray(row.cells[1], names) !== -1){
//show row
}else{
//hide row
}
}
I dont have that much knowlwdge in Jquery..
But this query increases perfomance in a large DB.
SELECT
FROM TableB
LEFT JOIN TableA ON TableB.name=TableA.name // id will be better than name
WHERE TableB.name IS NULL
Hope this helps

Categories

Resources