Excel return true if number is within range - excel

My problem
I have a list of values (List 1) that have the following pattern...
1234-COD-125
I have another list (List 2), which follow the pattern...
12345(1234-COD-100 - 1234-COD-150)
I need to search List 2 and return True if the value in List 1 is within range. So for example..
List 1 Result List 2
1234-COD-125 TRUE 12345(1234-COD-100 - 1234-COD-150)
1234-COD-126 TRUE 12345(4567-BAH-100 - 4567-BAH-150)
1234-COD-155 FALSE
4567-BAH-125 TRUE
4567-BAH-126 TRUE
4567-BAH-155 FALSE
Background
The first part (1234-COD) is the vendor ID and code. The last part (125) is the order ID. Different vendors can have the same order ID, so my lookup needs to account for the vendor.
What I've done so far
I have written a series of formulas which extract parts of the string. For instance, for
12345(1234-COD-100 - 1234-COD-150)
I have extracted the following in individual cells
100
150
COD
1234-COD-100
1234-COD-150
I know I can create a series to manually populate each order ID within range, then perform a lookup but I have hundreds of values in List 2 so this isn't an option.
Another option is to take the value in List 2 (12345(1234-COD-100 - 1234-COD-150) and check if every number in the range 100-150 is found in List 1.
I would like to be able to use a formula (or even VBA) to achieve this, but haven't been able to get any further. Any help would be greatly appreciated!

Parsing text is always problematic. The following will return what you want:
=SUMPRODUCT((A2>=TRIM(LEFT(MID($C$2:$C$3,FIND("(",$C$2:$C$3)+1,LEN($C$2:$C$3)),FIND(" - ",MID($C$2:$C$3,FIND("(",$C$2:$C$3)+1,LEN($C$2:$C$3)))-1)))*(A2<=SUBSTITUTE(TRIM(MID($C$2:$C$3,FIND(" - ",$C$2:$C$3)+3,LEN($C$2:$C$3))),")","")))>0
But it depends exclusively on the pattern you are showing. Specifically that the range is always in () and the two ranges are separated by -

Related

Excel: Match 2 Items, Including if Date is Between a Date Span on Multiple Worksheets

I have 2 worksheets:
Worksheet 1: Member ID, Engagement Date and other data.
Worksheet 2: Member ID, Policy Begin Date, Policy End Date and other data.
On Worksheet 1, I want to return a policy type name (from Worksheet 2), if Worksheet 1's Member ID matches Worksheet 2's Member ID AND if Worksheet 1 Engagement Date falls between Worksheet 2's Policy Begin and End Date...
The following is the formula I tried and also have attempted extensive research, to no avail:
=INDEX('Program Data'!M2:M25671,MATCH(A2:A489&F2>='Program Data'K2&F2<='Program Data'L2,'Program Data'!E2:E25671,0))
Replace your MATCH with an AGGREGATE that Calculates the SMALLest row where the Policy ID and Dates all match up.
So, we want AGGREGATE(15, 6, <SOME CODE>, 1) to get the Smallest non-error value in a list created by <SOME CODE>
The first thing that <SOME CODE> will want is the ROW we are looking at (minus one, because I see that you are skipping the header row...) which is ROW(Sheet2!$A$2:$A$25671)-1
If the Row does not match, we want to either make it massive or make it error (even better, because then it gets completely skipped). How to do this? Well, I have the POWER function for that. If you try POWER(10,999) you get a #NUM! error, because 10^999 is too large a number for Excel. If you try POWER(0,999) you get 0, because 0^anything is 0. So, we'll just add some POWER to our ROWs to make it error-out when we don't want them.
But, now we need to decide between 10 and 0. Fortunately, Logical statements can be treated as Bitwise Multiplication (True = 1 and False = 0`)
So, --(Sheet2!$A$2:$A$25671=$A2) will give us 1 when the First Columns (Member ID) match, --(Sheet2!$B$2:$B$25671<=$B2) will make sure that the Policy Start Date is before-or-on the record date, and --(Sheet2!$C$2:$C$25671>=$B2) will check the End Date. Multiply it all together, and we get 1 when the row matches, and 0 when it doesn't.
Now, if we take that away from 1, we get the opposite: 0 when we want 0, and 1 when we want 10. So multiply that by 10, and shove it in the POWER function, and add that to the ROW to get <SOME CODE>. Dump it all in the AGGREGATE from the start, and voila
=AGGREGATE(15,6,ROW(Sheet2!$A$2:$A$25671)-1+(POWER(10*(1-(Sheet2!$A$2:$A$25671=$A2)*--(Sheet2!$B$2:$B$25671<=$B2)*--(Sheet2!$C$2:$C$25671>=$B2)),999)),1)
Then, just use that in place of your MATCH (it will generate a #NUM! error when no policy is found)
=INDEX(Sheet2!M2:M25671,AGGREGATE(15,6,ROW(Sheet2!$A$2:$A$25671)-1+(POWER(10*(1-(Sheet2!$A$2:$A$25671=$A2)*--(Sheet2!$B$2:$B$25671<=$B2)*--(Sheet2!$C$2:$C$25671>=$B2)),999)),1),1)

Excel Multiple If Statements showing False

I have this IF statement:
=IF(AG3<=7,"1",IF(15<=AG3<=21,"2",IF(22<=AG3<=28,"3",IF(29<=AG3<=35,"4",IF(36<=AG3<=42,"5",IF(43<=AG3<=49,"6",IF(50<=AG3<=56,"7")))))))
but either it gives me a 1 or "FALSE"
All the values are within the ranges and should be showing various numbers
Excel does not use 50<=AG3<=56. The way Excel will read this is it will resolve AG3<=56 which will resolve to TRUE or FALSE which have the values of 1 and 0 respectively. And since 50 is greater than both those it will always return FALSE and since you did not specify a final false argument Excel returns FALSE
It needs to be AND(50<=AG3, AG3<=56)
Also "1" returns a number as text and not a true number, remove the quotes.
So:
=IF(AG3<=7,1,IF(AND(15<=AG3,AG3<=21),2,IF(AND(22<=AG3,AG3<=28),3,IF(AND(29<=AG3,AG3<=35),4,IF(AND(36<=AG3,AG3<=42),5,IF(AND(43<=AG3,AG3<=49),6,IF(AND(50<=AG3,AG3<=56),7,"Value not in specs")))))))
But based on your criteria you could use:
=IF(OR(AND(AG3>=8,AG3<=14),AG3>56),"Not to Spec",MATCH(AG3,{-1E+99,15,22,29,36,43,40}))
Don't use Nested IFs if you can avoid it. Instead, use a banded VLOOKUP: it's many times more efficient, and a heck of a lot simpler to troubleshoot. Something like the answer here:
Excel IF statement Not returning the appropriate Value
In your case, here's your lookup list:
Note that since you haven't specified what should happen between 8 and 14 or over 57 I have simply put =NA() in those bands.
And here's the result for a range of numbers:
...and here's the formula that was used in the second column of that second table (using table notation):
=VLOOKUP([#Value],Table3,2,TRUE)

Using tbl.Lookup to match just part of a column value

This question relates to the Schematiq add-in for Microsoft Excel.
Using =tbl.Lookup(table, columnsToSearch, valuesToFind, resultColumn, [defaultValue]) the values in the valuesToFind column have a consistent 3 characters to the left and then varying characters after (e.g. 908-123456 or 908-321654 - i.e. 908 is always consistent)
How can I tell the function to lookup the value based on the first 3 characters only? The expected answer should be the sum of the results of the above, i.e. 500 + 300 = 800
tbl.Lookup() works by looking for an exact match - this helps ensure it's fast but in this case it means you need an extra step to calculate a column of lookup values, something like this:
A2: =tbl.CalculateColumn(A1, "code", "x => LEFT(x, 3)", "startOfCode")
This will give you a new column that you can use for the columnsToSearch argument, however tbl.Lookup() also looks for just one match - it doesn't know how to combine values together if there is more than one matching row in the table, so I think you also need one more step to group your table by the first 3 chars of the code, like this:
A3: =tbl.Group(A2, "startOfCode", "amount")
Because tbl.Group() adds values together by default, this will give you a table with a row for each distinct value of startOfCode and the subtotal of amount for each of those values. Finally, you can do the lookup exactly as you requested, which for your input table will return 800:
A4: =tbl.Lookup(A3, "startOfCode", "908", "amount")

Using VLookUp for a partial search

I have two tables in excel.
In table 1, one column contains a list of order numbers. This is done the format of XXXX-YYYY where X is an integer and Y is a letter. For example 3485-XTIP
Table 2 also has an order number column but this time it's in the format XXXX-YYYY (ZZ) where Z is the initials of the customer who made the order. Example: 3485-XTIP (KN)
How can I use a VLookUp to search for the order number in Table 2 but only using the XXXX-YYYY part? I tried using TRUE for an approximate search but it still failed for some reason.
This is what I have
=VLOOKUP("I3",'Table2 '!A:B,2,FALSE)
I am open to any alternatives other than VLookup for this situation.
Note that there are hundreds of order numbers and entering the strings manually will take forever.
You can use * as wildcard and add it at the end of the order number so that your VLOOKUP will match any order plus any other characters that come after it:
=VLOOKUP(I3&"*", 'Table2 '!A:B, 2, 0)
* will match anything after the order number.
Note: 0 and False have the same behaviour here.

Return a row number that matches multiple criteria in vbs excel

I need to be able to search my whole table for a row that matches multiple criteria. We use a program that outputs data in the form of a .csv file. It has rows that separate sets of data, each of these headers don't have any columns that are unique in of them self but if i searched the table for multiple values i should be able to pinpoint each header row. I know i can use Application.WorksheetFunction.Match to return a row on a single criteria but i need to search on two three or four criteria.
In pseudo-code it would be something like this:
Return row number were column A = bill & column B = Woods & column C = some other data
We need to work with arrays:
There are 2 kinds of arrays:
numeric {1,0,1,1,1,0,0,1}
boolean {TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}
to convert between them we can use:
MATCH function
MATCH(1,{1,0,1,1,1,0,0,1},0) -> will result {TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}
simple multiplication
{TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE}*{TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE} -> will result {1,0,1,1,1,0,0,1}
you can can check an array in the match function, entering it like in the picture below, be warned that MATCH function WILL TREAT AN ARRAY AS AN "OR" FUNCTION (one match will result in true
ie:
MATCH(1,{1,0,1,1,1,0,0,1},0)=TRUE
, YOU MUST CTR+SHIFT+ENTER !!! FOR IT TO GIVE AN ARRAY BACK!!!
in the example below i show that i want to sum the hours of all the employees except the admin per case
we have 2 options, the long simple way, the complicated fast way:
long simple way
D2=SUMPRODUCT(C2:C9,(A2=A2:A9)*("admin"<>B2:B9)) <<- SUMPRODUCT makes a multiplication
basically A1={2,3,11,3,2,4,5,6}*{0,1,1,0,0,0,0,0} (IT MUST BE A NUMERIC ARRAY TO THE RIGHT IN SUMPRODUCT!!!)
ie: A1=2*0+3*1+11*1+3*0+2*0+4*0+5*0+6*0
this causes a problem because if you drag the cell to autocomplete the rest of the cells, it will edit the lower and higher values of
ie: D9=SUMPRODUCT(C9:C16,(A9=A9:A16)*("admin"<>B9:B16)), which is out of bounds
same as the above if you have a table and want to view the results in a diferent order
the fast complicated way
D3=SUMPRODUCT(INDIRECT("c2:c9"),(A3=INDIRECT("a2:a9"))*("admin"<>INDIRECT("b2:b9")))
it's the same, except that INDIRECT was used on the cells that we want not be modified when autocompleting or table reorderings
be warned that INDIRECT sometimes give VOLATILE ERROR,i recommend not using it on a single cell or using it only once in an array
f* c* i cant post pictures :(
table is:
case emplyee hours totalHoursPerCaseWithoutAdmin
1 admin 2 14
1 him 3 14
1 her 11 14
2 him 3 5
2 her 2 5
3 you 4 10
3 admin 5 10
3 her 6 10
and for the functions to check the arrays, open the insert function button (it looks like and fx) then doubleclick MATCH and then if you enter inside the Lookup_array a value like
A2=A2:A9 for our example it will give {TRUE,TRUE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE} that is because only the first 3 lines are from case=1
Something like this?
Assuming that you data in in A1:C20
I am looking for "Bill" in A, "Woods" in B and "some other data" in C
Change as applicable
=IF(INDEX(A1:A20,MATCH("Bill",A1:A20,0),1)="Bill",IF(INDEX(B1:B20,MATCH("Woods",B1:B20,0),1)="Woods",IF(INDEX(C1:C20,MATCH("some other data",C1:C20,0),1)="some other data",MATCH("Bill",A1:A20,0),"Not Found")))
SNAPSHOT
I would use this array* formula (for three criteria):
=MATCH(1,((Range1=Criterion1)*(Range2=Criterion2)*(Range3=Criterion3)),0)
*commit with Ctrl+Shift+Enter

Resources