Learn Microsoft Access Advanced Programming Techniques, Tips and Tricks.

Creating Access Menu with Tree View Control

The Microsoft Access Project Menu, when finished with the Tree View Control, will look like the Image given below.

The Image above shows the Report Group’s third Option Custom Report is selected and highlighted, with the Report Filter Parameter Form open, overlapping the Menu Screen, for User’s input.

Before going into that, in last Week’s Lesson we have learned how to organize the related items in hierarchical order, using Microsoft Tree View Control, based on the Sample  data Table. 

I have made a point last week, that the related items in Tree View control’s data need not necessarily be next to each other.  After this you will be more clear about as how to update Relative Keys of Child Nodes, irrespective of it’s physical position of the records in the Table, but based on the relationship with it’s Parent Node IDs. 

This was the Data Table that we have used and finished with last week’s exercise:

Can you add the following list of items at the end of the above table and update their ParentID field values so that the TreeView display look like the sample image given below:

New records for Table item record related field:

  1. Text Field.
  2. Number Field.
  3. Date/Time Field.
  4. Hypelink Field.

Form related Controls:

  1. Text Box.
  2. Command Buttons.
  3. Combo Box.
  4. List Box.

Report related Controls:

  1. Text Box.
  2. Label.
  3. Graph Chart.

Assign ParentID Values to these items so that the Tree View Display looks like the following Image:

Now, we will proceed with the creation of an MS-Access Project Menu and learn what it takes to create one. A simple Menu Image is given below:

It is a simple Menu with only three group of options: Forms, Report Views and Macros. 

Under Forms Group two options are given, the first one displays the Tree View controls Menu table record.  The second Option displays the same records in continuous form mode.

The first option under Report View displays a Report on products Category records, from the Categories Table of NorthWind.accdb database.

The second option displays the Products List-Price Report.

The third option opens a Parameter Form so that the User can set the Minimum and Maximum List-Price values range, to Filter data for the Products List-Price Report.

Under the Macros Processes Group both option runs Macro1 and Macro2 respectively and displays different messages.

We need a Menu Table with the above option records with some additional fields, besides the usual TreeView’s Unique IDs, Description and ParentID data fields.  The Menu Table Image is given below:

Create a Table with the above structure and add the above records and save it with the name MenuID field is AutoNumber, PID and Type fields are Numeric fields, others are Text Fields.

We are familiar with the first three Data Fields: the Unique ID, Description and the ParentID Fields. Here, I have shortened the ParentID field name to PID.

We need four more fields in the Menu Table, one field Type for the object type Code and three fields Form, Report and Macro.

Type Field contains the Access Object Type Numeric Codes to identify the Option the User clicked on.

  • Form field is for Form Names, object Type code 1,
  • Report Field contains Report Names, object Type code 2,
  • Macro Field is for Macro Names, object type code 3.

Note: All the object names can be put in one Column. We have used separate fields for clarity only.  If you do that then make changes in the VBA Code, wherever it references different field names.

Based on the code numbers we can pickup the Object Names, from their respective fields and call the DoCmd.Openform or Docmd.OpenReport or Docmd.RunMacro to execute the action on the Child Node Clicks.

Now, the only question remains is how to link/store these two information (the Type Code and Object Name) on the Child Nodes?  We will take up that topic when we start Adding the Nodes to the Tree View control.

We need two more data Tables for sample Forms and Reports.  The Categories Table and Products Tables, from the NorthWind.accdb sample Database.  To save your time I have attached the Demo Database with all the Objects and Programs at the end of this Page to Download and try it out.

Create two Forms using the Menu Table with the names Data Entry and another Form Data View in continuous Form mode.

Create two Reports, one on the Categories Table with the report name: Categories,  another report on Products Table with the name Products Listing.  Add a long Label control below the main heading on the Products Listing Report and change the Name Property Value to Range.

Create a small form with two unboound Text Boxes and change their name Property Value to Min & Max, like the design given below:

Add two Command Buttons as shown above.  Change the Caption Property Value of the first Button to Open Report and the Name Property Value to cmdReport.

Change the Second Command Button’s Caption to Cancel and the Name Property value to cmdCancel.

Display the Code Module of the Form.  Copy and Paste the following Code into the Form Module and save the Form:

Private Sub cmdOpen_Click()
Dim mn, mx, fltr As String
mn = Nz(Me![Min], 0)
mx = Nz(Me![Max], 9999)
If (mn + mx) > 0 Then
    fltr = "[List Price] > " & mn & " And " & "[List Price] <= " & mx
    DoCmd.OpenReport "Products Listing", acViewReport, , fltr, , fltr
    DoCmd.OpenReport "Products Listing", acViewReport
End If

End Sub

Private Sub cmdCancel_Click()
End Sub

When the User sets a Value Range by entering the Minimum and Maximum List Price range in their respective Text Boxes the Report Filter criteria String is created.  The Report Filter String value is passed to the Product Listing Report as Open Report command Parameter.  The Filter String value is also passed as OpenArgs (Open Argument) Parameter. 

The Filter parameter filters the Report Data, based on the Criteria, specified in Min & Max fields, and the open argument value is copied to the Range Label Caption when the Report is open.

Copy and Paste the following Code into the Product Listing Report’s VBA Module:

Private Sub Report_Open(Cancel As Integer)
    DoCmd.Close acForm, "Parameter"
    Me.Range.Caption = Nz(Me.OpenArgs, "")
End Sub
  1. Create a new Form, with the name frmMenu and add the Microsoft TreeView Control from the Activex Control’s List.  Resize the Control as shown in the Design View below:
  2. Change the Tree View Control’s name to TreeView0 in the normal Property Sheet.
  3. Add a Command Button below the Tree View control.  Change it’s Name Property Value to cmdExit and Caption Property value to Exit.
  4. Right-Click on the Tree View Control and highlight the TreeCtrl_Object option and select Properties to display the Property Sheet.
  5. Change the following Property Values as given below:
  • Style = 7 (tvwTreeLinesPlusMinusPictureText)
  • Line Style = 1 (tvwRootLines)
  • LabelEdit = 1 (tvwManual)

Last Week we have changed the first two Property Values.  When LabelEdit Property’s default value is 0 -  tvwAutomatic, Clicking on the Node twice (not double-click) the Node-Text will go on Edit Mode and you can change the Text.  But it will not directly update on the data source field.  By changing it to 1 – tvwManual will prevent it from going into edit mode.

We can change this through Code by adding the following lines in the Form_Load() Event Procedure:

