Dynamic (Cascading) Dropdowns that reset on change

Share

Facebook
Twitter
LinkedIn

Dynamic dropdowns are a handy way to get your users to make choices based on what they’ve previously chosen, while steering them away from making invalid choices. Today we’re going to look at one that easily handles multiple levels, and we’ll take a look at what could go wrong. Let’s see one in action, shall we?

Right, what’s on the (dropdown) menu?
Chandoo_CascadingDropdowns_NoChoices

Fruit, anyone?
Chandoo_CascadingDropdowns_First Choice

*BING!*
Chandoo_CascadingDropdowns_Not Done
Cool…check it out…as you can see from the above, the user gets prompted with “Choose…” whenever a subsequent choice must be made.

 

Ok, what kind of fruit should I have? Hmmm, let me see….eeny, meeny, miny, STRAWBERRIES!!!MO!
Chandoo_CascadingDropdowns_Strawberries

*BING!*
Chandoo_CascadingDropdowns_Still not finished

 

Ok, so what delights does Sub Category 2 have in store for me?
Chandoo_CascadingDropdowns_Earliglow

Earliglow? Never heard of it. Sounds delicious…I’ll have those, please.

*BING!*
Chandoo_CascadingDropdowns_Done

There, all done. Pretty nifty ehusers only get to see valid choices depending on what they chose last. So users simply can’t screw up!  Or can they?

[Evil user, determined to prove me wrong]: Wait a minute…I just remembered that mother expects me to eat my vegetables first, before I move on to dessert. So I better change that initial selection:

Chandoo_CascadingDropdowns_Change Initial Selection

*BING!*
Chandoo_CascadingDropdowns_Embarrassing
What the…Strawberries are vegetables???

Damn…changing upstream dropdowns later on means those downstream choices can be flat out wrong! So how can we make this bulletproof?

Macros to the rescue

Yep, we’ll use some code to clear out any ‘downstream’ choices if anything ‘upstream’ changes. Let’s go back to that original strawberry fest:
Chandoo_CascadingDropdowns_Done

Now watch what happens when our user subsequently decides they better vege out first:

*BING!*
Chandoo_CascadingDropdowns_Downstream Reset

Ahh…look at that: the code realized that all those downstream choices are no longer valid. So it deleted them, and prompted the user to choose again. There. Now that IS bulletproof.

So let’s see…hmmm…for an appetizer, I’ll have baby carrots:
Chandoo_CascadingDropdowns_Baby Carrots

 

And I already decided on Strawberries for pudding…
Chandoo_CascadingDropdowns_Pudding

 

But what about my main course. Ah, yes, of course…
Chandoo_CascadingDropdowns_Human

MEAT! Yummy. BURP!

What’s the recipe?

My approach draws on Roger Govier’s excellent sample file on the Contextures website. Be sure to check out that link to see Roger’s in-depth discussion of the formula magic behind this puppy…It’s genius.

In my Dynamic-Dependent-dropdowns-20140214, you’ll see that all the different categories used by the dropdowns are hosted in an Excel Table, that has the initial categories down the left hand side, and subsequent categories across the top:
Chandoo_CascadingDropdowns_val list

So how do these categories get used by the data validation dropdowns? Roger’s approach uses two dynamic named ranges to feed the data validation lists, one called MainList and one called SubList:
Chandoo_CascadingDropdowns_Name Manager

Here’s the MainList formula:
=INDEX(Table1[[Choose…]],1):INDEX(Table1[[Choose…]],COUNTA(Table1[[Choose…]]))

