I am trying to find another solution to below Excel formula that was already provided here:
How do I create groups based on the sum of values?
It is the same requirement, but the grouping criteria needs to be an exact value.
Here's the sample data:
Column A | Column B
Item A | 1
Item B | 2
Item C | 3
Item D | 4
Item E | 5
Item F | 1
Item G | 2
Item H | 3
Item I | 4
Item J | 5
I need to group the rows if their Column B sum = 5.
Expected result:
Group 1 = Item A, Item D (1 + 4) = 5
Group 2 = Item B, Item C (2 + 3) = 5
Group 3 = Item E = 5
Group 4 = Item F, Item I (1 + 4) = 5
Group 5 = Item G, Item H (2 + 3) = 5
Group 6 = Item J = 5
If a row's Column B exceeds 5 or does not have another matching row to equal 5 when added then it will have no Group value.
Groupings can be interchangeable, ie. Group 1 = Item A, Item I can be made since 1 + 4 = 5.
I assume this can be achieved using Excel formulas but I am struggling to find which formula(s) can be used. Any help is appreciated!
I believe I was able to understand your question after some comments exchanged. Anyway I would recommend to update your question, it is an interesting problem, but the question was difficult to follow.
Before looking for an Excel solution, I took the approach of understanding the problem as a state machine with the transition from one state to another. I considered the following states that represent the position the item in the group. A group is defined as consecutive items that the sum of all items is equal to 5.
EMPTY: Just the initial situation
START: Start of the group
MIDDLE: A middle element of the group
END: The end of the group
START-END: A group with a single element
NA: Not applicable group
I follow the same idea of: How do I create groups based on the sum of values?, but slightly different helper columns:
Total (Column D), but for this case it is used the following formula: IF(SUM(C3,D2)>5,C3,SUM(C3,D2))
Status or item position within Group (Column G). Here is where it is calculated the corresponding status for each element
Checks for Valid Groups (Column H): Evaluates if a group is valid. When there is no match to 5, the group is not valid. It is indicated at the row that represents the beginning of the group (START or START-END states). If TRUE it means a valid group, if FALSE it is not a valid group, and NA for an NA value from Status column. If empty represents any element of the group that is not the first one.
Group # (Column I): To identify the group the row (Item) belongs to. Notice that we start counting the group from 1 and I also consider the case a group can not be formed (NA).
Here is a screenshot with the solution and the formula on G3:
=LET(total, D3, prevS, G2, QTY, C3,
IF(C3="", "",
IF(OR(AND(total=5, QTY<5, prevS="START"), AND(total=5, prevS="MIDDLE")), "END",
IF(OR(AND(total>5, total=QTY, OR(prevS="START", prevS="MIDDLE")),AND(total>5, OR(prevS="", prevS="END", prevS="NA", prevS="START-END"))), "NA",
IF(OR(AND(total<5, total=QTY, OR(prevS="START", prevS="MIDDLE")),AND(total<5, OR(prevS="", prevS="END", prevS="NA", prevS="START-END"))), "START",
IF(AND(total<5, OR(prevS="START", prevS="MIDDLE")), "MIDDLE",
IF(OR(AND(total=5, total= QTY, OR(prevS="START", prevS="MIDDLE")),AND(total=5, OR(prevS="", prevS="END", prevS="NA", prevS="START-END"))), "START-END", "UNDEFINED")
)
)
)
)
)
)
Notes::
LET Excel function is used to have something more readable
The IF blocks should to be ordered from the most specific case of total and QTY values to the most generic ones. For the case with same total condition, make sure the second condition for prevS are not repeated.
Added as a last resort UNDEFINED case, to check if any transition was not covered, if that is the case it has to be reviewed, so far in the sample data all cases are covered
Column K-Q is just for documenting purpose to identify all possible transitions. Column K-M provides all possible transitions organized them by previous status. The columns O-Q represent all possible transitions ordered by current status, so it is easier to formulate each portion of the IF blocks.
Maybe the formula can be simplified, compared to the solution provided by the similar question is more complex, but this question has more specific conditions. Some transitions maybe not relevant for the final result, but it is preferred to consider all positions in the group to make sure all transitions are covered.
The following state machine diagram shows all possible transitions:
Notes:
As you can see the solution also considers when a group cannot be created or non valid groups (NA values). The solution considers that Item column has only positive values, it is not stated in the question any restriction, but looking at the example they are all positives. To consider zero values, this solution needs to be adjusted.
Checks for Valid Groups column is calculated as follow:
= IF(G3="", "",
IF(G3="START-END", TRUE,
IF(G3="NA", "NA",
IF(G3="START",
LET(endRow, IFNA(MATCH("START", LEFT(G4:$G$1000,5),0), MATCH("", LEFT(G4:$G$1000,5),0))+ ROW()-1,
value, VLOOKUP("END", G4:INDIRECT( "G" & endRow),1,0),
IF(ISNA(value), FALSE, TRUE)
), ""
)
)
)
)
It identifies the start and end of the group, and then finds any NA values, if there are, then it is not a valid group. If the end of the candidate group is not found (the first MATCH returns N/A), then is searches until a blank row
Group # column is calculated has follow:
=IF(C3="","", LET(value, MAX($I$2:I2), IF(G3="NA", "NA",
IF(H3=TRUE, value + 1, IF(H3=FALSE, "NA",
IF(I2="NA", "NA", value))))))
This way only valid transaction are considered, i.e. the following status transitions starting from START but not ending in END : START->NA, START->MIDDLE[one or more]...->NA and NA are not considered valid groups (NA).
I added more examples from the original sample file provided, more can be added to further test all possible scenarios, but I guess you get the idea about this approach. As you sated "I assume this can be achieved using Excel formulas" yes it is possible, but I would say for more complex conditions I would suggest to implement a state machine algorithm in VBA. Even it is possible to do it with Excel functions, you have to deal with several nested IF blocks and helper columns, something that can be achieved with a simple for-loop in VBA.
Here is a link to online Excel file I used.
I have data from over 100 countries in a table. Now I want to categorize those countries in 3 cathegories. (0,1,2). So I have a list 1 and 2. All other countries should receive the country code "0". If I use now the function "if" to check if the first country is in list 1 (return 1) or else return 0. I receive 10 times a 0(for each country), because there are 10 countries in list 1. But of course I just need to receive the one single country code that belongs to it. (If it matches only one country in the list 1 => TRUE)
Do I need an other function, or what do I need to change?
Thanks in advance.
if" to check if the first country is in list ..
you can use =IF(COUNTIF(urData,urData)>0,1,0)
is this what u r looking for ?
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 -
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)
In Table 1:
I have Product Segments 1-6 for Companies
1-8. Each have different products that they list, not necessarily in the same order.
1-8. Each have different products that they list, not necessarily in the same order.
In Table 2:
I would like to return a "True" or "False" if the company lists Product Segments A-F as one of their products. For example, in Table 2 for Product Segment A, company 1 would return "True" and company 4 would return "False"
I feel like an =MATCH(J$2,INDEX($B$3:$G$10,MATCH($I3,$A$3:$A$10,0)),0) function is exactly what I'm looking for, but unfortunately I cannot return an array with excel's INDEX function.
Any suggestions would be highly appreciated.
Please refer to the image below:
http://i.stack.imgur.com/491Wk.jpg
I would use SUMPRODUCT:
=SUMPRODUCT(($A$3:$A$10=$I3)*($B$3:$G$10=J$2))>0