With Me.TreeView0.Object
    .Style = tvwTreelinesPlusMinusPictureText
    .LineStyle = tvwRootLines	
    .LabelEdit = tvwManual
End With

Last Week we have used the Form_Load() Event Procedure to read the Tree View Node values to create the Root-level and Child Nodes.  We need the same Procedure here also with few lines of  additional Code.

Besides that we need to trap the Node_Click() Event of Nodes to check which Option the User has selected.

Copy and Paste the following VBA Code into the Form Module and Save the Form.

Option Compare Database Option Explicit Dim tv As MSComctlLib.TreeView Const KeyPrfx As String = "X" Private Sub Form_Load() Dim db As Database Dim rst As Recordset Dim nodKey As String Dim PKey As String Dim strText As String Dim strSQL As String Dim tmpNod As MSComctlLib.Node Dim Typ As Variant Set tv = Me.TreeView0.Object tv.Nodes.Clear

‘Change the TreeView Control Properties

With tv
    .Style = tvwTreelinesPlusMinusPictureText
    .LineStyle = tvwRootLines
    .LabelEdit = tvwManual
    .Font.Name = "Verdana"
End With

strSQL = "SELECT ID, Desc, PID, Type,Macro,Form,Report FROM Menu;" Set db = CurrentDb Set rst = db.OpenRecordset(strSQL, dbOpenDynaset) Do While Not rst.EOF And Not rst.BOF If Nz(rst!PID, "") = "" Then nodKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc Set tmpNod = tv.Nodes.Add(, , nodKey, strText) 'Root-Level Node Description in Bold letters With tmpNod .Bold = True End With Else PKey = KeyPrfx & CStr(rst!PID) nodKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc Set tmpNod = tv.Nodes.Add(PKey, tvwChild, nodKey, strText) 'Check for the presense of Type Code If Nz(rst!Type, 0) > 0 Then Typ = rst!Type Select Case Typ Case 1 'save type Code & Form Name in Node Tag Property tmpNod.Tag = Typ & rst!Form Case 2 'save type Code & Report Name in Node Tag Property tmpNod.Tag = Typ & rst!Report Case 3 'save type Code & Macro Name in Node Tag Property tmpNod.Tag = Typ & rst!Macro End Select End If End If rst.MoveNext Loop rst.Close Set rst = Nothing Set db = Nothing End Sub Private Sub cmdExit_Click() If MsgBox("Close Menu Form? ", vbYesNo, "cmdExit_Click()") = vbYes Then DoCmd.Close End If End Sub Private Sub TreeView0_NodeClick(ByVal Node As Object) Dim varTag, typeid As Integer Dim objName As String, nodOn as MSComctlLib.Node If Node.Expanded = False Then Node.Expanded = True Else Node.Expanded = False End If

‘Reset the earlier lighlight to normal

For Each nodOn In tv.Nodes
    nodOn.BackColor = vbWhite
    nodOn.ForeColor = vbBlack

‘changes BackColor to light Blue and ForeColor White

tv.Nodes.Item(Node.Key).BackColor = RGB(0, 143, 255)
tv.Nodes.Item(Node.Key).ForeColor = vbWhite

‘—Highlight code ends-

varTag = Nz(Node.Tag, "") If Len(varTag) > 0 Then typeid = Val(varTag) objName = Mid(varTag, 2) End If Select Case typeid Case 1 DoCmd.OpenForm objName, acNormal Case 2 DoCmd.OpenReport objName, acViewPreview Case 3 DoCmd.RunMacro objName End Select End Sub

On the Global Declaration Area of the Module the Tree View Object is declared.  A constant variable KeyPrfx is declared with the value “X”.

The Form_Load() Event Procedure of last week’s Article we have modified with additional Code.  I have commented the new Code segment to give an indication of what it does but will explain what it does.

The Procedure declares Database, Recordset and four String Variables.  Next two line declares a temporary Node Object: tmpNod and Typ Variant Variables are declared.

Next, the TreeView Object tv is assigned with the TreeView0 Object on the Form.  The TreeView0’s existing Nodes, if any, are cleared with the statement: tv.Nodes.Clear, in preparation for loading all the Nodes again.

We have implemented the following Code to modify the Tree View control’s Properties through Code, rather than through the Property Sheet.

With tv
    .Style = tvwTreelinesPlusMinusPictureText
    .LineStyle = tvwRootLines
    .LabelEdit = tvwManual
    .Font.Name = "Verdana"
End With 

The Tree View Font is changed to Verdana. Besides that we will bring in some more functions like expand or collapse all the Menu Groups with one click, rather than manually expanding or collapsing one group after the other.

The new SQL String is modified to add the new Fields Type, Form, Report and Macro Fields from Menu Table.

The Menu Table’s first record is checked for the presense of any value in PID field, if it is empty then it is a Root-level Node record. It is added to the Tree View Object as the Root level Node and it’s reference is saved in the tmpNod Object.

The Node have several properties like Forecolor, Bold and several others out of that we have taken the Bold Property and assigned True to make the Root level Node look different than it’s Child Nodes.

If it is not Root Node entry then it has the PID value, the program takes the Else clause and the record is added as a Child Node.  Here, we checks the Type field value.  If it contains one of the three values 1, 2 or 3 then we must take the value from Form, Report or Macro Name along with that the Type Code and join them together  (like ”1Data Entry”, “2Category Listing” etc.) and save it in the Tag Property of Child Nodes.  We are familiar with the Tag Property in Access controls, like Text Boxes, Labels, Command Buttons and others, but we rarely use it.

The cmdExit_Click() Procedure closes the Menu Form, if the response from the User is affirmative.

When the User clicks on a Child Node, the value we have saved in it’s Tag Property must be extracted and checked to determine what to do next.  For this we need a TreeView0_NodeClick() Event Procedure.

Private Sub TreeView0_NodeClick(ByVal Node As Object) Dim varTag, typeid As Integer Dim objName As String, nodOn as MSComctlLib.Node If Node.Expanded = False Then Node.Expanded = True Else Node.Expanded = False End If

‘Reset the earlier lighlight to normal

For Each nodOn In tv.Nodes nodOn.BackColor = vbWhite nodOn.ForeColor = vbBlack Next nodOn

‘changes BackColor to light Blue and ForeColor White tv.Nodes.Item(Node.Key).BackColor = RGB(0, 143, 255) tv.Nodes.Item(Node.Key).ForeColor = vbWhite ‘—Highlight code ends- varTag = Nz(Node.Tag, "") If Len(varTag) > 0 Then typeid = Val(varTag) objName = Mid(varTag, 2) End If Select Case typeid Case 1 DoCmd.OpenForm objName, acNormal Case 2 DoCmd.OpenReport objName, acViewPreview Case 3 DoCmd.RunMacro objName End Select End Sub

