While a number of other posts address similar issues, I was unable to find one that met my specific needs, using multiple sheets, etc.
What I need is the ability to select a value from a validation list in one column, and then have a second validation list be narrowed to just the values that can be selected based on the first validation list, and then a third that follows the same logic, etc.
So for example, I have 5 sheets:
Log - This sheet is used for input and will contain the columns that
have the dropdown validation lists.
Clients - This sheet is a two column list of clients. Column A has
the Client ID, column B has the Client Name.
Matters - This sheet is a three column list of Matters. Column A has
a Client ID, Column B has the Matter ID, column C has the Matter
Name.
Timekeepers - This sheet is a two column list of Timekeepers. Column
A has the Timekeeper ID, Column B has the Timekeeper Name.
Rates - This sheet is a three column list of Rates. Column A has a
Matter ID, Column B has a Timekeeper ID, Column C has a Numeric
Rate.
The log sheet:
Column A (Timekeeper) will be a simple validation list dropdown from which I will select a timekeeper (by name). This validation list is populated by the list on the Timekeeper sheet.
Column B (Client) will be another simple validation list dropdown from which I will select (by name) a client. This validation list is populated by the list on the Clients Sheet.
Column C (Matter) will have a validation list of Matters. This is the first dynamic validation list, as the list should only show the matters that belong the to client that was selected in Column B. We know which matters belong to a client by the Column A (Client ID) in the Matters sheet.
Column D (Rate) will simply display the rate for a given timekeeper/matter combination. We would now have the matter id and client id from the input into columns A and C, so we just need to locate the row in the Rates sheet that has that matter id and timekeeper id.
The solution can use VBScript or not, whatever you prefer. I'm a software developer, so I'm comfortable with VBScript, and I'm relatively familiar with Excel, so nested built in functions would be fine too.
Thanks in advance!
EDIT:
This workbook is going to be dynamically generated from a database, so I need to utilize an approach that can be generated programmatically.
The "Log" sheet will contain many rows where the user will select a Timekeeper from a dropdown, then select the Client from a dropdown (which will limit the Matter dropdown list) then select a matter from the Matter dropdown (which, combined with the selection in the timekeeper field will determine the "Rate").
The dropdowns will show the "name" values (i.e. timekeeper name, client name, matter name) but the limitations to subsequent lists based on these selections has to be based on the "ID" value for the selected "Name".
An example showing how to use subsequent list limitations would be most helpful. All of the examples I have seen show how to select one value and limit a second list, but I need to be able to have the selection from the second list limit a third list, the third list limit a fourth list, and finally, the "rate" is determined by what is selected in two of the lists.
The gist of dynamic validations is using =INDIRECT(SomeNamedRange) as the Source data in the List type of Data Validation.
Now, the hardest part is to dynamically generate this list of partners. For the sake of this example, I'll assume you have three sheets: Sheet1, Config, and Validation. I'm also assuming you are selecting a Partner based on a Region, as that is a simpler example.
Let's start with Validation.
Here's an example of my data:
Notice how I've sorted the data based on the most general criteria (Region, in this case). This will be important later on. Also notice that I've named A1:A26 as Validation.Region. I've also named B1:B26 as Validation.Partner.
Config is where your magic happens.
Moving over to the Config, we're going to need to add a list of unique regions, and an address describing where they're located. We'll name this address Region.Choices.
For this example, I used the COUNTIF function to find the last partner in the list. The exact formula was ="Config!$B$2:"&CELL("address";OFFSET(B$2;COUNTIF(B$2:B$230;"?*")-1;0)). Unfortunately, Excel doesn't have a built-in function for the sheet's name, so I had to hardcode that. I went ahead and hardcoded $B$2 to improve performance (maybe?), but you could do that dynamically too.
Sheet1 is where you'll be making your dynamic selection.
In this sheet, we have the following structure.
Take B4, name it "Region.Selected", and add Data Validation as a List of Source =INDIRECT(Region.Choices).
Creating the logic behind the dynamic drill down
Now go to Config, and replicate the contents of B1 on C1, making sure to alter the hardcoded $B$2). Finally, name Partner.Choices, and type in the following Array Formula in C2:C100:
=IF(Region.Selected="";OFFSET(Validation.Partner;1;0;COUNTA(Validation.Partner);1);OFFSET(Validation.Region;MATCH(Region.Selected;Validation.Region;0)-1;1;COUNTIF(Validation.Region;Region.Selected)))
Note: to add an Array Formula, select C2:C100 before typing the formula, and once you're done typing, hit Ctrl+Shift+Enter instead of Enter.
While it may seem convoluted at first, this is basically returning every Partner if no Region is selected, or returning the partners from a selected Region by calculating where it ends and starts and shifting one column to the right with OFFSET.
Wrapping up the dynamic drill down
Now go back to Sheet1, take C4, name it "Partner.Selected" (for consistency), and add Data Validation as a List of Source =INDIRECT(Partner.Choices), as displayed below:
For this example, I used the COUNTIF function to find the last partner in the list. The exact formula was ="Config!$C$2:"&CELL("address";OFFSET(C$2;COUNTIF(C$2:C$230;"?*")-1;0)). Unfortunately, Excel doesn't have a built-in function for the sheet's name, so I had to hardcode that. I went ahead and hardcoded $C$2 to improve performance, but you could do that dynamically too.
Now go ahead and test your dynamic validation! It should look like this:
Related
What I would like to achieve is that sellers can choose the STORE in the blue cell (either with a drop down list or by hard-typing the STORE name) and, based on the selection on the blue cell, the available POSITIONS for that particular PRODUCT and that particular STORE are show in the green cell as a drop down list.
Let's say I have an Excel workbook, which contains a worksheet with this table with products data, which is automatically imported daily from our Nav server with this layout. It has 4 columns including PRODUCT CODE, DESCRIPTION, STORE IN WHICH IT CAN BE LOCATED and POSITION INSIDE DE STORE (please, check screenshot). It contains 1.5k rows and it changes dynamically, for example, new items are added or positions are exchanged.
As you can see, the same product (PRODUCT 2) can be located in several stores (STORES 1, 2 and 3), and it can be in several locations on each store (POSITIONS 2, 3, 1 and 4).
Now I need sellers to report which of these items they pick and from where, not only the STORE but its POSITION inside the store too. They do it with another worksheet inside the same Excel workbook. It looks more or less like this (please, check screenshot).
I know the drop down list is achieved via Data Validation but I can't figure out the formula for this. I have tried several approaches like:
Array formula to return all POSITIONS in the same ROW, following this (Formula 2.): https://www.ablebits.com/office-addins-blog/2017/02/22/vlookup-multiple-values-excel/. It is quite slow to calculate on the 1.5k items and, once done, I can't figure out how to make Data Validation to look for the 4 or 5 or 10 POSITIONS returned by the array formula, which also need to be filtered by STORE (please, check screenshot for the closest that I have been, array formula returning POSITIONS from column E).
Same formula as above directly on the Data Validation list box, which returns only the first POSITION found.
VBA custom fucntions which are not allowed in the Data Validation box.
I feel comfortable with both Power Query and VBA, and forumla as well, and can adapt most of the code I see but I don't know why I just can't figure out how to achieve this, maybe it is only I am blocked or something but every path I start to follow ends up in a dead end.
Does anyone have an idea on how to approach this? It doesn't really seem that complicated but it is becoming impossible for me.
Thank you very much for your time!!
This is what I have finally done, just in case someone else is facing this situation.
Instead of a plain-text table for the POSITIONS, I created a PowerQuery importing that CSV. Named that worksheet _LOCATIONS.
Added a custom column (Column E) combining the PRODUCT and the STORE so I had something like a Unique Identificator, resulting something like this but in PowerQuery.
Combined column:
Sorted column E and sub-sorted column D, so I make sure the list will always be ordered as I need, and saved the query.
Then, in worksheet REPORT, I entered this formula to create the drop down list in Data Validation in cell D2:
OFFSET(_LOCATIONS!$D$1,MATCH($A2&"-"&$C2,_LOCATIONS!$E:$E,0)-1,0,COUNTIF(_LOCATIONS!$E:$E,$A2&"-"&$C2))
And I am able to choose from the available POSITIONS for the selected PRODUCT in the selected STORE.
Brief explanation:
I set the reference for the OFFSET function in the very first POSITION (D1), and then I move it the amount of rows detected by the MATCH function (which searches for the "PRODUCT 2-STORE 2" string in the newly created combined column) minus 1 (PoweryQuery table has headers) and 0 columns. This leaves me on the first occurrence of my string (but on the POSITIONS column). Then I make the offset as high as the amount of rows detected by the COUNTIF function (which counts all occurrences of my PRODUCT-STORE pair), returning an array of all the positions (column D) matching the PRODUCT-STORE pair.
Ask for formula in Spanish if you need it.
I got a problem with some popular Excel question, dynamic ranges and data validation drop-downs and auto-populate. Lets say I got 2 sheets, and on one sheet I got drop-downs to choose from another sheet, and that is not a problem when I define cells and range using:
=OFFSET($A$19;;;COUNTA('0528 - info'!$E$2))
..but what about when I wanna add some new cells in between,so that they can be automatically recognized in which group they belong:
As you see for instance Column B has some "groups" where you can find more different "values" like in Column C, like Power Supply has MV1 and MV2... and so on. My drop-downs on the sheet 1 are called exactly like this "groups" and I did reference them manually using given function. But is it possible to populate my drop-downs automatically when I add for instance MV3 beneath MV2 in this table? Or RN7 on 14th row? Everytime I add new values I have to extend my dropdowns (what is fine..), but problem will be when I share this table to others, they gonna forget it 90%.
I hope you get my point, any suggest will be fine!
p.s. Indirect doesnt work in a way it should - It gives me all instances from the Column but not specific ones that I need.
=INDIRECT("Table4[VarEDS]")
Well this option gave me again what I already had before - all "matches" from the Column and still not ONLY matches that are for certain group. ...
If your Data Validation source is a "Table" as shown in your image then you can take advantage of "Table Column" Range which is dynamic. That means whenever you refer that column as NAMED range and if make changes to the column (Edit, Add, Delete) it will reflect in the referred cell.
You can use this technique even for ranges not in table. You need to NAME them with offset formula and make dynamic.
You can find dynamic address of your column as shown in the image below. Select entire column WITHOUT Header
Name your column data range with appropriate name as shown in image below
Then in Data Validation Window refer this name using F3 as shown in image below.
Then you can see... Even if you edit, add or delete any row in the column the data validation will change
Editing based on your comment below: If you want text from column B and Column C appear together in the validation dropdown list. Insert column in the table and join text from column B and C and then make data validation based on that column as shown in Colum D in image below
Finally I think I understood your question.
Watch this video
Excel: Find Multiple Matches & Dependent Drop Down List
After some days of searching and trying I got what I wanted - wasnt wasy job at all. Needed to combine more functions with the help of couple of videos from Leyla (Xelplus):
https://www.youtube.com/watch?v=gu4xJWAIal8
https://www.youtube.com/watch?v=7fYlWeMQ6L8&t=5s
First step was to make unique list of my values (text in my case) on separate sheet:
=IFERROR(INDEX(t_VarGroup[Vargrouptext];MATCH(0;INDEX(COUNTIF($J$2:J2;t_VarGroup[Vargrouptext]););0));"")
Then I needed to "extract" all the values that are belonging to the certain unique values:
=#IF($I3<COLUMNS($K$2:K$2);"";INDEX(t_EDS[[VarEDS]:[VarEDS]];AGGREGATE(15;3;(t_VarGroup[[Vargrouptext]:[Vargrouptext]]=$J3)/(t_VarGroup[[Vargrouptext]:[Vargrouptext]]=$J3)*(ROW(t_VarGroup[Vargrouptext])-ROW(t_VarGroup[[#Headers];[Vargrouptext]]));COLUMNS($K$2:K$2))))
FUrthermore, I created Unique drop down list:
=OFFSET($J$3;;;COUNTIF($J$3:$J$14;"?*"))
And then dependent drop down list nearby using:
=OFFSET($K$2;MATCH($H$2;$J$3:$J$17;0);;1;COUNTIF(OFFSET($K$2;MATCH($H$2;$J$3:$J$17;0);;1;20);"?*"))
And because I made it on other sheet, I had to reference them to an appropriate sheet name where my main sheet is - with drop downs, it is actually very useful for my future work and for everyone else who has struggling with drop downs but on a bit specific way =))
credits to: #Naresh Bhople for suggestion about Youtube videos.
I have one sheet containing the table name customer_id and Project_id.For each customer id various projects are displayed.when i try to create data validation by selecting all those it is not coming.for ex.
Customer_id Project_id
1 1.1
1 1.2
2 2.2
2 2.3
and like that.please tell me some solution.
This really depends on what you want exactly, but since your question is not that elaborate, I guess you mean this?
You can create a data validator from data in your worksheet in the following way:
Select the sheet you want the validator to be on
In the ribbon, click the data tab, and then Data validation
Select 'Allow List'
in the Source bar, select the cells with the allowed values
Another way, is to create a data validator using a vba or vb.net macro. In your macro say:
Dim range as Excel.Range = listSheet.Range("A1")
range.Validation.Add(Excel.xlDVType.xlValidateList, Excel.xlDVAlertStyle.xlValidAlertInformation, Excel.xlFormatConditionOperator.xlEqual, "Option1; Option2")
I guess what you want are two dropdown lists, the second depending on the value selected in the first one? (please elaborate your questions some more). To do that, I suppose there are other ways but this is what I usually do:
Take into account that I always use names to refer to ranges instead of references, to improve readness. If you have doubts to do it, read Use names in Excel formuas
Create a table or range somewhere in your book with one column with the master values.
I have named the range with the values master_list
Create a table or range somewhere in your book with two columns. The first column contains the master/look-up value and the second the dependent values.
I have named the list of look-up values (this is, the values in the first column) as dependent_list
I have named heading to the cell above the dependent_list (for example, if the dependency table starts in A2, the heading is A1
Order the lists
The master_list is ordered as you wish values appear in the dropdown list.
The dependent_list must be ordered by the values in the first column (master values). It doesn't matter if the order is the same in the master_list and the dependent_list, but identical values in the master column of the dependent_list must be together.
The order in the second column of the dependent_list will determine the order in the dependent dropdown list.
Optionally you can define a message to display in the dependent_list when there is no master value selected. I have named it msg_error.
Click on the cell where you want the master dropdown, ant go to the Data Validation menu, where you select:
Allow: List
Source: Add the formula =INDIRECT("master_list")
I have named the cell where the master dropdown list as key_value
Click on the cell where you want the dependent dropdown, and then go to the Data Validation menu, where you select:
Allow: List
Source: Add the formula =IF(key_value="";msg_error;OFFSET(heading;MATCH(key_value;dependent_list;0);1;COUNTIF(dependent_list;key_value);1))
Note that Excel functions are language dependent of the language and I have translated them to English, so maybe there are mistakes.
I have two tables that get dynamically created from a database query; the first table is the source of the drop-down list, and the second is the table that I will apply the drop-down list via data validation. First table:
and the second table:
What I need, ideally through just Excel formulas, is an intelligently designed drop-down that shows only the dimension values associated to the dimension in question.
So in cells B3:B10, the drop-downs would show a,b,c. In cells C3:C10, the drop-downs would show 1,2,3. In cells D3:D10, the drop-downs would show x,y,z. Etc, etc.
I need this to be dynamic in the sense that a week from now my DB query may return a fourth dimension that would need to follow the same approach.
Not sure if this is even possible without writing some VBA, but I figure I'd see if anybody has any creative ideas. Cheers!
You have to use Name Manager and =INDIRECT() formula to achieve that.
First download the sample file.
Sample File
See this tip (By me). It will help you to see screenshots step by step. Link is here
Now in-case of your data you have to use some formula to filter data automatically when new data come. So that new data can organize for dynamic combo boxes. I can also do that for you if you are not able to do that. Then share your sample workbook with me.
It is very possible, but not simple. There are a several ways to implement this, depending on your requirements, how dynamic it needs to be, and the expected structure of the data (as I mentioned in a comment).
I will give one possible solution, that is mostly dynamic, and is the simplest to explain. You can use a similar logic to make it all dynamic.
This solution will retrieve the data from table #1 according to the dimension name, assuming it is not sorted, and return the values in the order they are given in the table.
For some of the ranges I create names for simplicity, and some are mandatory. In order to follow the formulas logic you need the named ranges I use.
Create named ranges for table #1: (Either by using the Name Box or using the Name Manager Ctrl+F3):
For the data in the column Dimension: DimName =B3:B11
For the column Dimenstion Value: DimValue =C3:C11
Create dimension values lists in a new sheet:
Put the dimension name in B2 ="Customer". (The available dimension names can be created dynamically as well, but I'm skipping this part for simplisity).
B3 (array formula - Ctrl+Shift+Enter) =IFERROR(INDEX(DimVal,SMALL(IF(DimName=B$2,ROW(DimName)-ROW(INDEX(DimName,1))+1),ROWS(B$3:B3)),1),""). This formula returns the k-th value for the "Customer" dimension.
Copy B3 down to as many rows you think you'll need. Let's say B4:B10, so B3:B10 will have the array formula. The first cells will have the available values and the remaining cells will be empty because of the IFERROR function.
In B1 we will count the available values using the formula =SUMPRODUCT(--(B3:B10<>"").
Do the same for "Product" and "Geography" in columns C and D.
Create dynamic named ranges for the lists: (using the Name Manager Ctrl+F3)
For the lists' data DimLists =B3:D10.
For the lists' headers DimListHeaders =B2:D2.
For the lists' counts DimListCounts =B1:D1.
*These names are mandatory for the data validation to work in another sheet.
Set table #2 data validation list sources:
Select B3:B10 in table #2.
Go to Data > Data Validation, and select Allow: List.
Put the following formula in the source: =OFFSET(INDEX(DimLists,,MATCH(B$2,DimListHeaders,0)),,,INDEX(DimListCount,,MATCH(B$2,DimListHeaders,0))). This formula finds the correct list in DimLists according to the column header in table #2, and also sets the returned range height according to the list count.
Hope this helps.
I'm trying to write a macro that i can run which will allow me to simply sort a range of orders into what i like to call categories.
The basic idea is that we get orders through, and we generally have to print a different type of shipping label for the different items, based on weight, size and value. Unfortunately, there is no easy way of doing this other than going through all orders (sometimes thousands) and copying them into different worksheets to group them into the type of shipping method we need to use.
What i'd like to do (i already have a couple of macros already) - is to look in another sheet whereby we store the item titles, and have a second column within that sheet with a number (1, 2 or 3). For each item, based on it's weight, size or value, which we have already specified - they would be assigned a number. The Macro will look at the item name, if the sales sheet finds a match from column A in the item's sheet, it will then add the correct number specified in the item's sheet to the cell next to the item title in the sales sheet.
Column A-G has all customer details, Column H has the item title. The number i'm wanting to add to the row will be inserted into Column I.
The item's sheet has Column A which is the item title, and Column B is the number assigned to this item.
I have tried to muster a macro up myself, however it's confusing me no end.
This is exactly what vlookup is used for
=VLOOKUP(H1, items!A:B,2,FALSE)
Put this formula into I1 on the sales sheet and drag it down, if the items sheet is not in the same workbook , you will need to modify the reference to point to it,
you could obviously write a macro that will insert this formula and drop it down, but it will still be using vlookup or application.vlookup to get the result
Wildcard searches at the front would be
=VLOOKUP("*"&H1, items!A:B,2,FALSE)
or both ends would be
=VLOOKUP("*"&H1&"*", items!A:B,2,FALSE)
NB* BE CAREFUL WITH THIS AS YOU MAY HAVE ITEMS WITH SIMILAR DESCRIPTIONS
like "apple" and "red apple"
you should always use a product code to do lookups when available