I'm trying to build a MATCH formula (or a similar one) that returns the position of the first value (date) within a range that matches a specific year.
For example, if I have a list of dates, like this:
A
1 12-31-2014
2 11-30-2015
3 12-29-2016
4 12-30-2017
For the value 2016, it should return 3.
MATCH(2016,A:A,0) doesn't work, since it's not an exact match. I can't use any aux columns either nor modify the dates.
Any ideas?
Are you allowed to use array formulas? If so, it may be as simple as this:
=IFERROR(MATCH(2016,YEAR($A$1:$A$4),0),"No Match")
Remember to commit the answer using Ctrl+Shift+Enter, since it'll be an array.
You'll want to change the references within the YEAR function to match your range. By using 0 as your [match_type] parameter, you're going to get the first value in the list that has a year of 2016.
For real dates, try,
=aggregate(15, 6, row($1:$999)/(year(a$1:a$999)=2016), 1)
'return the date with index as,
=index(a:a, aggregate(15, 6, row($1:$999)/(year(a$1:a$999)=2016), 1))
If they are in ascending order you could use,
=MATCH(42369, A:A)+1
=index(a:a, MATCH(42369, A:A)+1)
For a list of strings that look like dates try,
=MATCH("*2016", A:A, 0)
=index(a:a, MATCH("*2016", A:A, 0))
Related
I want the code value in column B if the handset matches and the date is between the date from and the date to.
How the results should look:
Since you problem involve Date Range, therefore Vlookup & Index match is not possible to solve, I will use If + AND formula to solve your problem:
=IF(AND(E9>$G$3,E9<$H$3,F9=$E$3),$F$3,
IF(AND(E9>$G$4,E9<$H$4,F9=$E$4),$F$4,
IF(AND(E9>$G$5,E9<$H$5,F9=$E$5),$F$5,
IF(AND(E9>$G$6,E9<$H$6,F9=$E$6),$F$6,""))))
If you are able to add a column, one possible solution without using VBA would be to use a combination of SUMIFS and XLOOKUP formulas.
In column E, add a unique identification number (e.g., 1, 2, 3, 4, 5, etc.). You could reference the row number or manually fill down the numbers or whatever. It wouldn't matter as long as the values are unique and all numbers (no text).
Then, use a SUMIFS formula to sum Column E if (1) the handset number matches, (2) the date is greater than or equal to the start date, and (3) the date is less than or equal to the finish date. As long as there are no overlaps in the date ranges for each handset, this will return the unique ID number. Depending on the dataset, you might have to play with the less/greater than or equal to vs just less/greater than.
=SUMIFS(E:E,A:A,I2,C:C,"<="&H2,D:D,">="&H2)
Then, use the XLOOKUP to return the code based on the unique ID. In this example, I combined the SUMIFS and XLOOKUP in one formula, but you could also do it in two columns to provide better visibility.
=XLOOKUP(SUMIFS(E:E,A:A,I2,C:C,"<="&H2,D:D,">="&H2),E:E,B:B,"NOT FOUND",0,1)
Here's an example.
screenshot
I'm evaluating my portfolio, and I make a record of it in some form like this:
I wish to get the profit% of those stocks, from either;
Stocks with sold: (Price at SELL/Price at BUY)-1
Stocks not sold: (Current Price/Price at BUY)-1
For 1), I was thinking of getting the Last Price (Col E) of Stock A by using VLOOKUP conditioning with 'Stock A' of Col B and a 'SELL' of Col C (then obviously using the VLOOKUP again with 'SELL' condition changed to 'BUY').
Is there a way to look up a value with two conditions? Any other suggestions (using a touch of VBA for eg) would be greatly appreciated.
A VLOOKUP is, in effect, a special form of INDEX MATCH (or XLOOKUP, from Office365 onwards). In other words, VLOOKUP("Value", A:C, 3, FALSE) is the same as INDEX(C:C, MATCH("Value", A:A, 0)), and VLOOKUP("Value", A:C, 3, TRUE) is the same as INDEX(C:C, MATCH("Value", A:A, 1))
Then, to create a VLOOKUP equivalent that checks multiple columns, we need to create a MATCH function to do the same. Fortunately, this is possibly using Array Calculations.
Essentially, we replace the second argument of the MATCH (the list of values to look for) with a formula which creates an Array based on our Conditions, and we Search the list for where the conditions are True. For example, if our Conditions are Column B = "Stock A" and Column C = "BUY", then our Array Calculation is (B:B="Stock A")*(C:C="Buy"), and our MATCH looks like this:
MATCH(1, (B:B="Stock A")*(C:C="BUY"), 0)
(At a Boolean or Bitwise level, * is the same as AND: TRUE*TRUE=TRUE, FALSE*FALSE=FALSE, TRUE*FALSE=FALSE)
Rather than using Entire Columns (which are Slow), it is often best to limit the number of rows. You can either do this manually:
=INDEX($E$1:$E$5, MATCH(1, ($B$1:$B$5="Stock A")*($C$1:$C$5="BUY"), 0))
Or you can do it dynamically with INDEX and COUNTA:
=INDEX($E$1:INDEX($E:$E, COUNTA($A:$A)), MATCH(1, ($B$1:INDEX($B:$B, COUNTA($A:$A)), ="Stock A")*($C$1:INDEX($C:$C, COUNTA($A:$A)), ="BUY"), 0))
Final note: the MATCH function will start at the top of the list, and work down until the first match. If these are in Date Order, and you want to find the last match, then Office356 users have the XMATCH function available, which has an extra argument used to decide if the search is First-to-Last (XMATCH(.., .., .., 1)), Last-to-First (XMATCH(.., .., .., -1)), Ascending Binary Search (XMATCH(.., .., .., 2)), or Descending Binary Search (XMATCH(.., .., .., -2))
Otherwise, you may have to use SUMPRODUCT to get the MAX date that matches your criteria, and include that in your MATCH conditions (SUMPRODUCT(MAX(A:A*(B:B="Stock A")*(C:C="BUY")))
Is there a way to look up a value with two conditions?
There is a very simple solution - you can concatenate (using &) the two columns holding conditions for your search into one and then base your VLOOKUP search on that column. Remember to put this concatenated column at beginning of your table.
If you can ensure that the combination Stock A - BUY and Stock A - SELL occur only once like in
and never twice like in
Then you can use the SUMIFS function to "lookup" the value. Because the sum of only one value will always be the value itself:
=SUMIFS(E:E,B:B,"Stock A",C:C,"BUY")/SUMIFS(E:E,B:B,"Stock A",C:C,"SELL") -1
To be sure there is only one entry per combination you can use the COUNTIFS to check it and return a warning in case of multiple entries (which would result in a false value):
=IF(AND(COUNTIFS(B:B,"Stock A",C:C,"BUY")=1,COUNTIFS(B:B,"Stock A",C:C,"SELL")=1), SUMIFS(E:E,B:B,"Stock A",C:C,"BUY")/SUMIFS(E:E,B:B,"Stock A",C:C,"SELL") -1,"multiple entries found")
I have seen plenty of posts for SUMIFS with or, but all the examples have a single criteria and an OR. This is usually done with an array like this:
=SUM(SUMIFS(sum_range,criteria_range,{"red","blue"}))
I need to be able to do that, but I need it to have multiple AND criteria and the OR using array or something similar
Like this:
=SUM(SUMIFS(sum_range,criteria_range1,criteria1,criteria_range2,{"red","blue"}))
But it doesn't seem to work.
Help please!
I'm showing you how it works with an example
Have the following table starting in A1:
a|0|1
a|1|2
b|0|1
b|1|2
b|0|1
c|0|1
c|0|1
Then you try this to sum values in the third column (C) where first column (A) is either "a" or "b" (result is 7):
=SUM(SUMIFS(C1:C7, A1:A7, {"a","b"}))
Then try this to sum values in the third column (C) where first column (A) is either "a" or "b" AND the value in second column (B) is 0 (result is 3):
=SUM(SUMIFS(C1:C7, B1:B7, 0, A1:A7, {"a","b"}))
Note that since these formulas contain an array, they are already array formulas. You don't need to force an array formula by using [ctrl]+[shift]+[enter].
In an excel sheet, I have from A1 to A6:
1, 2, 4, 6, 8, 9
I would like, using MATCH function, to retrieve the smallest interval that contains 5. Here, 4 and 6.
I can easily use the MATCH and INDEX function to find 4, but I can't find a way to find the 6.
How can I reverse the order of the Array in the MATCH function?
You still can use the composition of INDEX and MATCH by using #ExcelHero add one trick but you need to make sure the matched offset doesn't overflow your index. In many use cases, you could also protect your match against an underflow. Of course, we wouldn't need all this if MATCH didn't request a reverse (descending) order for the -1 (Greater than) match type argument or if Excel provided a formula for reversing an array.
My suggestion is to use the following formula for the MATCH
part:
=IF(N19 < INDEX(lookup_range, 1), 1, MIN(ROWS(lookup_range), 1 + MATCH(N19, lookup_range, 1)))
N19 is the cell holding the value you look up, lookup_range is the name of your lookup range, the condition refers to the first cell in the named range.
So all in all you can just do (adapt the formulas if you don't like named ranges):
# For the lower limit
=INDEX(lookup_range, IF(N19 < INDEX(lookup_range, 1), 1, MATCH(N19, lookup_range, 1)))
# For the higher limit
=INDEX(lookup_range, IF(N19 < INDEX(lookup_range, 1), 1, MIN(ROWS(lookup_range), 1 + MATCH(N19, lookup_range, 1))))
NOTA: You can also change the first argument of INDEX in these two formulas if you're interested in any other output range.
You could also try these two formulas:
=LOOKUP(1,0/FREQUENCY(-B1,-A1:A6),+A1:A6)
=LOOKUP(1,0/FREQUENCY(B1,A1:A6),+A1:A6)
Notes:
the list A1:A6 does not need to be sorted
if B1 is equal to one of the values in A1:A6 then both formulas return B1.
if B1 lies outside the range of values in A1:A6then one of the formulas returns #N/A
Use XMATCH, as explained on this site:
https://exceljet.net/formula/xmatch-reverse-search
XMATCH allows you to set the search direction, as follows:
=XMATCH(B1,A1:A6,0,-1)
Where B1 is the cell to match, A1:A6 is the array you are searching through, 0 indicates "exact match", and -1 selects searching in the reverse direction (starting with cell A6 and ending with A1).
I have an excel file like the following:
and I would like to replace the value of votes and avgsocre of those rows with Print = 1 with the rows I have in another file, which looks like the following:
The index number in the second file is exactly off by 1 and since there are also \N's with values from rows with Print = 0, so I cannot use replace then vlookup.
Would appreciate any help on this.
It looks like the variables that I'll call Design and Author uniquely identify your observations, so it would probably make more sense to look up Votes and AvgScore based on those values rather than trying to use the row-1 value in col A of the second file.
In your main file, make a column Votes_new with the formula (in this example, for row 2707):
{=INDEX(SecondFile!$A$1:$H$11, MATCH(1, (SecondFile!$B$1:$B$11=$A2707)*(SecondFile!$C$1:$C$11=$B2707)*(SecondFile!$G$1:$G$11=1), 0), 4)}
Use the same formula with 5 instead of 4 in the last argument in a column for AvgScore_new.
This formula matches on three criteria: Design (equal to the value in the current row), Author (equal to the value in the current row), and Print (equal to 1). It gets the value from the 4th column of the data in the second file, which is Votes (or the 5th column, which is AvgScore).
Note that you have to enter as an array formula using Ctrl+Shift+Enter.
Also note that this will return a #N/A error if there is no match (either because the Design-Author combination is not present or because Print is not equal to 1) so you may want to enclose this in an IFERROR() formula.
Alternatively, if you really want to look up by row reference, you can use =VLOOKUP(ROW()-1, ...) to look up the current row (e.g., 2707) minus 1 (2706) from the second file, and then find the value of print: =VLOOKUP(ROW()-1, SecondFile!$A1$H11, 7, FALSE). You can use this in an IF() function to look up a different column if the value is one: e.g., =IF(VLOOKUP(ROW()-1, SecondFile!$A1$H11, 7, FALSE)=1, VLOOKUP(ROW()-1, SecondFile!$A1$H11, 4, FALSE), "Value not found")