The Click() Event Procedure receives the clicked Node’s Reference as Parameter in the object Node.  At the beginning of this procedure we have declared few Variables.

Next few lines checks whether the clicked Node is in expanded or collapsed state.

Normally, to expand a Node, to show it’s hidden child Nodes, either we click on the + (plus symbol) at the left side of a Node or double-click on the Node itself.  Double-Clicking on the Node again or clicking on the – (minus symbol) will hide the Child Nodes.

With the following Code segment we can expand or collapse Child-Nodes with a single Click:

If Node.Expanded = False Then
    Node.Expanded = True
    Node.Expanded = False
End If 

The next six executable lines ensures that the Node received the Click remains highlighted.

‘Reset the earlier Highlight to Normal

For Each nodOn In tv.Nodes nodOn.BackColor = vbWhite nodOn.ForeColor = vbBlack Next nodOn

‘Changes BackColor to light Blue and ForeColor White tv.Nodes.Item(Node.Key).BackColor = RGB(0, 143, 255) tv.Nodes.Item(Node.Key).ForeColor = vbWhite ‘—Highlight code ends-

Next, the Tag Property value is read into the varTag Variable. If it is not empty then the value is split into two part. The Numeric value is extracted and saved in Typid variable and the Object Name part is saved in variable objName.

Depending on the value in Typid variable the Docmd is executed to open the Form, Report or Runs the Macro.

We will add two more Command Buttons on the Top of the Menu. One to expand all the Nodes with one Click and the second one to collapse all the Nodes.

  1. Add two more Command Buttons at the top area of the Tree View Control as shown on the design below.
  2. Change the Name Property Value of the left Command Button to cmdExpand and the Caption to Expand All.
  3. Similarly, change the right-side Command Button’s Name Property to cmdCollapse and the Caption to Collapse All.
  4. Copy and Paste the following VBA Code below the existing Code in the frmMenu Form Module and save the Form.
Private Sub cmdExpand_Click()
Dim Nodexp As MSComctlLib.Node

For Each Nodexp In tv.Nodes
    If Nodexp.Expanded = False Then
        Nodexp.Expanded = True
    End If
Next Nodexp
End Sub

Private Sub cmdCollapse_Click()
Dim Nodexp As MSComctlLib.Node

For Each Nodexp In tv.Nodes
    If Nodexp.Expanded = True Then
        Nodexp.Expanded = False
    End If
Next Nodexp
End Sub

At the beginning of the cmdExpand_Click() Event we have declared a Tree View Node object NodExp.  The For . . . Next loop takes one Node at a time and checks whether it is in expanded form or not.  If not then it’s Expanded Property value is set to True.

Similarly the cmdCollapse_Click() Event makes a similar check and if it is in expanded state then the Expanded Property value is set to False.

The full Tree View Control’s all Nodes can be expanded and makes all their child Nodes visible at once or all Child Nodes kept hidden except the Root-level Nodes.

Hope you enjoyed creating the new Menu for your Project.  If you run along the design task step by step then your Menu should look like the finished Menu Image given at the top.

During the Year 2007 I have designed a Menu in one of my Projects, for Vehicles Service Contract System, using the Tab Control with several Pages. Each Page having 10 or more Options and to make each Page appear in turn at the same area, when the User Clicks on the Command Buttons lined up at either side of the Menu. Command Buttons at the right-side also changes, based on the selection of left side Button.

Click to Enlarge

You can find the Menu Design with Tab Control Article on this Link:https://www.msaccesstips.com/2007/06/control-screen-menu-design.html


  1. MS-Access Class Module and VBA
  2. MS-Access VBA Class Object and Arrays
  3. MS-Access Base Class and Derived Objects
  4. VBA-Base Class and Derived Object-2
  5. Base Class and Derived Object Variants
  6. MS-Access Recordset and Class Module
  7. Access Class Module and Wrapper Classes
  8. Wrapper Class Functionality

Microsoft TreeView Control Tutorial

A. Introduction.

Microsoft Tree View Control is part of Microsoft Windows Common Controls. It is an interesting piece of Object that displays related data in an hierarchy of Nodes.  It can display related data, like entries and sub-entries in an Index List or listing of folders like Windows Explorer’s Left-Pane or a List of related Items in an hierarchical structure with Tree-Lines, Check-Boxes and Graphics of bitmap Images.

The ListView and ImageList Controls are part of Windows Common Controls and we will be using them along with the TreeView Control in Microsoft Access. 

I think you would like to look at some sample TreeView Control Demo Images, which we will be working on to build in the coming few weeks.

B. Sample Demo Images.

  1. The Sample Demo TreeView Image with all Nodes in Collapsed form.
  2. The above TreeView Control Nodes in expanded view.
  3. TreeView Sample Display, with arrow-head Image Icons displayed to the left of each Node Text.
  4. Next, the TreeView Display with linked data in a Sub-Form.  Root level Nodes have two Images.  Folder-Closed Image is displayed in normal mode.  When the Root Level Node receives a Mouse Click it displays the Folder-Open image and displays the Child-Nodes in expanded form. 

    Related information is displayed on the Sub-Form based on selection of Root level Node.

    One of the Child-Node item selected it displays another Form (normally kept hidden) with related information.

  5. On the next Form Image there are two Panels. The Product Category Item related Nodes are in TreeView Control, in the left Panel.  When one of the Category item receives a Click on the TreeView control, related Product Items with Quantity and List Price in separate Columns will appear in ListView Control, in the right-side Panel.

C. Creating Sample Data for Trial Run.

Let us try out the TreeView Control with some sample data shown below, based on the first two images shown at the beginning of this Page.

The above sample data table have three Fields. 

  • The ID field is an AutoNumber field with Unique ID Numbers.  The AutoNumber type is selected for our convenience.  In either case All records in the Table should have a Unique ID Value.  If it is Numeric then it should be converted into String Type, before adding it to the TreeView Control.
  • Second field is Node Description (Desc). The rows of information on this Column are  logically related. 
  • The third ParentID field is Numeric Type, to match the type of ID Field.  But it should be converted to String Type before using it on TreeView Control.

We must know how the Description Column values are related each other, based on that we can establish the relationship by entering related values into the ParentID field.

For example: The logical arrangement of relationship between Author of Books, Publishers of the Books,  the Book Stores where the Books are on Sale etc. or like Relationship between members iof a Family Tree. 

