I have a range say A1:E5 in Excel and now in this column has values and some are null. My question is I will give the row number dynamically to the function and for that row the function should give me the first non blank value?
1 2 3
Row1 23
Row2 67
When i give 2 it should return 67, when i give 1 it should give 23?
Try this:
=INDEX($A$1:$E$5,H1,AGGREGATE(15,6,COLUMN($A$1:$E$5)/((ROW($A$1:$E$5)=H1)*($A$1:$E$5<>"")),1))
So the AGGREGATE() Function is Creates an array of Column numbers and Errors. When the Row number does not match H2 and/or the cell is empty it will return a divide by 0 error.
The first part of the AGGREGATE function 15 tells it we are looking for the small. The second, 6, tell it to ignore the errors, so no we have an array of only those column number that did not error. In H2's case it has an array of {2,3,4,5} from which it sends back the smallest to the Index Function.
The Index Function has three parts. The first is the Range. The second the row of that range, hence the H1. The third is the column Which we get From the Aggregate Function. In this case it would return 2 because it is the smallest.
So the Value that is at row 2 and column 2 in the range selected is 23.
Related
I have this (example):
Luffy 320
Coby 350
Zoro 180
Now I want to show the max from this info, with number and text (in seperate cells) like this:
col 1 col 2 col 3
1st 350 Coby
2nd 320 Luffy
3rd 180 Zoro
The 2nd Column no problem with the MAX() formula.
For the 3rd column to get the text I've tried the MAX(...) and INDEX(...) formulas but nothings working ...
Can anyone help me?
You first need to get which value is the largest, second largest and so on.
You can use the function LARGE(range, n) for this.
So in your col 2 use this formula:
=LARGE(B:B,1)
=LARGE(B:B,2)
=LARGE(B:B,3)
Assuming B is the column with the values.
Then we need to match this value and get the name
=INDEX(A:A,MATCH("the above calculated cell",B:B,0))
With the above calculated cell I mean the LARGE function cell. And assuming column A is the column with the names.
This should give you a dynamic table that will update when values or names change.
I'm not sure how you manage to get that column 2 using MAX formula since it only outputs the largest number of the inputs and thus can't output 2nd and 3rd position.
I've got a table in excel with 10 rows and 10 columns.
The table contains 100 different values between 1 and 3.
I want to find the highest sum of 10 values using only 1 value from each row and 1 from each column.
Do u guys know a function that finds the highest sum? - I've tried to do i manually, but there are to many combinations!
Hope it makes sense.
Thanks in advance:)
My solution builds on what I wrote in the comment, i.e. you first take the maximum value in the 10x10 array, then the maximum in the 9x9 array (excluding the row/column of the first maximum), etc. My solution tries not to do everything in one formula, but I add a few helper columns, and a bit more helper rows (it is fast and dirty, but it works and is easily audited/understandable). You always can do this on a separate worksheet which you could hide if needed.
The screenshot above goes from cell A1 till Y31.
The key formulas:
3.55 is the result of =MAX(B2:K11)
The first gray cell is =IFNA(MATCH($M12;B2:B11;0);""), and you drag this 9 cells to the left. This tries to find a match with the max result in each column of the table;
The 10 left of the 3.55 is =MATCH(TRUE;INDEX(ISNUMBER(P12:Y12);0);0) , and gives the column number of the max value.
The 2 next to the 10 is =INDEX(P12:Y12;N12) and gives the row number of the max value.
The 1 in cell B12 is =IF(OR(B$1=$N12;$A12=$O12);0;1), and creates a 10x10 matrix with a row and column with zeroes where the previous max value was found.
Then you multiply this with the preceding matrix and create a new 10x10 matrix below (enter {=B2:K11*B12:K21} array formula (ctrl+shift+enter) in B22-K31
You then copy/paste rows 12 till 31 9 times below
The 23.02 is the total sum =SUM($M$12:$M$211) from all 10 maximum values and is the result you are looking for. The 10 is just a check with =COUNT($M$12:$M$211)
how can I merge two columns of data into one like the following:
Col1 Col2 Col3
========================
A 1 A
B 2 1
C 3 B
2
C
3
You can use the following formula in column D as per my example. Keep in mind to increase the $A$1:$B$6 range according to your data.
=INDEX($A$1:$B$6,INT((ROWS(D$2:D2)-1)/2)+1,MOD(ROWS(D$2:D2)-1,2)+1)
Result:
Thank you to #Koby Douek for the answer. Just an addition--if you are using Open Office Calc, you replace the commas with semi-colons.
=INDEX($A$1:$B$6;INT((ROWS(D$2:D2)-1)/2)+1;MOD(ROWS(D$2:D2)-1;2)+1)
Expanding #koby Douek's answer to more columns and explaining some of the terms
Original Code for 2 columns to 1 alternating
=INDEX($A$1:$B$6,INT((ROWS(D$2:D2)-1)/2)+1,MOD(ROWS(D$2:D2)-1,2)+1)
$A$1:$B$6 Defines the columns and rows to source the final set of data from, the $s are only present to keep the formula from changing the columns and rows selects if it is copied and pasted or dragged.
To extend to work on any values you dump into the columns instead of having to expand the range every time it should be amended to $A:$B or A:B so you can easily copy it to other sets of columns and create new merges, but it will also give the 1st value in every column as one of the alternating values so if you instead have headers you would be able to do this by instead using a large number so $A$1:$B$99999 or A$1:B$99999 if you want to past and move the columns ymmv which is better by situation.
lets assume you are fine including the values in the 1st row
This changes the formula to
=INDEX($A:$B,INT((ROWS(D$2:D2)-1)/2)+1,MOD(ROWS(D$2:D2)-1,2)+1)
Now on to D$2:D2
This is the row that is being used to calculate the difference between the current row the formula is in (D2) and the reference row (D$2) The important thing to make sure you do is to set the reference row number to the 1st row you will be putting values in, so if your 1st row is a header in the sort column you will use the 2nd row as the reference, if your values in the combined column D begin on the 3rd row then the reference row would be D$3
Since I like the more general form where the 1st row isn't a header row I'll use D$1:D1 but you could still mix source rows without headers into a combined row with a header of as many rows as you like just by incrementing that reference row number to be the 1st row where your values should begin.
This changes the formula to
=INDEX($A:$B,INT((ROWS(D$1:D1)-1)/2)+1,MOD(ROWS(D$1:D1)-1,2)+1)
Now INT((ROWS(D$1:D1)-1)/2)+1 and MOD(ROWS(D$1:D1)-1,2)+1
INT returns an integer value so any decimal places are dropped, it essentially functions like rounding down to the nearest whole number
MOD functions by returning the remainder of a division, it's result will be a whole number between 0 and n-1 where n is the number we are dividing by. (eg: 0/3=0; 1/3=1; 2/3=2; 3/3=0; 4/3=1 ... etc)
So -1)/2)+1 and -1,2)+1
the first value is again the difference between the current row and the reference row. but D$1:D1 is going to be the count of the rows, which is 1 so we have to correct for the rows count starting at 1 instead of 0 which would throw off our calculations, so both are using the -1 to reduce the count of the rows by 1
in the case of /2 and ,2 both are because we are dividing by 2 in the first statement it's a normal division by 2 /2 in the modulus statement it's an argument of the Mod function so ,2
finally we need to add 1 using +1 to correct for the index's need to have a value series which begins at 1.
INT((ROWS(D$2:D2)-1)/2)+1 is finding the row number to select the value from.
MOD(ROWS(D$1:D1)-1,2)+1 is finding the column number to select the value from
Thus we can change /2 and ,2 to /3 and ,3 to do this with 3 columns
This yields:
=INDEX($A:$B,INT((ROWS(D$1:D1)-1)/3)+1,MOD(ROWS(D$1:D1)-1,3)+1)
So maybe that's the confusing way to look at it but it's closer to how my mind works on it. Here is an alternative view:
=INDEX([RANGE],[ROW_#],[COLUMN_#]) returns the value from a range of rows and columns
Using the example:
=INDEX($A:$B,INT((ROWS(D$1:D1)-1)/3)+1,MOD(ROWS(D$1:D1)-1,3)+1)
[RANGE] = $A:$B this is the range of source columns.
[ROW_#] = INT((ROWS(D$1:D1)-1)/3)+1
INT([VALUE_A])+1 returns an integer value so any decimal places are dropped. Then adds one to it. we add one to the value because the result of the next steps will be 1 less than the value we need.
[Value_A] = (ROWS(D$1:D1)-1)/3
ROWS(D$1:D1) returns the number of rows in the Range to the current row in the results column, we use D$1 to designate the row number where the values in the results column begin. D1 is the current row in the results column giving us a range from the source row, allowing us to count the rows. we have to subtract 1 from this value using -1 to get the difference between the source and current. This is then divided by /3 because we have three columns we want to look through in this example so we only change rows when the result is divisible by 3. the INT drops any decimal places as mentioned so it only increments when cleanly divisible by 3.
[COLUMN_#] = MOD(ROWS(D$1:D1)-1,3)+1
MOD([VALUE],[Divisor])+1 returns the remainder of the value when divided by the divisor.
Using the example:
MOD(ROWS(D$1:D1)-1,3)+1
In this case we still divide by 3 but it's an argument to the MOD function, we still need to count the number of rows and subtract 1 before dividing it, this will return a 0, 1, or 2 for the column, but as above we are shifted backwards by 1 as the column numbers begin with the number 1, so as before we must add 1
And here we add column A and D
two different formulas depending on if you add the formula to an odd row or an even row.
https://1drv.ms/x/s!AncAhUkdErOkguUaToQkVkl5Qw-l_g?e=5d9gVM
Odd Start row
=INDEX($A$2:$D$9;ROUND(ROW(A1)/2;0);IF(MOD(ROW()-ROW($A$2);2)=1;4;1))
Even Start row
=INDEX($A$2:$D$9;ROUND(ROW(A1)/2;0);IF(MOD(ROW()-ROW($A$1);2)=1;4;1))
What is A1 in the picture is the cell directly above your first data cell.
If you want to place it on a different sheet you just add the sheet name:
=INDEX(MySheet!$A$2:$D$9;ROUND(ROW(MySheet!A1)/2;0);IF(MOD(ROW()-ROW(MySheet!$A$2);2)=1;4;1))
=INDEX(MySheet!$A$2:$D$9;ROUND(ROW(MySheet!A1)/2;0);IF(MOD(ROW()-ROW(MySheet!$A$1);2)=1;4;1))
I want to get last non empty cell from every row for further operations. Searching Net I came across a LOOKUP formula which can do this job fine. I have alpha as well as numeric data in the rows.
Sample Data is shown below.
ID1 ID2 ID3 ID4 ID5 ID6 ID7 ID8 ID9 ID10 ID11
a1 a2 a3 a4 a5 23 24 25 25
23 NN 67 99 200001 ss p1 23 rq 3
I am using the following formula in L4 which gives correct results that is 3 in L4. Similar formula for row 2 gives result of 25 in L2.
To understand the formula I carried out Formula Evaluation but I am not getting the logic of last step as how it translates to final result.
=LOOKUP(2,1/(A4:K4<>""),A4:K4)
LOOKUP(2,{1,1,1,1,1,1,1,1,1,#DIV/0!,1},A4:K4)
After this step result that is the last non empty value of Row 4 comes i.e. 3
Can someone explain how this line is finally translating into the result step by step.
Basically taking the below formula as an example
=LOOKUP(2,1/(A1:D1<>""),A1:D1)
With data in A1:D1
A1 B1 C1 D1
1 2 3
The formula will populate as follows
=LOOKUP(2,{1,1,1,#DIV/0!},{1,2,3,0})
The way this works is quite simple.
1/(A1:D1<>"") creates an array of 1's and #DIV\0!
1 where the cell is not blank
#DIV/0 where the cell is blank
Then the lookup formula looks for a 2 in this array , which it cant find, but it will always return the position of then last NON ERROR value in the context of an array filled with 1's and #DIV/0!, which would be the 3rd position in the array, The LOOKUP formula then returns the 3rd position of the last argument array in the formula A1:D1 , which is 3
This approach finding the last filled cell uses the vector form of LOOKUP. In
=LOOKUP(2,{1,1,1,1,1,1,1,1,1,#DIV/0!,1},A4:K4) the 2 is the lookup_value, the array {1,1,1,1,1,1,1,1,1,#DIV/0!,1} is the lookup_vector and the A4:K4 is the result_vector.
The vector form of LOOKUP looks in a lookup_vector for the lookup_value and returns the value from the same position in the result_vector.
If the LOOKUP function can't find the lookup_value directly in the lookup_vector, the function matches the largest value in lookup_vector that is less than or equal to lookup_value. If multiple equal values are in the array, which are the largest which are less than or equal to lookup_value, the position of the last is taken. In this case it matches the last 1 since this is the largest value in lookup_vector that is less than or equal to 2.
But for this to do, there is the rule, that the values in lookup_vector must be placed in ascending order. And this is the not documented feature with this approach. It seams as if the #DIV/0! errors within lookup_vector does not contradict that rule. But since the source is not open, we can't be absolutely sure about this. But this approach is used sucessfully so often, that we can be very sure.
Assume I have the following table:
A B C
1 Week 1 Week 2
2 Melissa 114.7 82.8
3 Mike 105.5 122.5
4 Andrew 102.3 87.5
5 Rich 105.3 65.2
The names are in column A, the Week values are in Row 1. (So A1 is blank, B1 = Week 1, and A2 = Melissa.)
I'm trying to build a formula that looks at all the values in a known range (in this example, B2:C5), chooses the highest value of the bunch (here, 122.5) and returns the name of the person from Column A that got that value. If I use this formula, it works for the values in range B2:B5:
=INDEX(A2:A5,MATCH(MAX(B2:B5),B2:B5,0))
That returns Melissa but if I expand the range to include more than just column B's values, I get an #N/A returned:
=INDEX(A2:A5,MATCH(MAX(B2:C5),B2:C5,0))
The weird part (to my simple brain) is that the MATCH portion of the formula works fine, if I just put in this formula, it returns the highest value of 122.5 from C3:
=MAX(B2:C5,B2:C5,0)
So clearly something it going wrong when I'm using either the MATCH or INDEX commands.
Hopefully this makes sense and someone can point out my error?
Try this:
=INDEX(A:A,MAX((B2:C5=MAX(B2:C5))*ROW(B2:C5)))
This is an array formula and must be confirmed with Ctrl+Shift+Enter.
Note: Match can only search one vector at a time. It can be one row or one column or one array. It cannot be two or more rows or columns or a 2D array.
Do it "twice"? Please try:
=INDEX(A2:A5,IFERROR(MATCH(MAX(B2:C5),B2:B5,0),MATCH(MAX(B2:C5),C2:C5,0)))
If you are going to have up to 52/53 weeks to cope with I'd suggest instead inserting a helper column with the MAX for each row. Make that an new (inserted) ColumnA (say =MAX(C2:BC2) etc.) and a simple VLOOKUP should serve, say:
=VLOOKUP(MAX(A:A),A:B,2,0)