Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excel: How to create dynamic data validation list based on data table

Imagine I'm writing a menu-planner in Excel for my kids (easier to describe than my actual problem) ...

I have a list of available foods: apples, bananas, carrots, dates, eggs, fish, etc.

I have a list of kids: John, Karen, Lional, Mike, etc.

Then, I have a simple table that lists the food each kid likes: Under John's column there will be an 'x' against apples, bananas and fish, but blanks against the others.

     J  K  L  M
---------------
a    x  x  x
b    x     x
c       x  x  x
d       x
e          x  x
f    x

Now, in the main part of my menu-planner, I want to have some cells with data validation that allow me to select food for each kid, using the above 'likes' table:

Name  Food
A2    B2

Cell A2 will contain data validation that gives an in-cell drop-down with all kids names (J, K, L, M) (that's easy - I can do that bit!)

Cell B2 needs to contain a dynamically generated list of foods that are liked by the selected kid. So, if I select John in A2, then B2 list would be {a, b, f}. If I select Lionel, B2 list would be {a, b, c, e}. Clearly, as my kid's tastes change, I can just update my 'likes' table by adding/removing 'x', and the drop-downs in B2 will auto-update.

How do I create the drop-down validation list for cell B2? (I'd prefer to do this without resorting to VBA please)

like image 739
Jim White Avatar asked Oct 20 '22 21:10

Jim White


1 Answers

I assumed that your data table is in range A1:E7.

Step 1. Create a list of choices for each kid

For each kid create a list with all their preferences listed (at the end of the list I added "-" as placeholders). Enter this formula in G2 and drag to range G2:J7:

=IF(G1="-";"-";IF(ISNA(OFFSET($A$1;IFERROR(MATCH(G1;$A$2:$A$7;0);0)+
MATCH("x";OFFSET(B$2;IFERROR(MATCH(G1;$A$2:$A$7;0);0);0;7;1);0);0;1;1));
"-";OFFSET($A$1;IFERROR(MATCH(G1;$A$2:$A$7;0);0)+MATCH("x";OFFSET(B$2;
IFERROR(MATCH(G1;$A$2:$A$7;0);0);0;7;1);0);0;1;1)))

Also put kids names above data columns (G1:J1).

Step 2. Create conditional data validation

Given that your first data validation list (name) is in cell L2 and you've followed step 1, use this formula for data validation for food:

=OFFSET(F$2;0;MATCH(L2;$G$1:$J$1;0);6-COUNTIF(OFFSET(F$2:F$7;0;
MATCH(L2;$G$1:$J$1;0));"-"))

This formula both excludes all empty choices ("-") in the list and gives the right list based on kid's name.


UPDATE. Alternative solution with INDEX/MATCH

OFFSET is a volatile formula (i.e. Excel recalculates it whenever there is any change in your workbook) so you might want to do this with INDEX instead. Here is the formula for my step 1 above:

=IF(G1="-";"-";IFERROR(INDEX($A$2:$A$7;IFERROR(MATCH(G1;$A$2:$A$7;0);0)+
MATCH("x";INDEX(B$2:B$7;IFERROR(MATCH(G1;$A$2:$A$7;0)+1;1);1):B$7;0);1);"-"))

As for the step two, it seems that formula for data validation gets recalculated only when you select the cell so OFFSET doesn't have volatility in data validation lists. As INDEX cannot return a range and Excel doesn't allow INDEX(..):INDEX(..) ranges for data validation, OFFSET is better for data validation lists.

like image 190
lina curious Avatar answered Oct 24 '22 00:10

lina curious