Generate two false Booleans every ten rows in excel - excel

I need to add a column to my spread sheet that generates two "false" at random intervals every ten frames.
So for example rows 1 though 10 could read:
true
true
true
False
true
false
true
true
true
true
and then repeat that for rows 11 through 20, but the false are randomly put in different places. etc. I want write a formula that does this for me.

With Office 365:
In first cell you want the list to be created put:
=LET(rws,1000,arr,RANDARRAY(10,rws/10),seq,SEQUENCE(rws,,0),INDEX(MAKEARRAY(10,rws/10,LAMBDA(i,j,INDEX(BYCOL(arr,LAMBDA(v,MATCH(SMALL(v,i),v,0))),1,j)<9)),MOD(seq,10)+1,INT(seq/10)+1))
Change the 1000 to the number of rows desired.
If one does not have Office 365 then put this in the second row of a column and copy it down.
=IF(COUNTIF(INDEX(A:A,MIN(ROW($ZZ1)-MOD(ROW($ZZ1)-1,10)+1,ROW()-1)):INDEX(A:A,ROW()-1),FALSE)>=2,TRUE,IF(COUNTIF(INDEX(A:A,MIN(ROW($ZZ1)-MOD(ROW($ZZ1)-1,10)+1,ROW()-1)):INDEX(A:A,ROW()-1),TRUE)>=8,FALSE,RANDBETWEEN(0,9)<8))
Be aware:
Each cell is randomly chosen and as such FALSE will appear in the last of the 10 more often than truly random. One can play with the RANDBETWEEN(0,9)<8 to maybe make that more random.

BRUTE FORCE METHOD
There are 10!/(8!*2!) = 45 ways of arranging your True/False requirements
I personally didn't have anything better to do with my time so I wrote out all possible combinations in 45 columns.
The concept with this methodology is to randomly write out one of the 45 columns every 10 rows. One of the problems here is that using random in a formula does not mean you will be able to use the same random value in the next row of the formula.
A potential random problem side step
In order to make a random result accessible by multiple formula calculations one can spit out the results in a helper column. For this solution we will be randomly selecting from 45 possible columns, so in the first column the following formula is used and copied down. The number of rows will be equal to the number of 10 groupings you will use.
Start in A1 and copy down
=RANDBETWEEN(1,45)
How to make each formula in a group of ten pick the same random number
For demonstration purposes the next column is to generate integers starting at 1 and increasing by 1 after every 10 rows. For the demonstration it would need to be copied down a number of rows equal to the number of results needed (10 * number of groups of 10). Ultimately this formula can be embedded in the final formula.
Start in B1 and copy down
=INT((ROW(A1)-1)/10)+1
For demonstration purposes the next column is to generate integers starting at 1 and increasing by 1 row but resetting to 1 after the 10th row. For the demonstration it would need to be copied down a number of rows equal to the number of results needed (10 * number of groups of 10). Ultimately this formula can be embedded in the final formula.
Start in C1 and copy down
=MOD(ROW(A1)-1,10)+1
So now there is a way of indexing the column you need and what row of that column you need.
Indexing the solution
In the next column the index function is used (twice) to find out what column and row to look in from the list of all possible combination. In this demo, the list of all possible combination is written out from F1:AX10.
First we start by indexing which random column to use. Since the random numbers are written in column A starting in row 1 I used the following formula:
=INDEX(A:A,B1)
To get the row reference I used the following formula:
=C1
I then took those two formulas and combined them to pull data from the possibility table as follows:
Start in D1
=INDEX($F$1:$AX$10,C1,INDEX(A:A,B1))
Tidying it up
We can't eliminate the random number column as we need something quasi static for the formulas to refer to. The reason I say quasi static, random is a volatile function which means it will recalculate every time the sheet recalculates. However, we can place the formulas from B and C into D. This results in the formula in D looking like:
=INDEX($F$1:$AX$10,MOD(ROW(A1)-1,10)+1,INDEX(A:A,INT((ROW(A1)-1)/10)+1))