Relationship between Product Category, Products, Stock, Price and so on. All these information may not appear under one Column in a single Table.  They may appear in different Columns or in different tables as well.

The ParentID field is very important that it determines the hierarchical arrangement of Nodes. If the ParentID Field is empty then that record should go as a Root-level Node.  The Child-Node always should have their ParentID filled in with it’s Parent records ID Value.

Root level Node can have one or more Child Node(s), Child Node can have it’s own child Node(s).

We will load the above data into a TreeView Control and see how it looks.  Then we will fill up the ParentId field with related IDs to change the view, the way we want to see it in a logical order.

D. Windows Common Controls Library file.

  1. But, first thing first, open one of your Database or create a new one.
  2. Open the VBA Window (ALT+F11) and select References… from Tools Menu.
  3. Look for the File: Microsoft Windows Common Controls in the displayed list of files and put check-mark to select it.

    If you could not find the file in the list, Click Browse... Button and find the file: MSCOMLIB.OCX in the Windows System directory, for Windows 7 Version look for the file in SysWOW64 folder.  Click OK to close the Library Files listing Control.

  4. Create a Table with the following structure:
  5. Save the Table with the name Sample.
  6. Fill the Table with the sample data of 12 records as shown on the data view Image above.

    E. Creating TreeView Control on Form

  7. Create a New blank Form.
  8. Click on Activex Controls button from the Controls Group, find the Microsoft TreeView Control and select it.
  9. Click OK to insert a TreeView control on the Form.
  10. Drag the control down and to the right to leave some space at the top and left of the TreeView Control.  Drag the bottom right corner sizing handle towards the right and bottom corner to make the control larger, like the sample image given below.
  11. Display the Property Sheet of the control and change it’s Name Property Value to TreeView0, if it is different there.
  12. Display VBA Editing Window of the Form.
  13. F. Access VBA Code.

  14. Copy and Paste the following VBA Code into the Module overwriting the existing lines of Code there:

    Option Compare Database Option Explicit Dim tv As MSComctlLib.TreeView Const KeyPrfx As String = "X" Private Sub Form_Load() Dim db As Database Dim rst As Recordset

    Dim strSQL As String Dim nodKey As String Dim ParentKey As String Dim strText As String Set tv = Me.TreeView0.Object strSQL = "SELECT ID, Desc, ParentID FROM Sample;" Set db = CurrentDb Set rst = db.OpenRecordset(strSQL, dbOpenDynaset) Do While Not rst.EOF And Not rst.BOF If Nz(rst!ParentID, "") = "" Then nodKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc

    ‘Add the TreeView Root Level Nodes tv.Nodes.Add , , nodKey, strText Else ParentKey = KeyPrfx & CStr(rst!ParentID) nodKey = KeyPrfx & CStr(rst!ID) strText = rst!Desc

    ‘Add the Record as Child Node tv.Nodes.Add ParentKey, tvwChild, nodKey, strText End If rst.MoveNext Loop rst.Close Set rst = Nothing Set db = Nothing End Sub

  15. Save the Form with the name frmSample, but don’t close the VBA Window.

    G. VBA Code Line-by-Line.

Let us take a quick look at the VBA Code and understand what it does.

In the Global Declaration Area, of the Form Module, the Variable tv declared as TreeView Object.  The KeyPrfx declared as Constant , with String Type value “X”. 

The TreeView Node’s Key Value must be always of String Type and needs at least one non-numeric character present in the Node Key.  Our sample Table Key Values are all in numeric form, we can convert and add it to the Constant value “X”.  Numeric Value converted into String Type alone will not accept as Node-Key.

Note: If the Node-Key and Parent-Key  values are already in Alpha or Alpha-Numeric form then the question of conversion doesn’t arise.  All Node-Key values must be Unique.

In the Form_Load() Event Procedure the Database and Recordset objects are declared.  Four String Variables are also declared.

The statement Set tv = Me.TreeView0.Object statement assigns, the TreeView0  Object on the Form, to the object variable tv.

The OpenRecordset() statement opens the Sample Table Records using the SQL strSQL.

The Do While… statement ensures that the recordset is not empty, if empty then exit the Loop and end the Program.

If there are records then the first record’s ParentId field is checked for the presense of some value in there or not.

If it is empty then that record is for TreeView control’s Root level Node item.  The Root level Node needs only the unique Node-Key Value, which we already have in the ID Field, and Item Description Field value for Text Argument.

If the ParentID field have some value then the record is a Child-Node (Child of Root level Node or child of some upper-level Child Node) of the TreeView Object. 

The next line creates the Key Argument Value in nodKey String Variable, with the ID field Value,  converted into String and added to the constant prefix X, Node-Key becomes X1.

The rst!Desc field value added to the String Variable strText, simply for clarity and to make it short in the Nodes.Add() method’s Parameter listing, if the field reference is very lengthy then this will keep the Add() method neat and tidy.

The next executable line: tv.Node.Add() calls the Add() method of TreeView.Nodes Object to add the Node to TreeView0 control on the Form frmSample

The Syntax of Add() method is given below for reference:

tv.Nodes.Add([Relative],[Relationship],[Key],[Text],[Image],[SelectedImage]) As Node

All six Parameters of Add() method are optional.  If you call this method without any parameters then an Empty Root level Node will be added and a blank tree-line will appear as an indicator in the TreeView control.

For TreeView Root Level Node requires the Key and Text Argument values.

For Child Nodes both [Relative] and [Relationship] Arguments are required. Omitting any one of them will insert the Node as a Root Node, but will not generate any error.

[Relative] is the NodKey of an existing Node, entered into the related record’s ParentID field.  [Relationship] is a Constant tvwChild with numeric value 4, identifying it as a Child Node of Key Value in ParentID Field.

The other Constant values for Relationship Argument are used for positioning Child Nodes in a specific location.  The Constant Values are as follows :

tvwFirst = 0,  places as first Node, at the level of the relative Node.

tvwLast = 1,  places as last Node, at the level of the relative Node.

tvwNext = 2,  places the Node after a specified Node.

tvwPrevious = 3, placess the Node immediately preceeding the specified Node.

Note: You may experiment by setting  each Value in the Relationship Argument and Run the Code in Debug Mode, after keeping the VBA Window and Form in Normal View side by side. Watch how the Nodes are getting arranged in each cycle of the code execution to understand. 

These will be useful while editing the TreeView Control by Deleting an Item and inserting another item in it’s place or add a new Node at a specific location.

A Node with [Relative] Key must exist in the Nodes Collection before attempting to add a Child-Node to that Node, otherwise the Add() method generates an error.

