I got a problem with my Excel, where it shows a same name twice, if the 'racers' have the excact same time. For example in the picture the racers 7 & 9 and racers 5 & 10 have the same time, but in the Start grid it shows the same name twice. It should be 4. Racer7 5. Racer9 & 9. Racer5 10. Racer10
The Function of Cell I3 =IF(OR(ISBLANK(B3);ISBLANK(C3));"";INDEX($B$3:$B$32;MATCH(J3;$D$3:$D$32;0))) (I have to use format ';' instead of ',') Function of cell J3 =IFERROR(SMALL($D$3:$D$32;H3);"")
Link to the file (does not work in Google Sheets & the functions have to use local formatting)
xlsx file
MATCH and RANK Getting Sick When Handling Time
Formulas
COMMA
[D3] =IF(NOT(ISNUMBER(C3)),"",ROUND($D$1-A3*"00:10,0"-C3,8))
[H3] =IF(ISNUMBER(K3),RANK(J3,D$3:D$32,2),"")
[I3] =IF(IFERROR(INDEX($B$3:$B$32,SMALL(IF($D$3:$D$32=J3,ROW($J$3:$J$32)-ROW(J$3)+1),COUNTIF($J$3:$J3,J3))),"")=0,"",IFERROR(INDEX($B$3:$B$32,SMALL(IF($D$3:$D$32=J3,ROW($J$3:$J$32)-ROW(J$3)+1),COUNTIF($J$3:$J3,J3))),""))
[J3] =IFERROR(SMALL($D$3:$D$32,A3),"")
[K3] =IFERROR(J3-J$3,IF(I3="","","disqualified"))
COLON
[D3] =IF(NOT(ISNUMBER(C3));"";ROUND($D$1-A3*"00:10;0"-C3;8))
[H3] =IF(ISNUMBER(K3);RANK(J3;D$3:D$32;2);"")
[I3] =IF(IFERROR(INDEX($B$3:$B$32;SMALL(IF($D$3:$D$32=J3;ROW($J$3:$J$32)-ROW(J$3)+1);COUNTIF($J$3:$J3;J3)));"")=0;"";IFERROR(INDEX($B$3:$B$32;SMALL(IF($D$3:$D$32=J3;ROW($J$3:$J$32)-ROW(J$3)+1);COUNTIF($J$3:$J3;J3)));""))
[J3] =IFERROR(SMALL($D$3:$D$32;A3);"")
[K3] =IFERROR(J3-J$3;IF(I3="";"";"disqualified"))
Why is MATCH 'miscalculating' to '7' instead of '6' in cells 'I6' and 'I7' in OP's worksheet (formula in 'D3')?
Time has a ton of decimals so I guess it's 'seeing' the values in 'D8' and 'D9' as different values. To avoid this you can round the values. If you want to use only these values it is enough to round them to 8 decimals for the numbers to be recognized as different even by a millisecond. If you want to sum them there might be some inaccuracies. In OP's case 8 decimals is more than enough.
RANK (formula in 'H3') is also 'miscalculating' if no rounding.
Why the long formula?
Best try it with and without the IF statement and see for yourself.
Here's a Hint:
For this you need a tie breaker. The unfortunately best way of doing this is using a helper column. In my test sheet I used column E but the column could, of course, be anywhere. More importantly, it could be hidden. In this column you enter a formula like
=D3+ROW()/10^8
The point is that the addition must be so small that it makes no difference to the result on rounding. So, the number of results you treat in this may makes a difference. If you find that the addition changes the result in the last row, increase the exponent. The change I made add 0.0001 seconds to each result, multiplied by the row number: 0.0001 in the first row, 0.0002 in the second, 0.0003 in the third etc. Check the results in the 10th and 100th row.
Now the results in column E are all different and it's these results that are used in columns J and I.
[J3] =SMALL($E$3:$E$32,H3)
and
[I3] =INDEX($B$3:$B$32,MATCH(J3,$E$3:$E$32,0))
There will be no more duplicates but the "winner" of a draw is decided by his position in the list.
A solution in old school array-formula-style would be:
Note It's an array-formula which needs to be confirmed through CTRLSHIFTENTER
=IF(OR(ISBLANK(B3),ISBLANK(C3)),"",INDEX($B$1:$B$32,SMALL(IF($D$1:$D$12=J3,ROW($J$1:$J$12)),COUNTIF($J$1:$J3,J3))))
The IF checks the timelist for the current time value and gives all matching lines back which are getting ranked by small. COUNTIF counts the occurences of the current time up to the current line.
Related
So this needs a bit of detail:
n,X,X,X,n is in cells B5 to F5
I need to get the following output:
1n,3x,1n
for this particular row.
Now the n's and X's represent stitches in knitting with the "n" being the background color and the "x" being the front color.
There is an array of cells B5:F12 representing the rows and stitches, so each row will have a different arrangement of stitches or background color.
I need to avoid vba as this needs to be as stable as possible with the user being my Mum who is 90 years old :) and all she needs is a place to enter the name and the layout (which I have done) and a pattern list for each row (also sorted).
I have started to consider things like:
if(B5=C5,1&B5,"")
But given the n umber of combinations that becomes very long.
Any ideas? Cheers.
You could try:
Formula in H5:
=BYROW(B5:F12,LAMBDA(x,LET(z,REDUCE(VSTACK(TAKE(x,,1),1),DROP(x,,1),LAMBDA(a,b,IF(b=#TAKE(a,,-1),IF(COLUMNS(a)=1,VSTACK(b,TAKE(a,-1)+1),HSTACK(DROP(a,,-1),VSTACK(b,DROP(TAKE(a,,-1),1)+1))),HSTACK(a,VSTACK(b,1))))),TEXTJOIN(",",,DROP(z,1)&TAKE(z,1)))))
I'll see if I can golf the bytecount down a bit...
EDIT:
After a considerable amount of golfing (came down to 119), I came up with:
=BYROW(B5:F12,LAMBDA(x,MID(REDUCE("",x,LAMBDA(a,b,IF(RIGHT(a)=b,LEFT(a,LEN(a)-2)&1+LEFT(RIGHT(a,2)),a&",1")&b)),2,99)))
Though less dynamic than the 1st one, but possible due to the fact there are only <10 columns for each knitting pattern.
If your mother doesn't have the latest Excel (with LAMBDA etc), here is an alternative to #JvdV's answer which only uses LET,SEQUENCE and FILTER.
It only accepts a single row, so you'd need to fill the formula down.
=LET(p,LOWER(B5:F5),c,COLUMNS(p),s,SEQUENCE(,c),
a,IF(s=c,c,IF(INDEX(p,,s)<>INDEX(p,s+1),s,0)),
b,FILTER(a,a>0),t,SEQUENCE(,COLUMNS(b)),
n,IF(t=1,INDEX(b,,t),INDEX(b,,t)-INDEX(b,,t-1)),
TEXTJOIN(",",TRUE,n & INDEX(p,,b)))
I might add that it allows for adding more than one colour into the pattern ...
and with a bit of conditional formatting, the good lady can design her own multicolour patterns!
This is just a start of a solution, but in cell "B6" you can put the formula:
=(IF(B5=A5,A6+1,1))
This will generate following list:
B C D E F
5: n x x x n
6: 1 1 2 3 1
From there, you can try to get the Subtotals feature to work, based on the Max formula, ... (as I said, this is just a start).
If you are willing to spread the logic over multiple sheets, it's quite easy to come up with a way to do this. Consider a workbook with three sheets:
Pattern
EqualPrevCol, where each cell of Pattern is checked for equality against the previous column of the same row.
The formula for cell EqualPrevCol!D3 is:
=Pattern!D3=Pattern!C3
And finally PatternResult, where most of the logic resides:
Consider one row of EqualPrevCol:
At every FALSE column, we want to know how many columns until the next FALSE. To do this, we want to find the next exact MATCH for D3 in the rest of the row:
=MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0)
If no match is found, that means the rest of the row is all TRUE. In this situation, we want to return the length of the rest of the row plus this current cell.
=IFNA(MATCH(...), COLUMNS(D3:$H3))
And finally, we append this to the current character:
=IFNA(...) & Pattern!D3
Also, if the 7 row at this column is TRUE, we want to keep this blank:
=IF(EqualPrevCol!D3, "", IFNA(...) & ...)
The full formula of cell PatternResult!D3 is:
=IF(EqualPrevCol!D3, "", IFNA(MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0), COLUMNS(D3:$H3)) & Pattern!D3)
Finally, the pattern is condensed to the Pattern sheet. The Pattern!B3 cell contains:
=TEXTJOIN(", ", TRUE, PatternResult!D3:$H3)
To scale this up, you simply need to change all occurrences of $H in the formulas (this was a reference to the last column) and re-fill the cells on the latter two sheets.
My worksheet contains orders from clients. The orders are all wooden panels.
Every order is assigned a number which is led by the letter Q.
Column B contains the number of parts in the order.
Column C contains the total m² in the order.
Orders that contain one or more parts that are 2.8 x 0.0735 m will get a row of their own.
I'm trying to count the number of times that this part occurs in a list of more than a thousand rows.
So if I divide the total m² by the m² of the part I'm looking for and divide this by the amount of parts in the order, I should get exactly 1 as a result.
If I take the sum of all the number of parts that result in a 1, I get my total.
Now I'd like to put this in one formula for the entire worksheet, but SUMIF doesn't work the way I'm trying. (It's in Dutch)
=SOM.ALS(B:B;(C:C/(2,8*0,0735)/B:B)=1)
I can't seem to use this formula as a criterium in the SUMIF.
For now I use a helping column that gives the right amount per row. Then take the total SUM of these.
Is it possible to put this in a single formula?
Yes, it is possible. Try this one:
{=SUM(--(B:B=C:C/(2.8*0.0735))*IF(ISERROR(1/B:B),0,1))}
Remember to enter it as an array function with CNTRL + SHIFT + ENTER.
The first half of the formula is just a logical test, after the asterisk it tests if 1/B results in an error (thereby omitting text, zeroes, and blanks) and returns a zero if there is an error.
These are then summed and the result displayed.
In Dutch and English:
{=SOMPRODUCT(--(B:B=(ALS(ISTEKST(C:C);1;C:C))/(2,8*0,0735));B:B)}
{=SUMPRODUCT(--(B:B=(IF(ISTEXT(C:C),1,C:C))/(2.8*0.0735)),B:B)}
is working perfectly. (Enter with Ctrl-Shift-Enter)
The first bit is the logical test, which will check if B:B = C:C / (2.8*0.0735)
It got stuck on #VALUE! because there is text in C:C.
The IF(ISTEXT)) eliminates text by converting them to numeric values, in this case 1, but it can be any numeric value.
The logical test will return TRUE(1) or FALSE(0) because of the double dash or unary operator and this will be multiplied by their respective B:B value.
Because the row with text has no value in B:B, it will result as zero.
Currently. I have it set up when someone enters information in column E (Action Taken) then the whole row will turn yellow so it is easily seen that that item is being dealt with.
Another conditional format that I have set up is that once 5 working days pass on the date entered into column F (Date Actioned) then the row will turn red alerting the user to chase up the issue again.
Every week the user will contact more suppliers on the list regarding the listed product, and fill in their action taken and date actioned.
What I am looking to do is to add up all the suppliers contacted in one week (i.e. week 1 , 05.02.18 to 09.02.18) Which I know can be done by using the formula;
=COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018")
HOWEVER I only want to count each company once! So even though between the date 05.02.18 to 09.02.18, 8 actions were carried out, they only contacted 4 suppliers.
Is this possible? (FYI the screenshots attached are just a quick mock-up of the real document which contains thousands of products and more in-depth information).
If you don't mind adding a couple of working columns, the following is a possible solution:
Step 1
Set up two cells to contain the min and max dates for your range that you used in your formula =COUNTIFS(F4:F18,">=5/2/18",F4:F18,"<=9/2/2018"). This will allow you to up date things without having to recopy the formula each time. I used cells E1 and G1 for min and max date respectively.
Step 2
In a new column generate a list of supplier IDs that match your criteria. I arbitrarily chose column H. I placed the following formula in H4 and copied down:
=IF(AND(F4>=$E$1,F4<=$G$1),A4,"")
Step 3
In a new column generate a list of the count of the first time a supplier ID occurs from column H and do not count blank spaces. I arbitrarily chose column I. I placed the following formula in I4 and copied down:
=--(AND(COUNTIF($H$4:H4,H4)=1,H4<>""))
Step 4
Take the sum of the results from step 3. I arbitrarily chose to place the following formula in I19:
=SUM(I4:I18)
The "cop out" route, if you were only doing the calculation for 1 week would be to have a Pivot Table, with the Company as the Rows and the Date as the Columns. Then filter your columns, and you get a row per Company that week.
The Full route means looking into Array Formulae - you type one of these like normal, but instead of pressing [Enter], you press [Ctrl]+[Shift]+[Enter], and the equation will show in curly braces. (This is why they are sometimes called "CSE Formula" for "Control, Shift, Enter")
~Warning - This is a long walk through how I calculated the final formula. Hopefully it will make sense though!~
An array formula lets you iterate through every row in a range, calculate them seperately, and then add them all together at the end. This gives us the outside term - everything goes inside a =SUM(..). Press [Ctrl]+[Shift]+[Enter], and this will display as {=SUM(..)}
Now, what calculation do we want to be doing per row? Well, for every row where column F is within date, you want 1 per company within date. Well, another was to say "per" is "divided by" (hence the "Percentage" symbol being "0 / 0" or "%", and the lesser knows "Permille" symbol being "0 / 00" or "‰")
For the sake of reproducibility, I am going to assume that your Count is being done in Cell J2, and you have the Start/End of week dates in Cells H2 and I2
The formula for Row 4 would start out as =IF(AND(F4>=$H2,F4<=$I2), 1/???, 0), where ??? is how many times the Company on row 4 appears. Unfortunately, the AND function does not work with Array Formula. Fortunately there is an easy workaround - since boolean True/False can be treated as binary 1/0, the AND operator is the same as multiplication. Converting from boolean to binary is fastest by double-negation, so AND(F4>=H2,F4<=I2) can be rewritten as --(F4>=H2)*--(F4<=I2), which will work fine with array formula, giving us =IF(--(F4>=H2)*--(F4<=I2), 1/???, 0)
Now, before we work out what ??? should be, I'm going to skip down to row 18. There is method to this madness, I promise! Following the rules laid out above, the formula for row 18 is =IF(--(F18>=H2)*--(F18<=I2), 1/???, 0) - fairly simple? Now, if we want to run this for all rows from 4 to 18, we just need to join the ranges. So, you would get =IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0) Turning this into an Array Formula would get you an array of "1/???"s and "0"s, so add it together with SUM to get a single 'flat' number: =SUM(IF(--(F4:F18>=H2)*--(F4:F18<=I2), 1/???, 0))
Remember that "method" I mentioned earlier? Well, if we were looking for a straight Count of actions taken, ignoring the Unique Companies constraint, we could make ??? = 1, to get =SUM(IF(--(F4:F18>=$H2)*--(F4:F18<=$I2), 1, 0)) and hit [Ctrl]+[Shift]+[Enter] - which would give the same result as =COUNTIF(F4:F18, ">="&H2, F4:F18, "<="&I2) - and changing the 1 to D4:D18 would be a SUMIF on Products. (Incidentally, you can remove the IF statement from the CountIf, since the Condition returns 1 or 0 already)
So, last step! What is ??? Well, it's a Count of rows where Date Actioned is within our date bounds, and Company is the same as the current row. So, for Row 4 you have COUNTIFS(B4:B18, B4, F4:F18, ">="&H2, F4:F18, "<="&I2), and for Row 18 you get COUNTIFS(B4:B18, B18, F4:F18, ">="&H2, F4:F18, "<="&I2), making the final ??? become COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) (The trick here is that the Range arguments are treated as all the cells at once, but the Condition arguments are treated as an array of each cell one-at-a-time)
Now, some people might argue that you need to put your 1/COUNTIFS(B4:B18, B4:B18, F4:F18, ">="&H2, F4:F18, "<="&I2) inside an IFERROR to be safe - however, this is in the TRUE part of an IF statement referrring to the same row, so we know that if the COUNTIF is being evaluated then there will always be at least 1 row that matches.
So, if we stick it all together, and add a load of $ symbols to lock the rows/columns in place (so that you can drag down column J to calculate for different weeks/dates in columns H and I) you get the (slightly unwieldy) formula as follows:
=SUM(IF(--($F$4:$F$18>=$H2)*--($F$4:$F$18<=$I2), 1/COUNTIFS($B$4:$B$18, $B$4:$B$18, $F$4:$F$18, ">=" & $H2, $F$4:$F$18, "<=" & $I2), 0))
And, one last time - Don't forget to press [Ctrl]+[Shift]+[Enter]
(The 2 Date cells, $H2 and $I2 are the only terms I have left 'unlocked', and even then only on the Row)
I have the following formula to return the value of the last value in a column:
=LOOKUP(2,1/(D:D<>""),D:D)
What I need now is to return the value of the cell adjacent to it as well. (It will not necessarily be the last value in that column and the info in Column D could have duplicates.
If your data looks like this:
A 1
A 2
A 3
B 4
B 5
B 6
C 7
To get last value this will do the trick:
=INDIRECT("B"&COUNTA(A:A))
And to get last where value is A:
=INDIRECT("B"&MATCH("A",A1:A7,0)+COUNTIF(A1:A7,"A")-1)
Just use next column:
=LOOKUP(2,1/(D:D<>""),E:E)
Ok, So I have found an answer by playing around with array formulas.
The problem was that this is a stock control sheet where there are changes made at multiple times, each recorded in the next available row. There is always a date (Column E) but not necessarily a Supplier, as it might be stock moving out. When a Supplier delivers, the Supplier name is recorded in Column D. In D1 the last supplier is then shown with the following formula.
=LOOKUP(2,1/(D:D<>""),D:D)
I want to then see what date it was last received. The formula I found that works is as follows (Array Formula):
=INDEX(E:E,MAX(IF(D:D=D1,ROW(D:D)-ROW(INDEX(D:D,1,1))+1)))
This is generally how I do it:
=XMATCH(FALSE,ISBLANK(A:A),0,-1)
This is what each part does:
Parameter
Explanation
FALSE
Instructs Excel to find the first instance of FALSE that it finds
ISBLANK(A:A)
Takes in the column A:A and notionally assigns a value to every item in the column
0
Means we want an exact match. Probably not necessary to put in, but I think it's good practice anyway
-1
Instructs Excel to start the search at the bottom/right of the range and work up/left. If you change this to 1 (the default), Excel will begin the search at the top/left and work down/right
So, taken together, this will search from the bottom of the column A:A, until Excel finds the first cell that is not blank, and return that cell.
Also, yes, this equation can be changed to a row format (e.g. 1:1), and can take a smaller range (e.g. A1:A20), but it cannot take a 2-dimensional range (e.g. A1:B20).
As a practical matter, this approach is much faster than other approaches (and much faster than you'd think, given it's evaluating against every row/column in the range), and won't get fooled by columns that have empty spaces in them (like with a COUNTA style approach).
I am have a string with 6 spaces, e.g. 000000. Each space can hold one of three digits - 0, 1, or 2. I know that I can get a total of 120 permutations using the Permut function in Excel, i.e. =PERMUT(6,3) = 120. But I would actually like to have each individual permutation in a cell, e.g. 000001, 000010, etc.. Ideally, the end result would be 120 rows of unique 6-digit IDs.
Please help if you know a faster way of accomplishing this without entering the figures manually.
Thanks!
There is a VBA functionin the last post on this page. Copy it into a VBA module, then in Excel, create a column of integers from 0 to n where n = the number of IDs you want. In the next column, call the VBA function with the value from the first column as the first argument, and 3 as the second argument. Something like
Column A Column b
0 =baseconv(A1, 3)
1 =baseconv(A2, 3)
2 =baseconv(A3, 3)
... etc.
Your IDs are really just incremental values using a base 3 counting system. You can format the output to get leading zeros with a custom format of '000000'.
Incidentally, with 6 positions and 3 available values, you can get 3 ^ 6, or 729 unique IDs
First, I don't think you're using PERMUT correctly here. What PERMUT(6,3) gives you is the total number of ways to arrange three things picked out of a set of six things. So the result is 120 because you could have 6*5*4 possible permutations. In your case you have 3^6 = 729 possible strings, because each position has one of three possible characters.
Others have posted perfectly fine VBA-based solutions, but this isn't that hard to do in the worksheet. Here is an array formula that will return an array of the last six digits of the ternary (base-3) representation of a number:
=FLOOR(MOD(<the number>,3^({5,4,3,2,1,0}+1))/(3^{5,4,3,2,1,0}),1)
(As WarrenG points out, just getting a bunch of base-3 numbers is one way to solve your problem.)
You would drag out the numbers 0 through 728 in a column somewhere, say $A$1:$A$729. Then in $B$1:$G$1, put the formula:
=FLOOR(MOD(A1,3^({5,4,3,2,1,0}+1))/(3^{5,4,3,2,1,0}),1)
remembering to enter it as an array formula with Ctrl-Shift-Enter. Then drag that down through $B$729:$G$729.
Finally in cell $H$1, put the formula:
=CONCATENATE(B1,C1,D1,E1,F1,G1)
and drag that down through $H$729. You're done!