It's not clear which version of Excel you're using so this approach will work for all versions:
the starting point is C12:L13, where the formula in row 12 is
=RANDBETWEEN(1,5)
and the formula in row 13 is
=RANDBETWEEN(6,10)
These results determine the positions of the FALSE values in the range starting with cell C1 where the formula is
=NOT(OR(ROW()=C$12,ROW()=C$13))
The array formula in A1:A10 is
=INDEX($C$1:$L$10,,1+MOD(RANDBETWEEN(1,100),10))
column B is just an indexing column containing the formula
=1+MOD(ROW()-1,10)
which, coupled with the conditional formatting in column A illustrates that the positions of the FALSE values are different in each 10-row sequence.
(you will notice that the random numbers generated in columns I and J happen to be the same so, if this is a concern, you could extend the 'helper range' beyond 10 columns in order to augment randomness)

Related

Get last 5 values ignoring blanks excel

So I have data consisting of the following:
there are multiple more rows.
Im trying to retrieve the last 5 values in a row, for further use.
I can do this with a simple INDEX(MATCH()) setup, however that doesn't ignore the blank cells, which I would like it to do. It does successfully detect the first nonblank cell and returns that, however when it's blank in the middle of the 5 most recent, it doesn't remove that.
something like this is what it does now:
however i want it to come back in this format:
and so on. A blank could occur at any position, and there may not always be 5 scores available to retrieve.
TIA
You could use the following array-formula (entered with ctrl+shift+enter in older Excel versions):
=INDEX(1:1,AGGREGATE(14,6,COLUMN(A:G)/(A1:G1<>""),{5,4,3,2,1})) copied down.
Aggregate creates an array of the column numbers divided by 1 or 0 (TRUE or FALSE). Divided by 0 results in an error and gets ignored. It then takes the 5th largest to the largest column number without error and returns that as an array on the indexed row.
Where 1:1 represents the first row and A:G represents the first to last column used.
If you would want it on row 2 and column A:Z you'd have to amend it like this:
=INDEX(2:2,AGGREGATE(14,6,COLUMN(A:Z)/(A2:Z2<>""),{5,4,3,2,1}))
Different approach - using the new Excel 365 formulas:
This will return the values of the last five non-empty cells of row 2
=LET(
data,FILTER(B2:H2,B2:H2<>""),
cntData,COUNT(data),
matrix,SEQUENCE(1,MIN(cntData,5),IF(cntData>5,cntData-4,1)),
INDEX(data,1,matrix)
)
data returns all values except empty cells using the FILTER- formula
cntData holds the number of cells
using SEQUENCE a matrix is build that will return the column-indices to be returned. In case less then 5 values are available, the matrix returns 1 to cntData.
finally this "index-matrix" is used to return the values from the filtered data
This could be enhanced, by storing the number of cells to be returned within a named cell - and referencing this name in the formula. By that you could easily alter the number without altering the formula.

Return a random order of a list into a single cell

I have a list: [a,b,c,d,e]
I want to return a random order of this list into an individual cell, 20 times. I have only been to use =Rand() to pull random integers for each value and sort multiple cells randomly.
In the end i want a random order of the list in an individual cell. I cant seem to figure it out:
|a,b,c,d,e|
|b,d,e,a,c|
|c,a,b,e,d|
...etc
In office 365 Excel put this in the first cell and copy down 20 rows:
=TEXTJOIN(",",,INDEX($A$1:$A$5,UNIQUE(RANDARRAY(1000,1,1,5,TRUE))))
Older version we will need 5 helper columns.
In a column which is right of a blank column we put:
=INDEX($A:$A,AGGREGATE(15,7,ROW($1:$5)/(COUNTIF($B1:B1,$A$1:$A$5)=0),RANDBETWEEN(1,6-COLUMN(A1))))
Then copy that over 5 columns and down 20.
Then it is just a matter of concatenation:
=C1&","&D1&","&E1&","&F1&","&G1

IF + AND + Date range formula