This process is repeated till all the records are processed in the recordset.

Note: You may review the VBA Code again after the Demo Runs.

H. The First Trial Run.

Open the Form in Normal View.  The Trial Run result will look like the Image given below.

It doesn’t look more than a normal Listbox.  Remember we have not filled-in any value in the ParentID field in our Sample Table.  We have to establish some relationship between the Items in the rows of Record to move and position them in an hierarchical order in the TreeView Control.

I. Understanding the Relationship between Records.

  1. Open the Sample Table and let us examine the Records and how they are related.
  2. Let us leave the Database item alone as a Root Item.

    The Database Object also have some top-level objects: Application, DBEngine, Workspaces Collection and Databases Collection, which we have omitted here.

  3. Then we have the Tables group Item with ID value 2.
  4. Next Table, Fields and Field items are related to the Tables group.  We want Table, Fields and Field items to line up under the parent Item Tables Group Record with ID value 2.
  5. Let us call the record Tables as the Parent Node, Table, Fields and Field records as Child-Nodes.

    J. Updating the ParentID Field.

  6. So we need to update the value 2 (Node-Key of Tables) in ParentID field of Table, Fields and Field  records.
  7. Please update only those records and close the Table.  When it is done the records will look like the Image given below:
  8. Now, open the your frmSample in Form View and check the TreeView Control.  The result will look like the earlier one without any change.  The changes are already happened but it is not visible to you.

    K. The Property Sheet of TreeView Control.

  9. The TreeView Control has it’s own Property Sheet and the settings in there influences it's appearance.  So we will make a change in one of it’s Properties and come back to view the TreeView again.

  10. Turn the frmSample in Design View.
  11. Right-Click on the TreeView Control and high-light TreeCtrl_Object from the Shortcut Menu and select Properties.

    The Property Sheet will look like the Image given below:

  12. Settings on this Property Sheet changes the appearance of the TreeView Display.

    The left-side top Property Style is already set with the maximum features available Option-7 (tvwTreeLinesPlusMinusPictureText).

  13. Change the LineStyle Property Value = 1 (tvwRootLines) and Click Apply button then click OK to close the Property Sheet.

    L. Run After the LineStyle Property Value Change

  14. Save the Form and open it in Normal View.  Now, the Tree Lines are appearing correctly.  The Tables Node have a plus (+) sign at the left side, indicating that this Node have one or more Child Nodes in the next level and they are not in expanded form.
  15. Click on the plus symbol to expand the Node and display the Child Nodes, with the same ParentID.  When you click on the Minus Symbol the Child Nodes are collapsed and hidden, changing the symbold to plus sign again.
  16. The display will look like the following Image, when expanded:

    M. ParentID Updating of Other Records.

    We will update the Forms record ID Value (Node-Key Value) into Form, Controls and Control records’ ParentID fields, so that these records will list under the Forms Node as it’s Child Nodes.

    Similarly update ParentID field of Report and Controls records with Reports ID (Node-Key Value) Value  so that Report and Controls items will position under the Parent Node Reports, as it’s Child Nodes.

  17. Make changes to your Sample table records with the ParentID values as shown below:

    After the above changes the TreeView Display will look like the following Image, when all the Nodes are in expanded form.

    All Child Nodes related to the Root level Nodes: Tables, Forms and Reports are grouped as a list under their Parent Nodes.  But a Child Node may have a Parent Node, Grand-Parent Node or a Great Grand-Parent Node.

    N. Arranging All Object in Logical Hierarchical Order.

    For example let us take the first Root level Node Tables.  Logically Field (with record ID 5) is directly related to the Fields collection (record ID 4), the Fields collection related to Table and Table is part of Tables collection.  Each item in the group (record number 5 to 2) is related to one step up to the next level.

    So let us position these Child Nodes correctly under their own Parent Node and see how it looks.

  18. Open your Sample Table and change the ParentID values of the Tables related Child Records as shown below:

  19. The Field with ID-5 record’s Parent is Fields, record with ID-4, hence we have updated the 5th record’s ParentID field with ID Number 4.
  20. Like wise 4th record’s ParentID field updated with 3 and 3rd Record’s ParentID is updated with record number 2.

    Note: Don't assume that the items arranged in this way must be next to each other.

  21. After changes to the records save the Table and Open the frmSample to view the changes.  Your TreeView display should look like the image given below, with all Nodes in expanded form.

The Child-Node of a Root level Node can be a Parent-Node to it’s own Child or Children.  This way it can go several step down the tree.

Change the other two group of Child Node's ParentID field values to look like the Image given above.


  1. Dictionary Objects Basics
  2. Dictionary Object Basics-2
  3. Sorting Dictionary Object Keys and Items
  4. Display Records from Dictionary
  5. Add Class Objects as Dictionary Items
  6. Update Class Object Dictionary Item

MS-Access Class-Module Tutorial Index

We are planning a Series of Tutorials on Microsoft Windows Tree View Control Programming in Microsoft Access and will publish the Series in the coming weeks.

In the meantime I thought it is appropriate to organize the earlier Tutorial Links, on Class Module and Event Handling Programming Series, of Articles on a separate page, for easy access in  published order.

This is helpful for those who would like to go through the Tutorials on a gradual progressive way of learning. Those tutorials were started from the Basic-level and progressed through the more advanced stage of programming levels. The learning curve should start from the base level and go up to the top to understand the changes at each level. Once you are familiar with the Object or Control, you may continue to learn further by experimenting with them  on your own Programs or Projects.

After all, there are more than one way to solve a problem in Computer Programming, based on the Programer’s own understanding of the Language, Skill and Experience.  

We have developed an Android App ('Microsoft Access Guru' - MSA Guru in short) and is available in Google Play Store to Download and Install it on your Android Phone. This App connects directly to the website:www.msaccesstips.com and you may select the Articles, from it’s Menu/Sitemap, the interested Topic you are looking for.