…and here’s the SubList formula:
=IF(OR(Sheet1!B8="Choose…",Sheet1!B8=""),"",INDEX(Table1,1,MATCH(Sheet1!B8,Table1[#Headers],0)):INDEX(
Table1,COUNTA(INDEX(Table1,,MATCH(Sheet1!B8,Table1[#Headers],0))),MATCH(Sheet1!B8,Table1[#Headers],0)))

The SubList formula has a relative reference in it: whatever cell you use it in, it retrieves the value of the cell to the immediate left, and then it scans the column headers of our validations table (Table1) looking for the heading that matches that value. Once it’s found it, it simply uses the items listed underneath that heading.

Because this formula is relative, before you enter it into the Name Manager, you will need to first select cell C8, because the above relative formula refers to B8 – the cell to the left. (Note that it doesn’t matter what is in C8 or where your actual dropdown are…rather it’s just that the above formula happens to refer to B8, and because we want our formula to always reference the cell on the immediate left, then we’ve got to select the cell to the immediate right before we enter this relative formula into the Name Manager.

Also note that my version of Roger’s approach uses Excel Tables and the associated Structured References that Table functionality allows. My table is called Table1. Your validation lists MUST be held within an Excel Table (which requires Excel 2007 or greater) and you MUST change the Table1 references in the above formula to match the name of your table.

Excel Tables – known as ListObjects to VBA developers – were introduced in Excel 2007, and are a very powerful and simple way to store things like lists, chart data, and PivotTable data…especially if you might need to add more data to your spreadsheet at a later date, and want to avoid having to repoint all your formulas to include the additional data. If you’re not familiar with Excel Tables – or you don’t know what that Table1[#Headers] guff above means – then I strongly suggest you check out Chandoo’s Introduction to Structural References and this great video he did with MrExcel.

The way these two formulas work is very clever. That MainList named range only gets used by dropdowns in that very first ‘Main Category’ column:
Chandoo_CascadingDropdowns_MainList2

…and all other ‘downstream’ dropdowns – no matter what level they are – are fed by the SubList named range:
Chandoo_CascadingDropdowns_SubList2

The beauty of Roger’s approach is that it can handle any number of cascading levels, provided all the category names are unique. All you need to do is simply add the new subcategories to the right hand side of our validations table (Table1).

Let’s look at an example. If you look at the below screenshot, you’ll see that users can choose from a number of different kinds of meat:
Chandoo_CascadingDropdowns_Meat List

Let’s add a further level that would give meat eaters some further choices relating to how their meat is prepared.

To set this up, all we need to do is take the individual items from that ‘Meat’ column and add each one as a new column header:
Chandoo_CascadingDropdowns_New Headers

Then we simply list the new options for each type of meat below the relevant header:
Chandoo_CascadingDropdowns_Flesh out

Now here’s the magic: as soon as we add another column to our input table and set it up with data validation – which I did simply by clicking on the bottom right corner of the cell with the word ‘Human’ and dragging it across – then Excel picks up on the fact that there’s a sub-subcategory, and serves it up to us. *BING!* Order up!
Chandoo_CascadingDropdowns_Raw Person

Add code, and stir-fry for 10 milliseconds

As mentioned earlier, in addition to Roger’s great method, I’ve written some code that clears out any downstream entries in the event that an upstream entry is changed. It’s in the sample workbook already, all set to go. But here’s the actual code, for you VBA nerds. (Special thanks to Gabor Madacs for some enhancement suggestions)

Option Explicit

Const CHOOSE = "Choose…"

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo ErrorHandler
    Dim targetCell As Range
    Dim nextCell As Range
    Dim oldCalc As Excel.XlCalculation
    
    If Not Intersect(Target, [DataEntryTable]) Is Nothing Then
        If [Radio_Choice] = 1 Then
            With Application
                .EnableEvents = False
                .ScreenUpdating = False
                oldCalc = .Calculation
                .Calculation = xlCalculationManual
            End With
            
            For Each targetCell In Target
                'Clear any cells that use 'SubList' to the right of targetCell in the current table.
                If targetCell.Column < (targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - 1) Then 'there are table cells to the right
                    For Each nextCell In targetCell.Offset(, 1).Resize(, targetCell.ListObject.ListColumns.Count + targetCell.ListObject.Range.Column - targetCell.Column - 1)
                        If HasValidationFormula(nextCell) Then
                            If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = ""
                        End If
                    Next nextCell
                End If
                
                'Perform different action depeding on whether we're dealing with a 'MainList' dropdown
                ' or a 'SubList' dropdown
                If HasValidationFormula(targetCell) Then
                    Select Case targetCell.Validation.Formula1
                    Case "=MainList"
                        If targetCell.Value = "" Then
                            targetCell.Value = CHOOSE
                        ElseIf targetCell.Value = CHOOSE Then
                            'Do nothing.
                        Else
                            targetCell.Offset(, 1).Value = CHOOSE
                        End If
                        
                    Case "=SubList"
                        If targetCell.Value = "" Then
                            targetCell.Value = CHOOSE
                        ElseIf targetCell.Offset(, -1).Value = CHOOSE Then
                            targetCell.Value = ""
                        ElseIf targetCell.Value = CHOOSE Then
                            'Do nothing
                        Else
                            Set nextCell = targetCell.Offset(, 1)
                            If HasValidationFormula(nextCell) Then
                                If nextCell.Validation.Formula1 = "=SubList" Then nextCell.Value = CHOOSE
                            End If
                        End If
                    End Select
                End If
            Next targetCell
            With Application
                .EnableEvents = True
                .ScreenUpdating = True
                .Calculation = oldCalc
            End With
        End If
    End If
    Exit Sub
ErrorHandler:
    With Application
        .EnableEvents = True
        .ScreenUpdating = True
        If oldCalc <> 0 Then .Calculation = oldCalc
    End With
    MsgBox Err.Description, vbCritical, Name & ".Worksheet_Change()"
End Sub

Private Function HasValidationFormula(cell As Range) As Boolean
    On Error GoTo ValidationNotExistsError
    If cell.Validation.Formula1 <> "" Then
        HasValidationFormula = True
    Else
        HasValidationFormula = False
    End If
    Exit Function
ValidationNotExistsError:
    HasValidationFormula = False
End Function
 


Hungry for more?


Here’s some related Posts at Chandoo.org:

Download the file

To see how this is done, download this file and enable macros:
Dynamic-Dependent-dropdowns-20140214

About the Author.

Jeff Weir – a local of Galactic North up there in Windy Wellington, New Zealand – is more volatile than INDIRECT and more random than RAND. In fact, his state of mind can be pretty much summed up by this:

=NOT(EVEN(PROPER(OR(RIGHT(TODAY())))))

That’s right, pure #VALUE!

Find out more at http:www.heavydutydecisions.co.nz

Facebook
Twitter
LinkedIn

Share this tip with your colleagues

Excel and Power BI tips - Chandoo.org Newsletter

Get FREE Excel + Power BI Tips

Simple, fun and useful emails, once per week.

Learn & be awesome.

Welcome to Chandoo.org

Thank you so much for visiting. My aim is to make you awesome in Excel & Power BI. I do this by sharing videos, tips, examples and downloads on this website. There are more than 1,000 pages with all things Excel, Power BI, Dashboards & VBA here. Go ahead and spend few minutes to be AWESOME.

Read my storyFREE Excel tips book

Overall I learned a lot and I thought you did a great job of explaining how to do things. This will definitely elevate my reporting in the future.
Rebekah S
Reporting Analyst
Excel formula list - 100+ examples and howto guide for you

From simple to complex, there is a formula for every occasion. Check out the list now.

Calendars, invoices, trackers and much more. All free, fun and fantastic.

Advanced Pivot Table tricks

Power Query, Data model, DAX, Filters, Slicers, Conditional formats and beautiful charts. It's all here.

Still on fence about Power BI? In this getting started guide, learn what is Power BI, how to get it and how to create your first report from scratch.

56 Responses to “Creating in-cell bar charts / histograms in excel”

  1. Hypnos says:

    Ay jhakkas!!!

    Man, you're on a roll. A true-blue Excel innovator. What you're writing makes me think - why didn't anyone else think of this before?

    Now that I've showered all the praises on you, it won't hurt to have a few comments on my blaag 😉

    PS. I meant the innovator part.

  2. Chandoo says:

    @Amit ... thanks, I was also curious why this one was not explored, but again, I havent really searched a lot to ensure that I am posting the same ideas again. My intent is to make few people to benefit from this, if that happens I would be happy...

    btw, posted a comment on your blaag... hope you are happy now 😀

  3. Hypnos says:

    Don't worry about repeating the ideas in the online world. As long as you are not copying it off anyone else and it is helpful for the readers, it's fine.

    PS. the comment does not count.

  4. The idea actually is not a new one :).

    Check out MicroCharts
    http://www.bonavistasystems.com/
    to see how far you can get with font based in-cell charting

  5. [...] can never get tired of in-cell charts, whenever I get sometime, I try to experiment something on them. Here is an idea to design true [...]

  6. [...] Since we can insert any character in to a cell using formula, by installing a custom bar chart / pie font in our computer we can create incell graphs in excel with ease. Click here to see example pie chart, line chart. [...]

  7. Mrayo84 says:

    Where is the file? I can't seem to locate it. I want to donwload it. Thanks Chandoo!

  8. Mrayo84 says:

    Found it.

  9. mahqooi says:

    Great job, Chandoo. Love the site - and the fact that you provide downloads to help us (me) learn your secrets faster. I downloaded the font but can't figure out how to add it to my font library... Any hints? Thanks! Keep up the fantastic work.

  10. Chandoo says:

    @Mahqooi: Thank you and welcome to PHD 🙂

    This is how you can install a font in a windows machine:
    unzip the font files (if needed)
    select and copy the font file to clip board by pressing ctrl+c
    go to control panel > fonts
    paste the file by pressing ctrl +v
    repeat this procedure for other font files if any

    if you are using mac, just right click on the font file and select install option.

    let me know if you have some issues with this.

  11. cybpsych says:

    Hi Chandoo,

    is there any mirrors for the bargraph font?

    it seems that fontstruct.com is down for maintenance.

    thanks!

    • Chandoo says:

      @Cybsych: I am not sure if they have any mirrors. I will look in to my backup to see if a copy of the font can be located and ping you back. Thanks.

  12. cybpsych says:

    hi Chandoo, fontstruct is back online 😉

    BTW, I am wondering about this in-cell chart.

    How do I apply an automated conditional formatting to only a bar/point?

    For example, the first image in this post, whereby RED = highest, BLUE=lowest.

  13. Pedro says:

    Chandoo,
    I guess this bars only work with positive numbers? so if you a list of costs per month, but one month you have negative cost meaning income due to let's say vendor credits. This incell bar could despict the month with a negative digit. or could it?

  14. cybpsych says:

    hi Chandoo, guess that you missed out my query 😀

    is there a way to highlight the MAX and MIN bar based on the actual data (not the normalized)?

  15. Chandoo says:

    @Pedro, for that you need to have another set of characters (may be A-J for 0-9 and K-S for -1 to -9 and then use them to show the bars. It is a bit tricky, but achievable.

    @Cybpsych: The highlighting was done manually (As you can see, there is probably no easy way to highlight / change colors of a portion of cell using Conditional formatting etc.). I am sorry, but you need to use someother sparkline technique to achieve this (or, write your own macro)
    http://chandoo.org/wp/2008/09/05/microcharting-excel-howto/

  16. cybpsych says:

    thanks chandoo!

  17. Jason says:

    I love this simple and quick way of visualization results. I would like to learn more about normalizing values (i.e. the use of linear normalization). Can someone kindly point me in a good direction for this beginner? Much thanks to everyone (especially Chandoo) for the wealth of information provided. Long live the internet age!

    • Chandoo says:

      @Jason: you can use simple excel formulas to normalize a set of values. If the list of values is in say a1: a10 and you want them to be normalized from 1 to 100, you can do that with a formula like: =A1/max($A$1:$A$10) * 100. Also, you can use the RANK formula to calculate the percentile of any value in the list.

  18. Matt A. says:

    Nifty way to normalize the data....I'll have to take that into account when working with my charts.

    One thing I'd like to add, you can eliminate the need for custom fonts with the bar charts by using a REPT function and using a small "g" set to the Webdings font. It's more likely anybody opening the file will have access to that font than the custom one you've provided. (More portability is a good thing 🙂 )

  19. Pedro says:

    Portability is great.
    I don't quite see how the REPT formula and the webding fonts can combine to solve the portability issue.
    Mind you, i see that +REPT("g",1) will give you a bar, but we would need several bars of unequal lenght.

    Can you elaborate?
    Thank you

  20. Chandoo says:

    @Matt: I almost forgot about this comment. Thanks to Pedro for the bump.

    As he points, portability is a good idea, but we will not be able to get bars of variable height using webdings font.

    We can ofcourse use that along with text rotation and char(10) to create a pseudo incell bars. Here is a tutorial: http://chandoo.org/wp/2008/07/15/incell-bar-charts-revisited/

  21. Matt A. says:

    @Chandoo: Yep, that's exactly what I meant, use your text rotation and char(10) trick with REPT("G",) (then set the font to Webdings) to get your string of bars with variable height.

    @Pedro: REPT("g",1) will give you one "g" (or in Webdings a bar of 1 height).

    REPT("g",B2) will repeat for the value in B2... 🙂 Use that with Chandoo's take on linear normalizing, and yer all set.

    Wingdings with an "n" character would be even more portable, but just doesn't look quite as cool...but pretty much everybody has that font, so it'd be portable.

    You may have to adjust the font size in order to get all the bars to show correctly, perhaps some sizing of the row heights as well...

    You can fake an incell line chart by using:
    REPT(" ",B2-1)&REPT("n",B2)
    where B2 is the value in the cell you want as a data point.

  22. Matt A. says:

    Wow, the formatting was horrid, let's elaborate a bit more...

    REPT("",-1)&REPT("n",) - would give you a line graph, where could be a reference to each cell you'd like as a data point.

    REPT just repeats a text string a number of times, it can be either a hard number (like Pedro's example), or a reference to a value in another cell (more handy). I believe Webdings is a common font in the MS Office suites I'm familiar with (2000 thru 2003), but I'm not sure of 2007's suite.

  23. Chandoo says:

    @Matt A: I am sorry for the formatting mishap. I am afraid of using too many plug ins, but I guess a simple HTML based comment box seems like a good idea now that lot more commenters are typing formulas and vba code in the comment box.

    Coming to the formula.. thanks for sharing it. And yes, you are right, webdings is common to Office 2007 too. But even better solution would be to use good old pipe | symbol. When the font is Arial, the pipe character spacing looks optimum and subtle enough to look like an incell histogram / column chart.

  24. Matt A. says:

    After some searching through the character maps in Arial I noticed that there's a box symbol --> ? (created by holding ALT then typing 5595 on the numpad) that would work perfectly as another character to use for column charts. It looks just like the Webdings "g" character.

  25. Ben says:

    Is there a way to change the colour of the bars based upon the data. eg. 1-5 = red, 6-7 = amber, 8-10 = Green

  26. Chandoo says:

    @Ben... you can change the color of all bars in a cell using conditional formatting. But selectively changing color of bars inside cell is not possible unless you do it manually or through VBA.

  27. [...] Creating in-cell bar charts / histograms in excel @ Pointy Haired Dilbert Filed under: Stuff [...]

  28. Vinu says:

    Is this work only for the numbers or will it work for % data also. I tried to do the same for % data, but i didnt get. Pls let me know the formula for % data.

  29. prb says:

    Hello Chandoo,

    I really like this, but I have Office for Mac 2011 and for the life of me I cannot figure out how to see the bargraph as an available font.

    I have followed all the instructions for adding a font, but it does not appear. Do you have any suggestions?

    Thanks

    prb

  30. Ekta says:

    Thanks. This one was cool and helpful. Can we experiment the same with "in cell" line graph as well? 🙂

  31. Lawrence says:

    Chandoo,

    How do you "manually" change the color of the last bar in the series?

    Lawrence

  32. Hui... says:

    @Lawrence
    Select the chart
    Select the series
    Select the last point/column of the series
    Ctrl 1 or right click Format Point
    Select a color

  33. Lawrence says:

    Hui,

    Thanks!

    I should have been more descriptive. What I meant to ask was about the in-cell bar graph created with the REPT function described above. How do I get the last REPT (the last bar) to be a different color than the rest?

    Lawrence

  34. Hui... says:

    @Lawrence
    You cannot change colors in a cell using formula
    You can use either VBA code or do it manually
    Select the cell
    Copy and paste it as values
    Edit the cell F2
    using the arrows move to the character you want to color
    Shift and select the cell by arrow keying over it
    with the characyer selected
    Ctrl 1 (Format Cells)
    Change the Font Color to suit

  35. Matt A. says:

    It won't be a color change per se...but you can set an IF statement in your REPT formulas for different characters to show as the bars. The characters "c" and "g" in Webdings are both boxes, one is a solid block, the other an outline.

    For example, say I wanted to highlight the highest bar in my REPT formulas...my formula to translate the numeric cells A2:A15 to characters would be:
    IF(A7=MAX($A$2:$A15),REPT("c",B7),REPT("g",B7))

    so if the cell I'm checking (here it happened to be A7), is the highest number...its bar would display differently further along down in the concatenations...

  36. Lawrence says:

    @Hui...THANKS!

    @ Matt A... Very cool idea. What formatting do you recommend for the cell? The Webdings "c" hollow box is very faded and hard to read even if bolded and bigger font size is used. If I could just punch it up a bit it would be perfect with 5 "c" columns followed by a single solid "g" column...as in showing the trend in the trailing 6 months of data.

    Lawrence

  37. Matt A. says:

    @ Lawrence

    Good question...lately I've been using ? (which you get from holding ALT then typing 5595 on the numeric keypad) for most of my bars. Unfortunately the character map doesn't lead me to a differently "shaded" box of the same size. Reason I use this nowadays...it's part of arial font...just a special char map character I can rapidly input w/o any formatting nonsense.

    I'll check to see if I can replicate another box of same size that may have different shading using the same method...no luck as of yet.

  38. Leepy says:

    I've just built the in cell bargraph and was trying to create a pop up window which would display the Monthly Sales for Last 12 months when they click on any of the bargraph cells

  39. [...] Reference: http://chandoo.org/wp/2008/05/13/creating-in-cell-bar-charts-histograms-in-excel/ Like this:LikeBe the first to like this. [...]

  40. [...] To quickly insert an in cell micro-chart, use REPT() function… Get Full Tip [...]

  41. captainentropy says:

    Hi, there is a problem with the Bargraph font. On my win7 machine it works perfectly but when I try to install it on my boss's mac it returns an error called " 'Name' Table Structure"

    I tried to install on two different macs and the same error resulted. As a result the font does not show up as an option in any program.
     
    Just an FYI. I don't use macs but I know some people do.

  42. Marc Frutos says:

    Whats up! I just wish to give a huge thumbs up for the good info you might have right here on this post. I can be coming back to your weblog for extra soon.

  43. [...] like .docx, .htaccess etc.) 43. To quickly insert an in cell micro-chart, use REPT() function… Get Full Tip 44. COUNT() only counts number of cells with numbers in them, if you want to count number of cells [...]

  44. Sarah says:

    Thanks Chandoo for the font!! It works great once installed on my machine, but is there any way (besides printing and scanning the doc) that I can get the graphs to show up on other peoples' machines without going through the font install process? My file has to be sent out to clients that don't have that font installed.

  45. captainentropy says:

    Sarah, Excel doesn't allow embedding of fonts (aside from a workaround using a macro). The font will need to be sent to all who want to view the file. I went through the same question with my boss. I ultimately just installed the font on her computer.

    If the data is only to be viewed, and not modified, moved, etc. you can save the file as a pdf. The font can be viewed that way.

  46. joesali says:

    Hello every one there is a problem I need auto update summary formula from other sheets data pick please give me sample file and also auto up grate summary sheet format.................

  47. nikhi says:

    Hi chandu,
    Apart from excel, i need the formula to find bar graph height dynamically when using with log scale, for example for linear graph i would take the maximum value to height of the panel as
    (value divided by maxvalue) * height.
    Now , i am using a logarithimic graph can you tell me the right formula which fits perfectly.
    Thanks in advance

  48. Robert Marco says:

    Nice info... Thanks... very hepfull... 🙂

  49. The font does not seem to be available at fontshop. Is there somewhere else to download the bargraph font?

  50. Swapna says:

    Is there a way to do this without using bar graph font? We have a financial report to be published to stakeholders and they will not have this font installed, so probably will not be able to view the bar chart as well.

Leave a Reply