Treeviews in Access Tutorial – Part 1 Basic – Loading information into Treeview

The Treeview is a great free part of the Microsoft Common Control Library that lets you create your own Treeview and tie your own data and events into the Treeview. It can present a lot of information in a limited space, and allows a lot more versatility in presenting your information. Combine this with the ability to use small icons for each individual record, you get maximum structure on data presentation.

This is part 1 in a series on how to use the treeview in Access.

This first video demonstrates how to add a Treeview into your form, and how to load information into it. Its all very basic, explained and coded from scratch, with detailed explanations. Later I will upload more advanced guides on the same topic, but this is intended to be a very easy getting started guide.



Download “Treeview Demo Part 1 Sample (2003 format)” – Downloaded 2108 times – 22 KB

Download “Treeview Tutorial Part 1 sample (2007 format)” – Downloaded 14198 times – 31 KB


49 comments on “Treeviews in Access Tutorial – Part 1 Basic – Loading information into Treeview
  1. Jessie says:


    I’m using your tutorial to create a tree in my database. I entered the loadTreeview code using my data, but when I tried to open the form, I get the following error:

    Run-time error ‘2465’: Application-defined or object-defined error

    When I click “Debug”, it highlights the following in your code:

    set tv=forms(frm_TreeView_Example”).treeReqs.Object

    It seems the “.treeReqs.Object” isn’t being recognized by my system. How do I change this?


    • TheSmileyCoder says:

      Hi Jessie and welcome to my blog.
      I recently found out that not all combinations of Windows/Access will automatically add the reference to the treeview, when the treeview object is first inserted in a form (like it is done in my video).
      So start by checking your references, and make sure a reference is set to
      “Microsoft Windows Common Controls 6.0 (SP6)”
      If it does not occur in your list, try browsing for it, its usually installed in:
      Hope that helps, and best of luck with your project.

      • Ben says:


        I have the same problem as Jessie did but am still slightly lost.

        Unfortunately my programming knowledge is pretty basic and only goes as far as I have learnt for other adhoc stuff I have done, now that I am doing a treeview for the first time I am unsure how to make sure a referent is set to ‘Microsoft Windows Common Controls’. Is this something I would do in the code or in the menu options somewhere.

        Apologies for the stupid question, I have tried googling to find out but to no avail!

        Many thanks

  2. Sidnei says:

    😀 Hi!
    I have a MS Access database with a Treeview control in a form. The application runs fine in my client machines but I’m using a 64bits Office 2010 to mantain it. As the control is not supported in the 64bit version of Office, I do not even open that form. Is there some workaround to this problem should I have to really modify something in the Treeview control with my MS Office 2010 64bit edition?


  3. Samer says:

    I tried to modify the example to present arabic data in the children nodes but it comes as ?????
    Need your help and support please

    Many thanks

    • TheSmileyCoder says:

      Hi Samer

      In design view, try right clicking the treeview, select “TreeCtrl Object” and then “Properties”. In here there is a font tab, where you can see the fonts available. To be honest I don’t know if that allows or does not allow you to use arabic letters. I have never tried using arabic letters, and don’t even know how you guys manage to type them in a normal textbox.

      Best of luck with your project.

    • hello Samer,
      have you ever find a solution to your problem? coz i have the same problem but not “????”, it shows garbage instead.


  4. says:

    Hi I appreciate you providing this tutorial. I have a table with data of my own in which I am trying to get this to work but for whatever reason it won’t run with the addChildren call within the first Do While Not loop

    addChildren tv, nodX, empData, empData!Name

    my first node works and creates the root name where mine is equal to 0 which i have here:

    Set nodX = tv.Nodes.Add(, , , empData!Name)

    I will copy and paste my code which is very similar to yours but when i run it I receive:

    Run-time error ’13’:
    Type mismatch

    when i click debug it highlights the addChildren call which I have provided above. Here is my code below that I have completed. Thanks again for your help.

    Option Compare Database

    ‘Within this module the LoadTreeview function is created so the code below runs when the Org_TreeView form is selected.
    Public Sub loadTreeview()
    ‘declaration of treeview as TreeView
    Dim tv As TreeView

    ‘sets the treeview and references where the treeview will be viewed by the user
    Set tv = Forms(“Org_Treeview”).TreeDesign.Object

    ‘clear all previous node information so only new info populates (for future changes to the tables)

    ‘declare data in order to capture for the treeview
    Dim empData As DAO.Recordset

    ‘identifies that all data from the Employees table, ordered by OrgID to be used later by strFind
    Set empData = CurrentDb.OpenRecordset(“SELECT * FROM Employees ORDER BY OrgID”, dbOpenDynaset)

    ‘Declare variable which will find the data
    Dim strFind As String
    strFind = “OrgID =0”
    empData.FindFirst strFind

    ‘declare node
    Dim nodX As Node

    ‘Declare bookmark to store location of table
    Dim strBook As String
    ‘Create While loop in order to find data along with adding data to the Parent Node
    Do While Not empData.NoMatch
    Set nodX = tv.Nodes.Add(, , , empData!Name)

    ‘set bookmark during loop
    ‘strBook = empData.Bookmark

    ‘executes addChildren function which is declared and coded below “End Sub”
    addChildren tv, nodX, empData, empData!Name

    ‘restore location of bookmark after addchildren completes
    ’empData.Bookmark = strBook
    empData.FindNext strFind


    End Sub

    ‘Create Function in order to load child nodes which are OrgIDs >0
    Private Sub addChildren(tv As TreeView, nodParent As Node, empData As DAO.Recordset, lngParentID As Long)
    ‘Declare String variable used for Find method along with loading data from Table
    Dim strFind As String
    strFind = “OrgID=” & lngParentID
    empData.FindFirst strFind

    ‘Delcare node again
    Dim nodX As Node

    ‘Declare bookmark to store location of table
    Dim strBook As String

    ‘Do While loop loop until it doesn’t have a match
    Do While Not empData.NoMatch
    ‘identifies location of node along with parent node
    Set nodX = tv.Nodes.Add(nodParent, tvwChild, , empData!Name)

    ‘set bookmark during loop
    ‘strBook = empData.Bookmark

    ‘recursively calls additional children
    addChildren tv, nodX, empData, empData!Name

    ‘restore location of bookmark after addchildren completes
    ’empData.Bookmark = strBook
    ‘iteration to find next orgID #
    empData.FindNext strFind

    End Sub

    • TheSmileyCoder says:

      Hi Perseus.
      Looking at your code, I am guessing that empDate!Name is NOT a numeric field. The AddChildren routine as it is currently is expecting a Long as the last argument. The definition for the AddChildren reads:
      Private Sub addChildren(tv As TreeView, nodParent As Node, empData As DAO.Recordset, lngParentID As Long)

      As the lngParentID argument you are passing empDate!Name in this line:
      addChildren tv, nodX, empData, empData!Name

      I am a bit confused. Are you trying to load more than 1 organisation as well as their employees?

      • Jeremy Vail says:

        Hi. Thank you so much for responding to my question. I am trying to create a demo tree view with employees and their directs. For example: John Doe is the root and then Jim Beam is his direct, then he has 2 directs, and then those 2 have directs of their own.

  5. TheSmileyCoder says:

    Ok. I presume they are both in the same table. I get a bit confused since your code mentions OrgID which I am guessing is Organisation ID? Either way, the part passed to the AddChildren function should be the ID of the Direct. The current code is set to assume the primary key is numeric, for example a Autonumber column.

    If not the
    “lngParentID as Long”
    would need to be changed to for example
    “strParentID as string”
    as well as some modifications in the code to make it handle strings instead of longs.

    That said, I strongly urge you to use a autonumber primary key. It does not get affected by such issues as name changes (marriage/divorce) or 2 people having the same name.

  6. Norbert Meiss says:

    iI got the treeview working, but cannot change the font. The font tab in the properties simply doesn’t show. Is there a chance to change the font via VBA code?

    • TheSmileyCoder says:

      Hi Norbert
      What version of Office are you using?
      When changing the font it must be done through the ActiveX’s custom properties and not the active x container’s properties.

      If you still cannot change the font through the GUI, yes you can try to do it through VBA:
      for example.

      But if you still cannot change the font I will venture a guess that you are having a reference problem. But lets turn that stone when you have tried the above.

      • Norbert Meiss says:

        I use Office 2013 (32 bit) and this particular db was migrated from Office 2007. The treeview didn’t respond to events, but then I registered the OCX manually and the events worked again.

        However, the Font tab in the ocx properties did not show. Thanks for your code example – this finally works.

        • TheSmileyCoder says:

          Thank you for returning. I wonder what made the font tab not show. Maybe its a 2013 thing…

          But very pleased to hear that the code worked for you.

  7. Andrew says:

    Hey, your tutorial is awesome, keep up the good work! I have run into an error while attempting to adapt the code to handle multiple tables of data (each table holding a different level of the tree). I’m getting an “out of stack space” error on the recursive addChildren line within the addChildren sub. Here is my code:

    Private Sub addChildren(tv As TreeView, nodParent As Node, rsParent As DAO.Recordset, lngParentID As Long, strAttr As String)
    Dim strFind As String
    strFind = strAttr & lngParentID
    rsParent.FindFirst strFind
    Dim nodX As Node
    Dim strBook As String
    Do While Not rsParent.NoMatch
    Set nodX = tv.Nodes.Add(nodParent, tvwChild, , rsParent!projectDescription)
    Select Case rsParent!projectProposed

    Case True
    nodX.ForeColor = vbBlue
    Case False
    nodX.Bold = True

    End Select

    strBook = rsParent.Bookmark
    addChildren tv, nodX, rsParent, rsParent!themeID, “themeID=”
    rsParent.Bookmark = strBook
    rsParent.FindNext strFind

    End Sub

    I’ve noticed when stepping through your code that it somehow jumps from outside of the loop directly to the rsParent.Bookmark = strBook line, however it does not do this in my code any longer, and it’s baffling. Help would be appreciated! I’m in Access 2010.

  8. Pavel says:

    Hi! Thank you so much for such great tutorial.
    Anders, could you please help me with my problem.
    When I add any control on the form containing TreeView I immediately get compiler’s error “Type Mismatch” on the string
    Set tv = Forms(“frm_TreeView_Example”).treeReqs.Object
    How it could be solved?
    Thank you

    • TheSmileyCoder says:

      Hi Pavel
      That sounds weird, and I haven’t run into something like that before. Are you using the sample download provided?
      I would suggest you start by checking the references to see if anything is missing.

      If that doesn’t help, try removing the treeview control from the form, and then adding it back in (And check reference)

  9. al capps says:

    I have my data in a single table row Level1ID, level1Text, Level2ID, level2Text, Level3ID,, level3Text level4ID, level4Text and I want how would you set up the structure to work. I see where you have a single ID and a level type. Is there a way to load the tree view using a this type of a structure.. not sure how to go more that one level deep.. Level1 and level2 are ok.. but the recursive call after that is what I am hung on.

  10. Caroline says:

    Just wanted to say thank you for the fabulous tutorials. They helped me a great deal to achieve what I needed to do.

    My rather complicated procedures are working great now, thanks to you.

    Much appreciated

  11. Jason says:

    Hello TheSmileyCoder,

    Very helpful your tutorials, so thank you.

    I am having a hard time finding any information on how to generate reports on treeviews. It seems recursively querying a treeview table is not something that is easily done in MS Access reports. Any ideas or links?


    • TheSmileyCoder says:

      It really depends on the structure of your data. If its a simple department/employees, then the report/subreport model fits nicely. Or really any tree where you know how deep it will run, i.e. how many levels, should be something you can cover by a report/subreport.

      If its single table hierarchical data of unknown depth, then either you need to use a different data table method such as a closure table, or a temp table. If you are using something like SQL server as your backend, then you could use a recursive query by CTE to get the data.

  12. Jason says:

    Thanks, that helps.
    I am still developing the DB and am not at the reporting stage yet, but I wanted to determine which design approach to take. You have given me good insight on that. Thank you,

  13. Kieran Shirey says:


    Firstly, thanks for posting this valuable information.

    I have the same issue as Jessie:
    I’m using your tutorial to create a tree in my database. I entered the loadTreeview code using my data, but when I tried to open the form, I get the following error:

    Run-time error ‘2465’: Application-defined or object-defined error

    When I click “Debug”, it highlights the following in your code:

    set tv=forms(frm_TreeView_Example”).treeReqs.Object

    I tried your advice of: ‘So start by checking your references, and make sure a reference is set to
    “Microsoft Windows Common Controls 6.0 (SP6)”
    If it does not occur in your list, try browsing for it, its usually installed in:
    That reference is set but it has its location as sysWOW rather than System32. Do I need to place a copy of the mscomctl.ocx in there and register it or would you have another suggestion?
    Kind regards,

    • TheSmileyCoder says:

      I don’t know if its a copy paste error on your part, but the line
      set tv=forms(frm_TreeView_Example”).treeReqs.Object
      is missing a double quote, it should be:
      set tv=forms(“frm_TreeView_Example”).treeReqs.Object

      In this example, it expects to find a treeview control named treeReqs on the form “frm_Treeview_Example”. If you created the form yourself, you will need to rename the texts accordingly.

      • Kieran Shirey says:

        Thank you so much. Facepalm moment. You can look at it for hours sometimes and not see the smallest thing. I’m building an app at the moment to allow me to demonstrate predictive modelling tool so your tutorials are just invaluable and I will certainly make a donation. You may hear a little from me over the next few months but I’ll try not to bother you.

  14. Steve Hembry says:

    Thank you for the tutorial. I am completely new to VBA. What is the minimum amount of code required to show the top level node?

    I would like to get that functioning as a confidence boost.

    • TheSmileyCoder says:

      To just add a node (with no reference to a table) it might look like so:
      Dim tv as Treeview
      Set tv=me.treeviewControl.Object
      tv.nodes.add ,,"Test"

  15. Kornel Rapai says:


    I tried to build up treeview. During the data loading there is an error. “Compile error: A module is not a valid type”
    “Private Sub addchildren(xyz…)” is highlited.
    This is the call: addChildren tv, nodX, rsReqs, rsReqs![5WhyID]
    And this is the sub: Private Sub addChildren(tv As Treeview, nodParent As Node, rsReqs As DAO.Recordset, lngParentID As Long)

    Could you help me what’s wrong?

    • TheSmileyCoder says:

      I don’t think I’ve ever come across that error before. Have you by chance named your module the same as the function?

  16. Elhoussine Korichi says:

    Thank’s for all you did, it’s very helpful
    I have a question abot Treeviews
    I want to remove duplicate nodes, how can I check if a child node exists before adding it to the treeview

    Thnk’s in advance
    Kind regards

    • TheSmileyCoder says:

      The best way would normally be to ensure that the query feeding your Treeview doesn’t contain duplicates, but I know there are cases where that might not be feasible.
      The key of a treeview node must be unique (and not start with a number), and usually I use the ID of the record along with a prefix to ensure its not a number.
      I don’t know of a way to check for a duplicate key, without triggering an error, so I find it easiest to write a small function, which will handle the error.
      Public Function node_exist(ByRef tv As TreeView, ByVal key As String) As Boolean
      ‘This function will return True if node exists, and false otherwise
      On Error Resume Next
      node_exist = tv.Nodes(key).Index <> 0

      End Function

  17. Ken says:

    Hi Smiley,

    I just viewed several of your videos and tutorials on treeview. I just upgraded my office to 2013 and treeview works fine on my computer with the latest ed of Windows 10.

    My question; however, has to do with structure.

    Your table has more than 2 fields, my database has several tables with only 3 fields (tables ID and information, and an ID for a linked table backwards). The structure was made this way because several records duplicate in the respective fields so I made separate tables to limit redundancy (Main, Levels 1 through 5).

    My treeview works until I get to the children. On your video you have PK_Req and ID_Type. My main table is tbl_Main with only 2 fields, MainCategoryID which I associate with your PK_Req and MainCategory which corresponds to your mem_Req.

    In my subsequent tables (Level1 through Level5) are similar (inclusive) fields such as “MainCategoryID, Level1CategoryID, Level1Category” … “Level1CategoryID, Level2CategoryID, Level2Category”

    My database has an error when it gets to “addChildren tv, nodX, rsReqs, rsCategory!MainCategoryID” which corresponds to your “addChildren tv, nodX, rsReqs, rsReqs!PK_Req” line of “Private Sub addChildren…”

    The error is an Run-time error ’28’: Out of stack space and I’m presumming I need to associate this line to the next table which would have “my” Level1 information but I don’t know how to change the line. When I change MainCategoryID to Level1CategoryID it has an error since Level1 table hasn’t been called or identified within the module.

    I don’t know if you still monitor this blog, but if you do, thank you for your time and attention to this message

    • TheSmileyCoder says:

      Out of stack space sounds like you have some recursion gone off the deep end, and it continues to add more nodes until the system is out of memory.

      • Ken Baker says:

        Hi SmileyCoder,

        I have resolved that issue and my treeview is now working 6 linked databases which have the following structure:

        Main Category

        MainCategoryID (Linked to Main)

        Level1CategoryID (Linked to Level1)

        Level3 through Level5 similar structures.

        The tree continues to work as I have placed some variables in to do comparison checks until it gets to about level3 data then it does a jump on the variables and loses count.

        there is a similar if then check on each level and it checks to see if there is a match in id # comparisons such:

        Do While Not rsL1Category.NoMatch

        L1_MCatID = rsL1Category!MainCategoryID
        L1CatID = rsL1Category!Level1CategoryID

        If L1_MCatID MCatID Then
        If L1_MCatID > MCatID Then
        GoTo Exit_L1DoWhile
        ElseIf L1_MCatID < MCatID Then
        GoTo IncreaseL1ID
        End If
        End If
        'end validation




        End Sub

        After Main (the true first level), which doesn't need a check, each level (Level1 or L1 through Level 5 or L5) has this check to make sure it is still comparing the same row.

        the tree works until it reaches level 3 and then completes without the rest of the data.

        As a side note, this is a creation of the levels of eBay categories which was created from an excel *.csv sheet.

        Any help would be appreciated.

        And thank you for responding to my original post, I sincerely appreciate your time.


        • Ken Baker says:

          correction, it is working 6 linked tables, one database

        • TheSmileyCoder says:

          In theory its possible to do it your way, but I wouldn’t recommend it. Imagine if you decide some level 3 category is now a level 2 category? You would need to move all sorts of records around between tables. It really should be in just a single table.
          Its really hard to give more specific advice without having the database in front of me. Sorry.

          • Ken Baker says:

            I understand what you are saying. I was able to fix it to see all 6 tables, and if you would like, it would be a pleasure to send you the database to get your input.

          • TheSmileyCoder says:

            The correct solution is to load the data into a single table, and work at it from there.
            I am afraid I don’t have the time availble at the moment to offer more support on this.

  18. Lee Fitzsimons says:

    Hi, I’m playing with creating a treeview for an upcoming project at work. A complete novice.

    I’m hoping there’s an obvious solution to you but I keep getting hit with Run-time error ‘394’.

    Any idea what may be causing it?

    Thanks in advance.

  19. Hello!

    I’m having the same issue everytime i try to use tv.Nodes



    Can you help me, please?

    Thank you a lot!

  20. Amin says:

    Good Day Sir, Thanks for your help!

    Sir I am using Persian language with the tree view controller and it is showing ?????? could u please advise me how to solve the issue.
    many Thanks,


    • TheSmileyCoder says:

      I’m afraid I don’t have experience with that. Have you set the font of the treeview to something that supports Persian(if that is required)?

Ask a question, leave some feedback, post a reply!

This site uses Akismet to reduce spam. Learn how your comment data is processed.