You may Download and Install the App from Google Play Store so that you can pick the group of required Articles Organized in the Sitemap Page to Read/Learn Access VBA Programming.


  1. MS-Access Class Module and VBA
  2. MS-Access VBA Class Object and Arrays
  3. MS-Access Base Class and Derived Objects
  4. VBA-Base Class and Derived Object-2
  5. Base Class and Derived Object Variants
  6. MS-Access Recordset and Class Module
  7. Access Class Module and Wrapper Classes
  8. Wrapper Class Functionality


  1. MS-Access and Collection Object Basics
  2. MS-Access Class Module and Collection Objects
  3. Table Records in Collection Object


  1. Dictionary Objects Basics
  2. Dictionary Object Basics-2
  3. Sorting Dictionary Object Keys and Items
  4. Display Records from Dictionary
  5. Add Class Objects as Dictionary Items
  6. Update Class Object Dictionary Item


  1. Withevents MS-Access Class Module
  2. Withevents and Defining Your Own Events
  3. Withevents Combo List Textbox Tab
  4. Access Form Control Arrays And Event
  5. Access Form Control Arrays And Event-2
  6. Access Form Control Arrays And Event-3
  7. Withevents in Class Module for Sub-Form
  8. Withevents in Class Module and Data
  9. Withevents and Access Report Event Sink
  10. Withevents and Report Line Hiding
  11. Withevents and Report-line Highlighting
  12. Withevents Texbox and Command Button
  13. Withevents Textbox Command Button
  14. Withevents and All Form Control Types

Download Android App MSA Guru Version of LEARN MS-ACCESS TIPS AND TRICKS from Google Play Store.

Download Link: MSA Guru  Size: 2.3MB

MS-Access Tips and Tricks Android App

Get all Microsoft Access Tips and Tricks Articles at your Finger-Tip. Take all Articles with you in your Android Phone App, wherever you go and learn them at your own pace.

 Install the Android App from Google Play Store Now.


Word Mail-Merge with Ms-Access Table


Form Letters.

Form Letters are prepared from a standard Microsoft Word template merged with addressee related information filled in on each letter.  Appointment letters, call letters for interviews or Employment Contracts etc. are some of the examples and easier to prepare them in Ms-Word Mail-Merge mode, rather than composing them individually for each addressee.

These type of Letters will have some common body text, applicable to all the recipients and will have specific areas where personalized information can be inserted, like Name and Address, interview dates or nearest location where the candidates can attend the interview and so on.

If the interview calls should go to hundreds of prospective candidates then we need to prepare only one letter with standard body text applicable to all recipients.  Other personalized information can be automatically inserted from the attached data table, at appropriate places on each letter, at printing time.  This process in MS-Word is known as Mail-Merging.

We have already made an attempt to mimic this process in Microsoft Access itself with the help of VBA, some time back, and the links of those Posts are given below for your reference:

  1. Ms-Access and Mail-Merge
  2. Ms-Access and Mail-Merge-2
  3. Ms-Access and Mail-Merge-3

The Names, Addresses and other related information of each individual can be kept in Data Table.  The external Table can be prepared in any of the following Applications:

  1. MS-Word Document with Table Grid.
  2. MS-Excel Data Table.
  3. MS-Access Table.

The Table can be linked to the Form Letter so that Ms-Word can pick the required information from the Table and insert them where Table Field-Codes are placed on the body of the letter.

Sample MS-Word Table.

We have prepared a small Table in MS-Word Document, within the Table Grid, as an example  in case if you prefer to prepare one in Microsoft Word itself.  Here is an image of the data table with only 3 entries, similar to the one we have in Northwind.accdb Employees Table.

Click on the Image to Enlarge.

MS-Access Employees2 Table.

But, we will be using a modified Employees Access Table prepared with few new fields, for our Mail Merge Demo Run, from the original Employees Table of Northwind.accdb sample database.  The  image of the Employees2 Access Table is given below:

Click on the Image to Enlarge.

Create the Employees2 Table from the Employees Table of Northwind.accdb, with the selected fields in your Database.  Create three more fields and fill it up with sample data as shown in the above image.

Sample Letter Specimen.

A Specimen image of the Letter, without the individual Employee details is given below:

Click the Image to Enlarge it.

Create a Letter in Microsoft Word similar to the specimen given above and save it with the name: Employees.

Sample Merge-Printed Letter.

When we merge print the personal information on the Document, from Access Table, it will look like the sample image given below:

Click the Image to Enlarge.

Inserting the Merge Fields on Document.

Let us prepare a Mail-Merge Document in MS-Word, with the above Employees2 Table as Source Data,  matching the above merged letter model. 

We assume that the above Employees of our Organization is awarded with an Annual increment, in appreciation of their commendable contribution to the Company’s overall growth and encourage them to do better by taking up future challenges of the company.

  1. Open the Employees Word-Document, as per specimen given above, created and saved earlier.  If you have not yet created one so far, then let us do it now.
  2. Click on Start Mail-Merge from Mailings Menu and select Letter.
  3. Click on Select Recepients and select Use Existing List.
  4. Browse and find the Database where you have the above Employees2 Table is and Click Open.
  5. The list of Tables are displayed, select Employees2 Table and Click OK to select it.  Now, the Employees2 Table is attached to the Document.
  6. Next, if you click on the Edit Recepient List it will display all the records in the Employees2 Table with check-marks indicating that all the employee records are selected for Merge-Printing the Letters.  If any employee is to be excempted from the letter then remove the check-mark on that item.

    First we will insert the Address Block and Greeting Line information on the Letter, from the Merge-Fields selected from the attached Table.  Even though we can insert these to sections in two simple steps, we will do it the hard way to make things to our liking and less complicated, if the automatic method is not properly understood, for the first time user.  You may try them later by selecting Address Block and Greeting Line buttons and their optional settings to modify the output on the document.

  7. Click some where below the Reference information (Ref:ABC/HRD/2020/1234-) and above the word Dear on the Letter.
  8. Click on Insert Merge Field option in Mailings Menu and click on First Name Field.  Open the same list again and select Last Name.
  9. Click in the middle of both field-codes and tap the space bar to insert a space between First-Name and Last-Name segments of the Employee Name and position the insertion point on the next line.
  10. Select Address from the Merge-Field list for the second line.
  11. Select City for the third address-line.
  12. Insert State/Province and Country/Region on the next line, with a space in between.
  13. Position the Insertion point after the word Dear with a space, insert First Name and Last Name  fields with a space in between.

    After inserting the merge fields it will look like one of the images given below, based on the Field-Code display option setting ALT+F9.


    The second image is the expanded form of Merge Field Codes. You can toggle between these two states by pressing ALT+F9 Keys.  see that the Preview Result button is in de-selected state.  If the Preview Result button is on then the actual data will be displayed.

  14. Position the insertion point on the Designation line and insert the Job Title Merge-field.
  15. On next three lines insert Pay, Grade and Wef (stands for with-effect-from) Fields.

    When completed it will look like the following image:

    We need two more pieces of data for Reference Sequence Number and Date of the Letter.

  16. Position the insertion point at the end of the existing reference number, immediately after the dash character (Ref: ABC/HRD/2020/1234-).
  17. Select Page Number from Insert Menu and select Current Position from the displayed list.
  18. Position the insertion point after the word Date:.
  19. Click on Date & Time option, under Insert Menu and select one of the Date-format options displayed.
  20. Press Ctrl+S Keys to save the Word Document with the changes.