I have a problem to create a formula so I want to ask you for your help.
Excel sheet has 150 000 rows and with this formula I want to safe a time.
I have a Date, Name and Status and I need to see in other cell which Name was 4x or more time in consecutive GOOD or OK
Example of input:
https://imgur.com/aRALd9S
I think IF + AND + DATE Range it’s enough, but I don’t know how to put it together.
Thanks a lot for your suggestions !
Here is what i have so far: https://imgur.com/Y5WAov5
=COUNTIFS($D$2:$D$15;D2;$C$2:$C$15;"OK";$D$2:$D$15;D2;$E$2:$E$15;">="&E2;$E$2:$E$15;"<="&E2+7)+(COUNTIFS($D$2:$D$15;D2;$C$2:$C$15;"GOOD"))
With this i'm able to count how many times i have a Name, which is OK or GOOD and is in one week range, but i still don't know, what i have to change, that i will stop to count when false is there
Well here's something you could try. You could do it in one formula with an array formula, but with 150K rows it seems much better to try and avoid array formulas and use helper columns where necessary.
The first helper column just contains the person's ID if the row contains FALSE:
=IF(H2=FALSE,I2,"")
The second helper column contains the offset from the current row to the next FALSE for the same person:
=IFERROR(MATCH(I2,K2:K$15,0)-1,16-ROW())
So now you can use basically your same COUNTIFS formula but replacing each range with an INDEX which specifies how many rows you should count:
=IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$15,L2),I2,H2:INDEX(H2:H$15,L2),"GOOD",J2:INDEX(J2:J$15,L2),">="&J2,J2:INDEX(J2:J$15,L2),"<="&J2+7))+
IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$15,L2),I2,H2:INDEX(H2:H$15,L2),"OK",J2:INDEX(J2:J$15,L2),">="&J2,J2:INDEX(J2:J$15,L2),"<="&J2+7))
Note 1
The 16 in the second equation is to allow for the case where there are no more rows labelled FALSE after the current row, so the MATCH fails. This makes the Countifs count everything from the current rows to the end of the data.
Note 2 - expanding to a larger range of data
You should be able replace the figure 16 with countA(I:I), the size of the data plus headers.
There shouldn't be a problem with using a larger range for the Index e.g.
=IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$150000,L2),I2,H2:INDEX(H2:H$150000,L2),"GOOD",J2:INDEX(J2:J$150000,L2),">="&J2,J2:INDEX(J2:J$150000,L2),"<="&J2+7))+
IF(H2=FALSE,0,COUNTIFS(I2:INDEX(I2:I$150000,L2),I2,H2:INDEX(H2:H$150000,L2),"OK",J2:INDEX(J2:J$150000,L2),">="&J2,J2:INDEX(J2:J$150000,L2),"<="&J2+7))
but increasing the search range in the MATCH to 150K rows in the second formula does seriously affect performance when repeated 150K times. The only solution I can think of at the moment is to see if a maximum can be placed on the distance from any occurrence of a name to the next occurrence of the name with FALSE next to it.

Google Spreadsheet, SUM or MINUS of above cell in the column using ARRAYFORMULA in the first row

