Reputation: 57
Need to amend my script so that the random values generated from my range won't repeat when the function "myFill" is triggered. The range currently has 32 values - but only 5 non repeated values are required each time when triggered. Those values can be included again next time the function is triggered.
Link attached.
As an overview, the Script below is used in conjuction with these formula on the spreadsheet
Cell B2 =myFill(1,5,"H2:H33",J18)
Cell B3 =iferror(ArrayFormula(vlookup(B2,$H$2:$I$33,2,0)))
Appscript:
function tst(){
var rows = 1
var cols = 5
var range = "H2:H33"
myFill(rows, cols, range)
}
function myFill(rows, columns, range) {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
Logger.log(rows)
Logger.log(columns)
Logger.log(range)
var rng = sheet.getRange(range).getValues()
var output1 = [], l = rng.length;
for(var i=0; i<rows; i++) {
var output2 = [];
for(var j=0; j<columns; j++) {
output2.push(rng[Math.floor(Math.random() * l)][0]);
}
output1.push(output2);
}
return output1;
}
Upvotes: 2
Views: 1246
Reputation: 18707
I wondered if it's possible to do it with formulas. The resulting formula is:
=ArrayFormula(VLOOKUP(QUERY(UNIQUE(RANDBETWEEN(ROW(INDIRECT("A1:A"&COUNTA(A:A)*10))^0,COUNTA(A:A))),"limit 5"),{ROW(INDIRECT("A1:A"&COUNTA(A:A))),FILTER(A:A,A:A<>"")},2,0))
Please look at this Sample file with explanations on how the formula works.
Upvotes: 1
Reputation: 5892
This code will give you unique set of letters i.e. no repeating set for each run. However, in my brief executions of the script never once encountered a repeat random number anyway!
function myFill(rows, columns, range) {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
Logger.log(rows)
Logger.log(columns)
Logger.log(range)
var rng = sheet.getRange(range).getValues();
var output1 = [], l = rng.length;
for(var i=0; i<rows; i++) {
var output2 = [];
for(var j=0; j<columns; j++) {
var isUnique = false
do {
var index = Math.floor(Math.random() * l)
if(rng[index][0] !== 0){ //Check if the value has been already been used.
output2.push(rng[index][0]);
rng[index][0] = 0; // Set a used value to zero
isUnique = true;
}
} while (!isUnique)
}
output1.push(output2);
}
return output1;
}
The way I achieve to get unique letters is by setting the value of the rng array to 0 if that particular value at that index has already been used. Then check index each time to check if it is zero if it not then use that value else generate a new random index.
Upvotes: 0
Reputation: 64042
Well I'm not sure what your trying to accomplish because your not doing anything with the return from myFills but this is a little more likely to work for you. Your were using "rng" as a range but getValues returns an array (2D). BTW random does not mean non repeating.
function tst()
{
var rows = 1;
var cols = 5;
var range = "H2:H33";
myFill(rows, cols, range);
}
function myFill(rows, columns, range)
{
var rows = (typeof(rows) !== 'undefined')? rows : null;
var columns = (typeof(columns) !== 'undefined')? columns : null;
var range = (typeof(range) !== 'undefined')? range : null;
var sheet = SpreadsheetApp.getActiveSheet();
var rngA = sheet.getRange(range).getValues();
var outputA = [];
var l = rngA.length;
for(var i=0; i<rows; i++)
{
outputA[i] = [];
for(var j=0; j<columns; j++)
{
outputA[i][j]=Math.floor(Math.random() * l);
}
}
return outputA;
}
Upvotes: 0