Merge-Printing the Letter.

Now, we are ready to Merge-Print the Document for each selected employee on the Employees2 Table.

  1. Click on Preview Result button, with the Zoom Glass image, under Mailings Menu. 
  2. If it is still on Field-Code display, then Press ALT+F9 Keys to Fill-in the first Employees data, wherever we have inserted the Merge-Fields on the Document.
  3. Now, you are viewing the sample Document you will get when Merge-Print the Document on the Printer,  one Document for each employee.
  4. Now, Click on Finish & Merge button and select Edit Individual Document. . .  and select All.

All the Documents are merged with Employees information and you are allowed to edit the Pages, if needed.  Can insert spaces between lines or inserted information can be formatted in Bold letters.  If Letter head is not appearing properly then insert a line and so on.

Once you are finished editing, select Print from Office Button, then Preview or Print the Document on Printer.

If you have selected Send EMail Message at Step-4 above then you can send the Document as Email Message.

  1. MS-Access and E-Mail
  2. Invoke Word-Mail Merge from Access2007
  3. Automated Email Alerts


Auto-Numbers in Query Column Version-2


During January 2010 I have published a Function: QrySeq() - Auto-Numbering in Query Column  on this website and well-received by the readers all through these years.  While going through it again I thought it can be written with less Code and improve it’s performance by using a better approach, other than Variant Array.

When the function QrySeq() is called from a query record the program searches through the Array of Unique Keys and look for the matching key, passed from the record as parameter, finds it and returns the sequence number from Array-Element to the calling record.

If the Query have large Volume of records this process may take more time, because every time the program looks for the Key Value from the beginning of the Array.

The New Version is with the Name: QryAutoNum()

Using Collection Object  instead of Array.

You can find a detailed discussion on Collection Object in Ms-Access and Collection Object Basics Page.

Here we will have a brief introduction to know what it is and how it is used in VBA.  The Collection Object is a versatile Object that can hold, in general terms, any Values, Numeric or String Values, Class Module Objects or collection of other Objects.  The Collection Object is instantiated in VBA programs in the following manner:

'declare a Collection Object. Dim ABC as Collection 'create an instance of Collection Object in Memory Set ABC = New Collection 'We can Add built-in data types: Numeric, Strings etc ‘or Objects like Class Module Objects, ‘or other Collection Object as Items to the Collection Object.

'Use the Add method to add a Collection Item to the Object. ABC.Add 25 ABC.Add "ms-accesstips" 'When Collection Object Items added this way, ‘it can be retrieved only in the added order. For j = 1 to ABC.Count 'gets the count of Items Debug.Print ABC(J)’ retrieve in Item index Order. Next 'When ADDed an Item with a String Key 'we can use the Key value to retrieve the Items Randomly. 'But, usage of Key is optional. ABC.Add 25, "1" ABC.Add "ms-Accesstips", "2" x = "2" Debug.Print ABC(x) Result: ms-accesstips

So, we will use Collection Object to add the Query Auto-Numbers with the Unique Key Values as Collection Object Key.  With this approach we can retrieve the Auto-Numbers directly, rather than struggling with Arrays and it’s complicated storing/retrieving steps.

The QryAutoNum() Function Code.

Option Compare Database
Option Explicit

Dim C As Collection

Public Function QryAutoNum(ByVal KeyValue As Variant, ByVal KeyfldName As String, ByVal QryName As String) As Long
'Purpose: Create Sequence Numbers in Query Column Ver.-2
'Author : a.p.r. pillai
'Date : Dec. 2019
'All Rights Reserved by www.msaccesstips.com
'Parameter values
'1 : Column Value - must be UNIQUE Numeric/String Type Values from Query Column
'2 : Column Name  - the Field Name in Quotes from where Unique Values taken
'3 : Query Name   - Name of the Query this Function is Called from
'Limitations - Function must be called with Unique Field Values
'            - as First Parameter
'            - Need to Save the Query, if changes made, before opening
'            - in normal View.
Static K As Long, Y As Long, fld As String
On Error GoTo QryAutoNum_Err

Y = DCount("*", QryName) ' get count of records for control purpose

'If KeyfldName Param is different from saved name in variable: fld
'or Value in K more than count of records in Variable: Y
'then it assumes that the QryAutoNum() is called from a different Query
'or a repeat run of the same Query. In either case the Control Variable
'and Collection Object needs re-initializing.
If KeyfldName <> fld Or K > Y Then
'initialize Control Variable
'and Collection Object
    K = 0
    Set C = Nothing
    'save incoming KeyfldName
    fld = KeyfldName
End If

'if KeyValue parameter is Numeric Type then convert
'it to string type, Collection Object needs it's Key as String Type.
If IsNumeric(KeyValue) Then
    KeyValue = CStr(KeyValue)
End If

K = K + 1
If K = 1 Then
Dim j As Long, db As Database, rst As Recordset
Dim varKey As Variant

Set C = New Collection

Set db = CurrentDb
Set rst = db.OpenRecordset(QryName, dbOpenDynaset)

'Add recordlevel AutoNumber with Unique KeyValue
'to Collection Object, in AutoNumber, KeyValue Pair
While Not rst.BOF And Not rst.EOF
    j = j + 1 ' increment Auto Number
    'Get key value from record
    varKey = rst.Fields(KeyfldName).Value
    'if numeric key convert it to string
    If IsNumeric(varKey) Then
      varKey = CStr(varKey)
    End If
    'Add AutoNumber, KeyValue pair to Collection Object
    C.Add j, varKey
    Set rst = Nothing
    Set db = Nothing

'Retrieve AutoNumber from Collection Object
'using the KeyValue.  Works like Primary Key of Table
    QryAutoNum = C(KeyValue)
    QryAutoNum = C(KeyValue)
End If

If K = Y Then 'All record level AutoNumbers are Returned
    K = K + 1 ' increment control variable
End If

Exit Function

MsgBox Err & " : " & Err.Description, , "QryAutoNum"
Resume QryAutoNum_Exit

End Function

Sample Source Query SQL.

With the NorthWind Products Table.