I'm learning to use array formulas and have been successful doing simple things like adding 2 columns together in a third column. For example, I can put =arrayformula(B:B+C:C) in D1 and it adds B and C for each row.
But now I have a situation where I want to subtract two numbers in the same column. I want to take the value of that column in the current row and subtract the previous row's value from it. Without array formulas this is simple: in O7 I put =N7-N6 and cop that down so O8 gets =N8-N7, etc. But that requires copying down every time - can I do the same thing with an array formula?
Basically, can I do something like =arrayformula(B:B+(B-1):(B-1)) ?
Context: column N is a monthly account balance. I would like to calculate how much that balanced changed each month. So for row 7, =N7-N6 gives me that difference. But I'm changing the entire spreadsheet to array formulas so I can stop pasting all of the formulas and I'm stuck on this one since it's comparing the same column.
I'm trying to get everything into Row 1 so my values and calculations can start in Row 2. For example, here's one of my formulas in Row 1:
arrayformula(if(row(A:A)=1,"Total gross income",if(LEN(B:B),B:B+C:C,"")))
Unfortunately, in Column O (the one I asked about originally) if I do this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),N2:N-N:N,""))))
Or this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),offset(N:N,1,0)-N:N,""))))
Every row is off by 1 - the result that should go in Row 3 goes in Row 2, etc. And if I do this:
=arrayformula(if(row(A:A)=1,"Amount saved this month",if(row(A:A)>1,if(LEN(N:N),N:N-offset(N:N,-1,0),""))))
Then it gives me an error because the offset function is trying to evaluate something out of range (possibly it starts with N1 and tries to grab a value 1 row above N1?)
Any advice on how to handle that out-of-range error?
I think the error is because of offset range N:N which starts from N1 and you are trying to shift it -1 or one cell up, which brings the formula out of sheet.
Try this formula instead:
=arrayformula(
{"Amount saved this month";
if(LEN(N2:N),N2:N-offset(N2:N,-1,0),"")})
It uses {} to make an array. See more info:
https://support.google.com/docs/answer/6208276?hl=en
Bonus. There is no reason to check row number now.

Looking for formula to extract specific values from a row containing numbers and blanks

I have a sheet with rows of data, with many columns. I am looking for help on a formula that will extract the sum of the smallest 3 numbers in a row based on the last 5 values entered. Note that not all the rows will have values for each column, so the first value found on each row will may be found in a different column.
To determine the sum of the smallest 3 I am using the formula =SUM(SMALL(B3:R3,{1,2,3})), Unfortunately, that formula is looking at the entire range. Again, I am looking for help that with a formula that will select only the last 5 values posted.
Here is simple example. The results for each line show the totals that should be determined. Again, it needs to look for the sum of the smallest 3 based on the last 5 posted (in the example below the range would be col. 1 thru 10, with col 10 having the latest postings).
Ex.
1.....2.....3......4......5.....6.....7.....8......9.....10...... Result
31.........44....51....36..........44...34....36....38.......106 (34+36+34)
35..31...44...40.....38...52..........42....37...............115 (37+38+40)
Hope this is understandable. I am looking for a formula solution vs a VBA macro solution because of my users. Thanks for any help!!
Now that you clarified the question, I have an answer for you. This is fairly ugly but it gets the job done. You might want to hide the columns with the intermediate results - or you could get adventurous and "nest" the expressions. This makes it really hard to understand / debug though. If there's a smarter way to do this I am always open to learning.
Assuming you have the data in columns A through J, starting in row 2, put the following in cell L2:P2:
=MATCH(9999, A2:J2,1)
=MATCH(9999,OFFSET($A2,0,0, 1, L2-1)) ... copy this by dragging right to the next 2 columns
=MATCH(9999,OFFSET($A2,0,0, 1, M2-1))
=MATCH(9999,OFFSET($A2,0,0, 1, N2-1))
=MATCH(9999,OFFSET($A2,0,0, 1, O2-1))
The first line finds the last cell with data in it; the next ones find the last cell "not including the last cell", and so they work backwards. The result is a number corresponding to the columns with data. For your example, this gives
10 9 8 7 5
9 8 6 5 4
Now we want to find the sum of the smallest 3 of these: put the following equation in cell Q2:
=SUM(SMALL(INDIRECT("RC["&P2-17&"]:RC["&L2-17&"]",FALSE),{1,2,3}))
Working from the inside out:
RC["&P2-17"] results in RC[-12], which is "the cell 12 to the left of this one".
That is the first of the "last five cells with data", cell E2
RC["&L2-17"] results in RC[-7], the last cell with data in this row
FALSE use "RC" rather than "A1" indexing
INDIRECT turn string into an address (in this case a range)
SMALL find the 3 smallest values in this range
SUM and add them together.
This formula did indeed give me 106, 115 for the example you provided.
I would hide columns L through P so you only see the result (and not the intermediate stuff).

Resources