Excel, find max value for a collection of sequence - excel

In column A, I have a collection of sequential data.They all start from 1, but end with different numbers. I wish I can create a column B, which has the max number for each sequence. Is there any formula can help me do this? These numbers are in different cells.eg.A1=1 A2=2 A3=3.....
A 123123412
B 333444422

If the numbers aren't in the same cell and the sequences always start with 1 you can just look for the next 1 in the column and go back 1 (except for the last sequence where you need to find the last number in the column):
=IFERROR(INDEX(A$1:A$100,MATCH(1,A2:A$100,0)+ROW()-1),LOOKUP(999,A$1:A$100))
This is shorter but has to be entered as an array formula using Ctrl-Shift-Enter (CSE):
=INDEX(A1:A$99,MATCH(TRUE,A2:A$100<A1:A$99,0))
Non-CSE version
=INDEX(A1:A$99,MATCH(TRUE,INDEX(A2:A$100<A1:A$99,0),0))

Related

Numbering Based on Condition(s)

I'm trying to create auto numbering for Agents that are currently present and has numbers including zeroes 0 in 3rd or 4th column(zero meaning they don't get any stats but they are present)
Agents who has TEXT Value in the 3rd or 4th column are those who are not present (Ex: A = Absent, SL = Sick Leave, VL = Vacation Leave). Meaning, they should not be counted, therefore their value on 1st column should be blank, and therefore this should not stop the auto numbering for the rest of the agents below and should continue the count in sequence.
Can anyone help create formula that would fill the numbers on the 1st column automatically for those agents that are present and has value including 0 on column 3 or 4 (stats 1 or stats 2)?
To give more idea, I'm trying to show the current total number of agents who are currently present in this situation and will count their stats, and exclude all other agents who are not present and should not be counted.
Thank you!
Sequence Two Numeric Columns
Single Cell
In cell A3, a basic not spilling formula would be...
=IF(AND(ISNUMBER(C3),ISNUMBER(D3)),MAX(A$2:A2)+1,"")
... with the condition of a string in cell A2.
Without any conditions, you could try an improved version, similar to one of David Leal's suggestions:
=IF(AND(ISNUMBER(C3),ISNUMBER(D3)),
SUM(ISNUMBER(C$3:C3)*ISNUMBER(D$3:D3)),"")
Spill
In cell A3 you could use the following:
=LET(Data1,C3:C13,Data2,D3:D13,
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,""))
Line1: the inputs ('constants'), the same-sized single-column ranges
Line2: the zeros and ones, where the ones present the data of interest
Line3: the formula to replace the ones with the sequence and the zeros (errors due to division by zero) with an empty string
Converted to a LAMBDA, it could look like the following:
=LAMBDA(Data1,Data2,LET(
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,"")))(C3:C13,D3:D13)
Since it's such a long formula, you could create your own Lambda function by using this part...
=LAMBDA(Data1,Data2,LET(
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,"")))
... to define a name, e.g. SeqNumeric, when in the same cell, you could use
it simply with...
=SeqNumeric(C3:C13,D3:D13)
... instead.
Now you can use the function like any other Excel function anywhere in the workbook.
The Path
F3 =ISNUMBER(C3:C13)*ISNUMBER(D3:D13) - multiply: zeros-no, ones-yes
G3 =SCAN(0,F3#,LAMBDA(a,b,a+b)) - use the 'LAMBDA' helper function 'SCAN'
H3 =G3#/F3# - divide the 'scan' result by the zeros and ones
I3 =IFERROR(H3#,"") - convert the '#DIV/0!' errors to empty strings
The translation of the SCAN part could be something like the following:
Set the initial result a to 0.
Create a new array of the size of the initial array in F3#.
Loop through each element of the initial array, write its value to b, and replace a with the sum of a+b.
Write (the accumulated) a to the current element of the new array and repeat for the remaining elements of either array.
Return the new array.
Combine all of it in a LET.
J3 =LET(Data1,C3:C13,Data2,D3:D13,
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,""))
Convert to LAMBDA.
K3 =LAMBDA(Data1,Data2,LET(
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,"")))(C3:C13,D3:D13)
Copy the first part of the LAMBDA (note how it results in a #CALC! error since no parameters are supplied)...
L3 =LAMBDA(Data1,Data2,LET(
Data,ISNUMBER(Data1)*ISNUMBER(Data2),
IFERROR(SCAN(0,Data,LAMBDA(a,b,a+b))/Data,"")))
... and select Formulas -> Name Manager -> New to create your own function and finally use it with the following:
A3 =SeqNumeric(C3:C13,D3:D13)
You can try the following in cell A1:
=LET(B, B2:B12, C, C2:C12, f, 1*ISNUMBER(B*C),seq, SEQUENCE(ROWS(B)),
MAP(seq, LAMBDA(s, IF(INDEX(f,s)=0, "",SUM(FILTER(f, (seq<=s),0))))))
Here is the output:
A non-array version, expanding down the formula would be:
=IF(ISNUMBER(B2*C2), SUM(1*ISNUMBER(B$2:B2*C$2:C2)),"")
For the array version, it counts only if both columns Stat1 and Stat2 are numeric. The name f, has a value of 1 if the condition is TRUE, otherwise is 0. The MAP does the count if the index position of the f array is not zero, otherwise returns an empty string.
I think I got it.
This is the formula that I made
=IF(COUNTIFS(D2:BE2,"*",$D$1:$BE$1,TODAY())>0,"",MAX(A1:A$4)+1)
Countif criteria 1 = if the cell contains a letter and is counted > 0 then it will return blank, otherwise it will start the count using max function. The countif criteria 2 will will return the correct value according to the date today since the excel sheet has several data daily.

Extract a substring based on next column

I have 2 columns. A and B. In column B, I have values like XXDDSSSSS, the important thing here that X can appear 1 time or n number of times but it will always be followed by a number. i.e., VD32lasjdflsak or VDS34dfsadfllo. I want to populate Column A from Column B so that it has all letters from beginning till when the first letter appears i.e., in first example column A should have VD and in next example column A should have VDS
Not as cool as Aggregate, but does the trick!
=LEFT(B1,MIN(FIND({0,1,2,3,4,5,6,7,8,9},B1&"0123456789"))-1)
Try,
=LEFT(A2, AGGREGATE(15, 6, ROW($1:$9)/(CODE(MID(A2, ROW($1:$9), 1))<65), 1)-1)
The position is hard-coded as 1 through 9. This could be adjusted with INDIRECT to 1 through the length of the string if that is insufficient.

Difference between 2 values in a row in excel formula

How to get this in excel
excel table
F column is the result column
For the following answer I am going to assume you only ever have two numbers in any row, but they can be in any cell along the row and they are always greater than 0.
If you just wish to find the difference between the two numbers without worrying about which number is bigger, a simple equation using maximum and minimum can be used, eg in Cell F1 you would have
=MAX(A1:E1)-MIN(A1:E1)
However, from your example, it seems more likely that you want to know the difference between the first number and the second number.
The difficulty here, is that the cells in columns B, C and D could contain either the first number, the second number, or no number! The solution is to use the following equation in Cell F1
=(MAX(A1:E1)-MIN(A1:E1))*IF(MAX(A1:E1)=INDEX(A1:E1,MATCH(0,A1:E1,-1)),-1,1)
This formula works as follows:
We still start off with the simple difference between the max and min, and then this is multiplied by 1 or -1 depending on which way around the numbers are.
MATCH(0,A1:E1,-1)
This part of the equation looks along the row for a 0, and assumes they are in descending order, so it will return the position of the second number.
This is then inserted into the INDEX function and checked to see if it is the same as the maximum number and the IF function returns either -1 or 1 as required.
Paste this formula on F1, then copy to F2 and F3
=INDEX(A1:E1,MATCH(TRUE,INDEX(A1:E1<>"",),0)) - LOOKUP(9.99E+307,A1:E1)

Search a date in multiple date ranges and return the corresponding value

In sheet 1, I have a list of dates in Column A in chronological order. There are values corresponding to this list in Column B. There is another list of dates in sheet 2 and I want to add values from sheet 1 to these dates.
Sheet 1.
**Column A Column B
DATE Amount**
1. 10/01/2015 25,60,000
2. 10/02/2015 26,80,000
3. 01/03/2015 21,55,000
4. 30/03/2015 24,60,500
5. 30/04/2015 28,20,000
6. 30/06/2015 19,00,000
Sheet 2.
Column A Column B
1. 21/02/2015 21,55,000
2. 15/01/2015
3. 20/05/2015
4. 25/04/2015
For example: I need to look up 21/02/2015 in sheet 1 and column A and return the value corresponding to the next available date. So for 21/02/2015 I need the value corresponding to the next date available which is 01/03/2015 and the value is 21,55,000. If its 15/01/2015 I need the value of 10/02/2015 i.e. 26,80,000
What formula could I use for this?
You could use VLOOKUP, but it has some issues. So it is better to use INDEX and MATCH combination. In your case try this
=INDEX('Sheet 1'!$B:$B,MATCH(A1,'Sheet 1'!$A:$A,-1))
Sorry, my previous answer works only for descending order. Try this instead
=INDEX('Sheet 1'!$B:$B,MATCH(TRUE,('Sheet 1'!$A:$A-A1)=MIN(IF('Sheet 1'!$A:$A-A1>=0,'Sheet 1'!$A:$A-A1)),0))
Explanation: I hope that INDEX and MATCH are well explained in Office Support.
About the condition:
('Sheet 1'!$A:$A-A1)=MIN(IF('Sheet 1'!$A:$A-A1>=0,'Sheet 1'!$A:$A-A1))
What it means?
'Sheet 1'!$A:$A-A1
results in a difference between the value in the cell A1 and the cell in A column in Sheet 1.
MIN(IF('Sheet 1'!$A:$A-A1>=0,'Sheet 1'!$A:$A-A1))
says that if the difference is non-negative ('Sheet 1'!$A:$A-A1>=0), find the minimum of such numbers (MIN function).
And if these numbers are equal (MATCH function), then pick the corresponding number in column B (INDEX('Sheet 1'!$B:$B,...)).
Apology: In my previous answers I swapped the columns of your example. I hope it is now correct.
You can use vlookup with True rather than the widely used form with False
As ExcelEfendisi said you can use vlookup with range lookup enabled. A simple way to get the value at the next date rather than the prior one would be to push all the amount values down one row, but to avoid that it might be better to repeat the index values - like this
1 10/01/15 25,60,000 1
2 10/02/15 26,80,000 2
3 01/03/15 21,55,000 3
4 30/03/15 24,60,500 4
5 30/04/15 28,20,000 5
6 30/06/15 19,00,000 6
Then you can use two vlookups, the first one to get the index of the row with the date prior to the date you are interested in and a second one to extract the balance value for the subsequent date - not very elegant but it would work
Try this formula (enter in Sheet2 cell B2 then copy till the last record)
=INDEX(Sheet1!$B:$B,1+MATCH($A2,Sheet1!$A:$A,1),1)
As data is sorted in ascending order use MATCH with match type 1 (less than) to obtain the row above the high next item, then add 1 and the result is the high next row, use this row to get the corresponding record from the column B with formula INDEX

Sort Order formula to alphabetise in Excel

I am currently drawing up a spreadsheet that will automatically remove duplicates and alphabetize a list:
I am using the COUNTIF() function in column G to create a sort order and then VLOOKUP() to find the sort in column J.
The problem I am having is that I can't seem to get my SortOrder column to function properly. At the moment it creates an index for two number 1's meaning the cell highlighted in yellow is missed out and the last entry in the sorted list is null:
If anyone can find and rectify this mistake for me I'll be very grateful as it has been driving me insane all day! Many thanks.
I'll provide my usual method for doing an automatic pulling-in of raw data into a sorted, duplicate-removed list:
Assume raw data is in column A. In column B, use this formula to increase the counter each time the row shows a non-duplicate item in column A. Hardcord B2 to be "1", and use this formula in B3 and drag down.
=if(iserror(match(A3,$A$2:A2,0)),B2+1,B2)
This takes advantage of the fact that when we refer to this row counter in our revised list, we will use the match function, which only checks for the first matching number. Then say you want your new list of data on column D (usually I do this for display purposes, so either 'group-out' [hide] columns that form the formulas, or do this on another tab). You can avoid this step, but if you are already using helper columns I usually do each step in a different column - easier to document. In column C, starting in C3 [C2 hardcoded to 1] and drag down, just have a simple counter, which error-checks to the stop at the end of your list:
=if(C2<max(B:B),C2+1," ")
Then in column D, starting at D2 and dragged down:
=iferror(index(A:A,match(C2,B:B,0)),"")
The index function is like half of the vlookup function - it pulls the result out of a given array, when you provide it with a row number. The match function is like the other half of the vlookup function - it provides you with the row number where an item appears in a given array.
Hope this helps you in the future as well.
The actual reason that this is going wrong as implied by Jeeped's comment is that you can't meaningfully compare a string to a number unless you do a conversion because they are stored differently. So COUNTIF counts numbers and text separately.
20212 will give a count of 1 because it is the only (or lowest) number.
CS10Z002 will give a count of 1 because it is the first text string in alphabetical order.
Another approach is to add the count of numbers to the count if the current cell contains text:-
=COUNTIF(INDIRECT("$D$2:$D$"&$F$3),"<="&D2)+ISTEXT(D2)*COUNT(INDIRECT("$D$2:$D$"&$F$3))
It's easier to show the result of three different conversions with some test data:-
(0) No conversion - just use COUNTIF
=COUNTIF(D$2:D$7,"<="&D2)
"999"<"abc"<"def", 999<1000
(1) Count everything as text
=SUMPRODUCT(--(D$2:D$7&""<=D2&""))
"1000"<"999"
(2) Count numbers before text
=COUNTIF(D$2:D$7,"<="&D2)+ISTEXT(D2)*COUNT(D$2:D$7)
999<1000<"999"
(3) Count everything as text but convert numbers with leading zeroes
=SUMPRODUCT(--(TEXT(D$2:D$7,"000000")<=TEXT(D2,"000000")))
"000999" = "000999", "000999"<"001000"

Resources