SELECT Products.ID, 
Mid([Product Name],18) AS PName, 
Sum(Products.[Standard Cost]) AS StandardCost, 
"Product_AutoNumQ") AS QrySeq
FROM Products
GROUP BY Products.ID, Products.Category, Mid([Product Name],18)
ORDER BY Products.Category, Mid([Product Name],18);

Review of VBA Code Line-By-Line.

On the Global Area of the Module we have declared a Collection Object with Object Variable C.

The QryAutoNum() Function declaration is the same as our earlier QrySeq() with three Parameters.

  1. Unique Key Value either Numeric or String as first Parameter.
  2. The Key Value Field’s Name in String Format.
  3. The Query Name in String Format.

The returned Auto-Number is in Long Integer format.

Three Static Variables,  K and Y declared as Long Integers and fld declared as String Variable.

All the three Variables controls the Code execution paths and determines when to initialize Collection Object and control variables.

The DCount() Function takes a count of records in the Query in Variable Y.

If the KeyFldName is different from the saved name in Variable fld then it assumes that the function call is from a new Query Record.  If the field name is same but the value in variable K is greater than Y  then the earlier Query is calling the function QryAutoNum() for a repeat of the earlier run.   In either case the control Variable K is reset to zero, the Collection Object with existing Items are cleared from memory.  The new Key field name received in KeyFldName variable is saved in fld variable for later validation check.

Next, if the KeyValue parameter value is numeric then it is converted to String format in the statement: KeyValue = Cstr(KeyValue). The Collection Object Item Key must be in string format.

Next, the variable K is incremented by one.  When the value in K=1 it assumes that this is the first call of this function, from the first record of a Query.  When this is the case the main process of this function starts.

The local temporary Variables are declared here and their values are not preserved between calls of this function from different records of the query.

The Collection Object, declared on Standard Module’s  Global area is instantiated in memory, with the statement Set C = New Collection.

The Query recordset is opened to read records one-by-one. The local variable J to create Auto-Numbers and Add it to the Collection Object for each record.  The Unique Key Value, read from the recordset,  into variable varKey, is added to the Collection Object as it’s Key Value.

If the varKey Value is Numeric Type then it is converted to String format.

The Auto-Number Value in Variable J and the string value in variable varKey are added to the Collection Object in the following statement, as it’s Item, Key pair:

C.Add J, varKey

This process is repeated for all the records in the Query.  The Auto-Numbers are generated for all the records and added them into the Collection Object, one after the other.  All this work is done during first call of the function from the first record of the query.

Did you notice that we are reading the Unique Key value of each record directly from the recordset within the While . . . Wend Loop to add them to the Collection Object.  After adding Auto-Numbers for all records the recordset and Database Objects are closed.

Remember, we are still at the first call of the function from the first record of the query and the first parameter variable KeyValue still holds the first record Key Value.

The next statement QryAutoNum = C(KeyValue) retrieves Collection Object’s first Item Auto-Number Value 1, using the Unique Key Value in parameter variable KeyValue, and returns it to the function calling record. This will happen only once because the variable K will be greater than one on subsequent calls of this function.

So, the Function calls from second record onwards will take the ELSE path of the If K=1 Then statement and retrieves the Auto-Numbers from Collection Object, using the KeyValue passed as Parameter, and returns it to respective records in the Query.

It works very fast because we can directly pick the item value, using the Collection Object Key, rather than searching for the Key, through the Array from the beginning to find the one we want.

When all the record Auto-Number values are returned the value in control variable K = Y. We have already taken the count of records of the Query, in Variable Y in the beginning of the program. At this point we increment the value in variable K by 1, to make it more than the value in Variable Y.  Since, K and Y are Static Variables their values are not lost after the last record call is over and remains in memory.  If the same Query is run a second time the test on these variable values can determine whether we need to reset the variable values and clear the earlier Collection Object from memory for a fresh start of the process all over again.

If the QryAutoNum() function is called from the same Query again the Static Variables and Collection Object is cleared from memory, preparing for a fresh run of the Function for the same Query or for a different Query.

The sample Report Image using the above Query as Source is given below for reference

You can use the Query as Source for Report or Form. 

A sample demo database, with all the Objects and VBA Code, is attached for Downloading and for trying out the Code.

  1. Auto-Numbering in Query Column
  2. Product Group Sequence with Auto-Numbers.
  3. Preparing Rank List.
  4. Auto-Number with Date and Sequence Number.
  5. Auto-Number with Date and Sequence Number-2.

MS-Access Tips on your Finger-Tip

  • Download Android App 'MSA Guru' Version of LEARN MS-ACCESS TIPS AND TRICKS from Google Play Store.

Want to Post Free Ads on the Web


Subscribe in a reader
Your email address:

Delivered by FeedBurner


Popular Posts

Blog Archive

Powered by Blogger.

Follow by Email


Forms Functions How Tos MS-Access Security Reports msaccess forms Animations msaccess animation Utilities msaccess controls Access and Internet MS-Access Scurity MS-Access and Internet Class Module External Links Queries Array msaccess reports Accesstips WithEvents msaccess tips Downloads Menus and Toolbars Objects Collection Object MsaccessLinks Process Controls Art Work Property msaccess How Tos Dictionary Object Graph Charts Query VBA msaccessQuery Calculation Combo Boxes Event List Boxes Command Buttons Controls Data Emails and Alerts Form Custom Functions Custom Wizards DOS Commands Data Type Object Reference ms-access functions msaccess functions msaccess graphs msaccess reporttricks Command Button Key Report msaccess menus msaccessprocess security advanced Access Security Add Auto-Number Field Type Form Instances Item Macros Menus RaiseEvent Recordset Top Values Variables Wrapper Classes msaccess email progressmeter Access2007 Copy Excel Export Expression Fields Join Methods Microsoft Numbering System Records Security Split SubForm Table Tables Time Difference TreeView Control Utility Workgroup database function msaccess wizards tutorial Access Emails and Alerts Access Fields Access How Tos Access Mail Merge Access2003 Accounting Year Action Animation Attachment Binary Numbers Bookmarks Budgeting ChDir Color Palette Common Controls Conditional Formatting Data Filtering Database Records Defining Pages Diagram Disk Dynamic Lookup Error Handler External Filter Formatting Groups Hexadecimal Numbers ImageList Control Import Labels List ListView Control Logo Macro Mail Merge Main Form Memo Monitoring Nodes Octal Numbers Operating System Paste Primary-Key Product Rank Reading Remove Rich Text Sequence SetFocus Summary Tab-Page Union Query User Users Water-Mark Word automatically commands hyperlinks iSeries Date iif ms-access msaccess msaccess alerts pdf files reference restore switch text toolbar updating upload vba code