I am a newbie with coding and am trying to get the minimum value of a column (of a temporary sheet) and then copy that value and some data from the corresponding row to another sheet. For some reason it seems to work only once during the loop, is it because I'm trying to define a range based on an object?
function create_filter(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet1 = ss.getSheetByName("APperCountry");
const sheet2 =ss.getSheetByName("Tender");
var lanelist = sheet2.getRange(2, 1, sheet2.getLastRow(), 8).getValues();
var country = ('B:B');
var origin = ('E:E');
for(var i=2; i<=lanelist.length;i++){
Logger.log("Filter has been added.");
country = ('B'+i);
Logger.log(country);
var origin = ('E'+i)
var calc = ('M'+i);
var apname = ('N'+i);
const ori = sheet2.getRange(origin);
if(ori.isBlank()){
continue;
}
const range = sheet1.getRange("A:D");
const filter = range.createFilter();
var Ctry = sheet2.getRange(country).getValue();
const Filter_Criteria1 = SpreadsheetApp.newFilterCriteria().whenTextContains(Ctry);
const coll1 = 1;
const add_filter1 = filter.setColumnFilterCriteria(coll1,Filter_Criteria1);
const new_sheet = ss.insertSheet();
new_sheet.setName("AirportDistanceCalc");
var tempsheet = ss.getSheetByName('AirportDistanceCalc');
range.copyTo(new_sheet.getRange(1,1));
var aplist = new_sheet.getRange(2, 1, new_sheet.getLastRow()-1, 8).getValues();
new_sheet.getRange(1,5,1,1).setValue("Origin")
new_sheet.getRange(1,6,1,1).setValue("DistanceKM")
for(var j=0; j<aplist.length;j++){
Logger.log(origin);
ori.copyTo(new_sheet.getRange(j+2,5));
mainFun()
}
let comparisonRange = tempsheet.getRange("F2:F");
let comparisonRangeValues = comparisonRange.getValues().filter(String);
let minimum = comparisonRangeValues[0][0];
comparisonRangeValues.forEach((rowItem, rowIndex) => {
comparisonRangeValues[rowIndex].forEach((columnItem) => {
minimum = Math.min(minimum, columnItem);
});
});
console.log(minimum);
sheet2.getRange(calc).setValue(minimum);
tempsheet.getRange(minimum, 2).copyTo(sheet2.getRange(apname));
if (tempsheet) {
ss.deleteSheet(tempsheet);
}
filter.remove();
}
}
The minimum of a column
function mincolumn(col=1) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet1");
const min = sh.getRange(1,col,sh.getLastRow()).getValues().flat().filter(e => !isNaN(e)).sort((a,b) => a - b)[0];
Logger.log(min);
}
Related
I'm trying to get the quantity of for example: DragonBall, it would return x3 or Featured it would return x2 etc, however I have tried this method with just the spammed response of 2
let data = mockdata.forEach(function (i) {
count[i] = (count[i] || 0) + 1;
console.log(count[i] = (count[i] || 0) + 1)
});
[
'Daily',
'DragonBall1B',
'DragonBall2B',
'DragonBall3B',
'Featured',
'Featured2',
'SquadOrigins',
'SquadOrigins2'
]
API used to retrieve the above information:
https://fortnitecontent-website-prod07.ol.epicgames.com/content/api/pages/fortnite-game/shop-sections
A regular expression can remove the first instance of digits (along with whatever follows) to get you to the key you're interested in grouping on.
const mockdata = [
'Daily',
'DragonBall1B',
'DragonBall2B',
'DragonBall3B',
'Featured',
'Featured2',
'SquadOrigins',
'SquadOrigins2'
]
const count = {};
mockdata.forEach((str) => {
const key = str.replace(/\d+.*/, '');
count[key] = (count[key] || 0) + 1;
});
console.log(count.DragonBall);
const arr = [
'Daily',
'DragonBall1B',
'DragonBall2B',
'DragonBall3B',
'Featured',
'Featured2',
'SquadOrigins',
'SquadOrigins2'
]
const count = {};
arr.forEach((str) => {
const key = str.replace(/\d+.*/, "");
count[key] = (count[key] || 0) + 1;
});
let val = Object.entries(count);
let itemName;
let itemNum;
let result = [];
for (var i in val) {
itemName = val[i][0];
itemNum = val[i][1];
result += `${itemName} (x${itemNum})\n`;
}
console.log(result);
With this script I could export a spreadsheet to a excel file keeping formulas and a specific range that I need.
But I need also to keep the style of the spreadsheet like colors, row height, text style...
What to add then to the code below?
function downloadXLS_GUI() {
var sh = SpreadsheetApp.getActiveSheet();
var nSheet = SpreadsheetApp.create(sh.getName()+": copy");
var numCols = 10;
var d = sh.getRange(1,1,sh.getLastRow(),numCols);
nSheet.getSheets()[0].getRange(1,1,sh.getLastRow(),numCols).setValues(d.getValues());
["A3", "C3", "F3", "G3", "H3", "F5", "G5", "H5"].forEach(a1Notation => {
var sourceFormulas = sh.getRange(a1Notation).getFormulas();
nSheet.getRange(a1Notation).setFormulas(sourceFormulas);
});
var URL = 'https://docs.google.com/spreadsheets/d/'+nSheet.getId()+'/export?format=xlsx';
var htmlOutput = HtmlService
.createHtmlOutput('Clicca qui per scaricare')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(380)
.setHeight(160);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Scarica Allegato 2 in Excel');
}
Update 2
For copying styles between different sheets you can use this method.
function downloadXLS_GUI() {
const numCols = 10
const sh = SpreadsheetApp.getActiveSheet();
const nSheet = SpreadsheetApp.create(sh.getName() + ": copy");
const o_range = sh.getRange(1, 1, sh.getLastRow(), numCols)
const c_range = nSheet.getSheets()[0].getRange(1, 1, sh.getLastRow(), numCols)
// Get the values and styles from the original
const v = o_range.getValues()
const b = o_range.getBackgrounds()
const c = o_range.getFontColors()
const f = o_range.getFontSizes()
// Set the values and styles to the copy
c_range.setValues(v)
c_range.setBackgrounds(b)
c_range.setFontColors(c)
c_range.setFontSizes(f)
const formulaA1Notation = ["A3", "C3", "F3", "G3", "H3", "F5", "G5", "H5"]
formulaA1Notation.forEach(a1Notation => {
var sourceFormulas = sh.getRange(a1Notation).getFormulas();
nSheet.getRange(a1Notation).setFormulas(sourceFormulas);
});
var URL = 'https://docs.google.com/spreadsheets/d/' + nSheet.getId() + '/export?format=xlsx';
SpreadsheetApp.getUi()
.showDialog(
HtmlService
.createHtmlOutput(`Download`)
)
}
Why not use the copy method?
Copies the spreadsheet and returns the new one.
Instead of copying a certain range, you copy it all and get rid of what you don't need.
For example:
Code.gs
function downloadXLS_GUI() {
const ss = SpreadsheetApp
.getActiveSpreadsheet()
.copy("new_copy")
const sheet = ss.getSheets()[0]
const numRows = 10;
sheet
.getRange(1, numRows + 1, sheet.getLastRow(), sheet.getLastColumn())
.clear()
const URL = `https://docs.google.com/spreadsheets/d/${ss.getId()}/export?format=xlsx`;
SpreadsheetApp.getUi()
.showDialog(
HtmlService
.createHtmlOutput(`Download`)
)
}
Documentation
clear()
I have a problem. I got one to save the data called in a loop to an empty json. It's about "eventsPolygon". One args with index 0 will have to be written to JSONA. How to do it?
async function main() {
console.log("Start checking rewards")
const currentBlockNumberPolygon = await maticProvider.getBlockNumber() - 1
const currentBlockNumberBsc = await bscProvider.getBlockNumber() - 1
const oldestBlockNumberPolygon = 22939848
const oldestBlockNumberBsc = 13763979
const eventFilterPolygon = Missions.filters.RewardToPay()
const eventFilterBsc = Rewards.filters.RewardPayed()
let eventsPolygon = []
let eventsBsc = []
for(let i = oldestBlockNumberPolygon; i < currentBlockNumberPolygon-10000; i+=10000) {
const eventsLoop = await Missions.queryFilter(eventFilterPolygon, i, i+10000)
eventsPolygon = eventsPolygon.concat(eventsLoop)
console.log(i)
}
//for(let i = oldestBlockNumberBsc; i < currentBlockNumberBsc-10000; i+=10000) {
//const eventsLoop = await Rewards.queryFilter(eventFilterBsc, i, i+10000)
// eventsBsc = eventsBsc.concat(eventsLoop)
//console.log(i)
//}
console.log('a')
}
when iterating if your certain that you need the zero index you could just make a condition inside your loop, if(i == 0){wanted action}
I have some vars that some time have value as "Infinity".
I need to check if the value of the var is "Infinity" if is true assign value as 0 to that var. i want to do a for loop there are many vars that i have to check. the value of account3 have to be 0.
var account1 = 111;
var account2 = 222;
var account3 = Infinity;
var account4 = 444;
Create an array of your vars, then check each of them, with the isFinite() function.
var account1 = 111;
var account2 = 222;
var account3 = Infinity;
var account4 = 444;
const varArray = [account1, account2, account3, account4]
console.log('source array:', varArray)
const mapArray = (arr) => {
return arr.map(e => isFinite(e) ? e : 0)
}
console.log('modified array:', mapArray(varArray))
More about isFinite(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite
I have a problem.
How to get the filename from the url?
enter image description here
I wouldn't normally do this since you haven't shown us what you've tried, but I'm feeling generous.
This function should work for you. (Note that you'll need to grant permissions for it to run.)
function getFileNames() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Get_File_Name");
var links = sheet.getRange("A2:A").getValues();
var filenames = [];
for (var i = 0; i < links.length; i++) {
var url = links[i][0];
if (url != "") {
var filename = SpreadsheetApp.openByUrl(links[i][0]).getName();
filenames.push([filename]);
}
}
var startRow = 2; // print in row 2 since row 1 is the header row
var fileNameColumn = 2; // Column B = column 2
var destination = sheet.getRange(startRow, fileNameColumn, filenames.length, filenames[0].length);
destination.setValues(filenames);
}
Another way
function getFileNames() {
var driveApp = DriveApp;
// SET THE SHEET HERE
var sheet = SpreadsheetApp.getActive().getSheetByName("Sheet1");
//SET THE URL LINK COLUMN HERE : From row 2 since row 1 is the header row till last row
var links = sheet.getRange("P2:P").getValues();
var filenames = [];
for (var i = 0; i < links.length; i++) {
var fileId = getIdFromUrl(links[i][0]);
if (fileId != "" && fileId != null) {
var getfile = DriveApp.getFileById(fileId);
var filename = getfile.getName();
Logger.log(filename);
filenames.push([filename]);
} else {
filenames.push([""]);
}
}
// SET STARTING ROW TO PRINT: From row 2 since row 1 is the header row
var startRow = 2;
// SET WHICH COLUMN TO PRINT : Column A = column 1 / Column B = column 2
// MAKE SURE THE SHEET LAST COLUMN HEADER IS FILLED + 1 (next column)
var fileNameColumn = sheet.getLastColumn() + 1;
var destination = sheet.getRange(startRow, fileNameColumn, filenames.length, filenames[0].length);
destination.setValues(filenames);
}
function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
You can create a custom function in spreadsheets like this.
function getSSName(name) {
var ss = SpreadsheetApp.openByUrl(url);
return ss.getName();
}