Command Bars in Microsoft Access 97: Tips and Tricks

Robert Flake
Microsoft Corporation

December 18, 1996

Introduction

The following articles contain useful information about using the new command bars feature in Microsoft® Access 97. In previous versions of Microsoft Access, the only way to create and modify menu bars, toolbars, and shortcut menus was to use menu bar macros or the Customize Toolbar dialog box. In some cases, you had to use Windows® API calls to in order to make certain modifications to these elements of the user interface.

In Microsoft Access 97, menu bars, drop-down menus, toolbars, and shortcut menus are all types of command bars. You can add and modify these command bars by using the Customize dialog box and the property sheets available by pointing to Toolbars on the View menu and then clicking Customize. You can also use the new command bar object model to create and modify command bars in Visual Basic®.

Note   In order to program with command bars in Microsoft Access 97, you must first set a reference to the Microsoft Office object library. Click References on the Tools menu while in module Design view, and select the check box next to Microsoft Office 8.0 Object Library.

Once you've set a reference to the Microsoft Office object library, you can view the Microsoft Office objects, properties, and methods in the Object Browser. The objects that you can use to program command bars include the CommandBar, CommandBarControl, CommandBarButton, CommandBarComboBox, and CommandBarPopup objects, and the CommandBars and CommandBarControls collections.

These new features are described in the Microsoft Office 97 and Microsoft Access 97 Help topics. The following sections give useful tips and solutions to common command bar problems that may not be covered explicitly in the Help topics, or they point out especially useful techniques for working with command bars.

Creating Custom Shortcut Menus in Visual Basic

The new command bars object model in Microsoft Office 97 lets you programmatically create and modify the various kinds of command bars: menu bars, toolbars, and pop-up menus. Pop-up menus appear in three ways: as menus that drop down from menu bars, as submenus that cascade off menu commands, and as shortcut menus. Shortcut menus (also called "right-click menus") are menus that appear on the screen when you right-click a particular area on the screen; for example, a blank area on a form or report, or a form control.

In Microsoft Access 97, you can create a custom shortcut menu by using the Customize dialog box. For more information, see the section "Creating Custom Shortcut Menus Using the Customize Dialog Box." You can also create custom shortcut menus by using Visual Basic. To do this, you use the Position argument of the Add method of the CommandBars collection. To create a custom shortcut menu named OrdersPopup, you can use the following syntax:

Dim mybar as CommandBar
Set mybar = CommandBars.Add(Name:="OrdersPopup", _
   Position:=msobarPopup)

Once you create a custom shortcut menu, you can modify its properties by using Visual Basic. For an example of creating and modifying a custom shortcut menu, see "Example: Creating a Custom Shortcut Menu."

Note   You can use the Add method to create a custom shortcut menu, but you can't change an existing command bar of another type to a shortcut menu by using Visual Basic. The Position property for command bars has an msoBarPopup setting. However, this setting is read-only; it is used to determine whether an existing command bar is a pop-up menu. You can't set this property to change the type of a command bar to msoBarPopup.

You can change the type of a command bar by using the Toolbar Properties dialog box in Microsoft Access (see the section "Creating Custom Shortcut Menus Using the Customize Dialog Box"). However, if you want to change an existing command bar to a shortcut menu in Visual Basic, you must use the Delete method to delete the existing command bar and the Add method to create the new shortcut menu. You can also copy an existing pop-up command bar and then modify it to include the controls you want. For information about copying a command bar, see the section "Copying Command Bars."

Example: Creating a Custom Shortcut Menu

This example creates a custom shortcut menu named OrdersPopup, and adds commands to this shortcut menu. The example also sets the ShortcutMenuBar property of the Orders form to the name of this custom shortcut menu. When you right-click in a blank area of the Orders form, Microsoft Access displays the shortcut menu. Note that the procedure uses the GetID function to determine the ID numbers for several built-in Microsoft Access commands. For information on this function, see "Finding the ID Number for a Built-in Command."

Sub CreateOrdersShortcut()
    Dim cmdBar as CommandBar
    Dim ctlNew as CommandBarButton
    Const conShortcutAlreadyCreated = 5
    On Error GoTo CreateOrdersShortcut_Err
    Set cmdBar = CommandBars.Add(Name:="OrdersPopUp", _
       Position:=msoBarPopup)
    ' Add the built-in controls Filter By Form, Apply Filter/Sort
    ' and Remove Filter/Sort. The GetID function finds the ID value
    ' for each of these built-in controls.
    With cmdbar
        .Controls.Add msoControlButton, _
           GetID("Filter Context Menu", "Filter By Form")
        .Controls.Add msoControlButton, _
           GetID("Records", "Apply Filter/Sort")
        .Controls.Add msoControlButton, _
           GetID("Records", "Remove Filter/Sort")
    End With
    ' Add a command button control that prints the current record.
    Set ctlnew = cmdbar.Controls.Add(msoControlButton)
    With ctlnew
        .BeginGroup = True
        .Caption = "Print Current Record"
         ' The = and () aren't required for the OnAction property
         ' setting, but they can be used to distinguish functions
         ' from macros.
        .OnAction = "=PrintRecord()"
        .Style = msoButtonCaption
    End With
    ' Attach the new shortcut menu to the Orders form.
    DoCmd.OpenForm "Orders"
    Forms!Orders.ShortcutMenuBar = "OrdersPopup"
CreateOrdersShortcut_Bye:
    Exit Sub
CreateOrdersShortcut_Err:
    ' You can't create a command bar if a command bar of the same
    ' name already exists. This If clause checks for the error
    ' message that occurs if a command bar named "OrdersPopup"
    ' already exists and deletes this command bar. The procedure
    ' then resumes, and adds the new shortcut menu.
    If Err = conShortcutAlreadyCreated Then
        CommandBars("OrdersPopup").Delete
        Resume
    Else
        MsgBox Err.Description, vbOKOnly, "Error = " & Err.Number
        Resume CreateOrdersShortcut_Bye
    End If
End Sub
Function PrintRecord ()
    ' This function runs from the command button control "Print
    ' Current Record" on the shortcut menu. It selects the current
    ' record in the Orders form and prints this record.
    RunCommand acCmdSelectRecord
    DoCmd.PrintOut acSelection
End Function

Finding the ID Number for a Built-in Command

When you add a built-in control to a custom command bar in Visual Basic, you use the Id argument of the Add method of the CommandBarControls collection. For example, you may want to create a custom menu that has several built-in controls and several custom controls. You can determine the ID value to use with the Id argument by using the Id property for the control. The following function returns the ID for a built-in control. You pass the name of the control in the strControlName argument and the name of the command bar the control appears on in the strBarName argument. For example, you could determine the ID value for the New Database… command that appears on the File menu on the main Microsoft Access menu bar by calling the GetID function using the following arguments:

Dim lngControlId as Long
lngcontrolID = GetID("File", "New Database...")

In this example, the name of the command bar is "File". This particular command bar is a pop-up menu that appears when you click File on the main menu bar. You must pass the exact command bar name in the strBarName argument. Note also that you must pass the control name exactly as it appears on the command bar. In this example, this means that the New Database… command name must be passed with the trailing three periods.

You can use the GetID function with the Add method of the CommandBarControls collection to add the specified control to a command bar. For an example, see the section "Example: Creating a Custom Shortcut Menu."

Function GetID(strBarName As String, strControlName As String) As Long
    Dim cbr As CommandBar, cbrctl As CommandBarControl
    On Error GoTo GetID_Err
    Set cbr = CommandBars(strBarName)
    Set cbrctl = cbr.Controls(strControlName)
    ' The ID value of the control is the setting of its
    ' Id property.
    GetID = cbrctl.Id
GetID_Bye:
    Exit Function
GetID_Err:
    MsgBox Err.Description, vbOKOnly, "Error = " & Err.Number
    Resume GetId_Bye
End Function

For example, if you enter the following in the Debug window:

? GetID("Insert", "Module")

The function returns 621, the ID number for the built-in Module command on the Insert menu.

To add this command to a custom menu, you could use the following syntax:

Set ctlnew = Controls.Add(msoControlButton, 621)

Or you could use the GetID function directly in the code that adds the command:

Set ctlnew = Controls.Add(msoControlButton, _
   GetID("Insert", "Module"))

Note   When you use this function, you must know the complete and correct name for the command bar that contains the control whose ID value you want to find. This is the name you use for the strBarName argument passed to the function. The command bar name is not always the name you see in the user interface. For example, the name of the pop-up menu that appears when you click a command that has subcommands is not necessarily the name of the command. For example, when you click the Filter command on the Records menu, you see a submenu containing commands such as Filter By Form and Filter By Selection. The name of this pop-up submenu is Filter Context Menu, not Filter.

To find the name of a command bar, use the Name property. For example, to find the name of the pop-up submenu mentioned in the previous paragraph, use the following syntax:

CommandBars("Records").Controls("Filter").CommandBar.Name

Microsoft Access supplies a number of built-in shortcut menus, each of which has a name. Although almost all built-in controls on these shortcut menus are also available on other menus, you may want to find the ID value for a built-in control on one of the shortcut menus. To see a function that when run lists all of the command bars in your application (including the shortcut menus) and their names, see "Example: Listing the Names of Command Bars in Your Application."

Example: Listing the Names of Command Bars in Your Application

This example lists the names of all the command bars in the CommandBars collection. Command bars can be one of three types, as defined by the Type property: toolbars (represented by the intrinsic constant msoBarTypeNormal), menu bars (msoBarTypeMenuBar), or pop-up menus, which include submenus and shortcut menus (msoBarTypePopup).

Sub ListCommandBars()
    Dim cbr As CommandBar
    For Each cbr In CommandBars
        listbar 1, cbr
    Next cbr
End Sub
Sub listbar(level As Integer, thisbar As CommandBar)
    Dim cbrctl As CommandBarControl
    Dim indent As Integer
    ' Indent the command bar depending on its level in
    ' the menu structure.
    For indent = 1 To level
        Debug.Print "   ";
    Next indent
    Select Case thisbar.Type
        Case msoBarTypeMenuBar
            Debug.Print "Menu Bar: " & thisbar.Name
        Case msoBarTypeNormal
            Debug.Print "Toolbar: " & thisbar.Name
        Case msoBarTypePopup
            Debug.Print "Popup: " & thisbar.Name
    End Select
    For Each cbrctl In thisbar.Controls
    ' If the control doesn't have a command bar associated
    ' with it, then don't print it.
        If cbrctl.Type <> 1 And cbrctl.Type <> 2 _
              And cbrctl.Type <> 4 And cbrctl.Type <> 16 _
              And cbrctl.Type <> 18 Then
            listbar level + 1, cbrctl.CommandBar
        End If
    Next cbrctl
End Sub

Creating Custom Shortcut Menus Using the Customize Dialog Box

With the new command bars feature in Microsoft Office 97, you can create and modify the various kinds of command bars: menu bars, toolbars, and pop-up menus. Pop-up menus appear in three ways: as menus that drop down from menu bars, as submenus that cascade off menu commands, and as shortcut menus. Shortcut menus (also called "right-click menus") are menus that appear when you right-click a particular area on the screen; for example, a blank area on a form or report, or a form control.

In Microsoft Access 97, you can create a custom shortcut menu by using the Customize dialog box, available by pointing to Toolbars on the View menu and then clicking Customize. To create a custom shortcut menu, click the New button in the Customize dialog box and name your new shortcut menu. Set any toolbar properties you want, making sure to set the Type property to Popup. You'll see a message telling you that the menu will disappear from view. You can see the menu by selecting the Shortcut Menus check box in the Customize dialog box, and then clicking Custom on the menu bar that appears.

You can add controls to this custom menu just as you can for toolbars and menu bars, and set the control properties using the Control Properties dialog box. To attach the custom shortcut menu to a particular form, form control, or report, set the form, form control, or report's ShortcutMenuBar property to the name of the custom shortcut menu.

You can also add custom shortcut menus to your application by using Visual Basic. For more information, see the section "Creating Custom Shortcut Menus in Visual Basic." Note, however, that you can only change the type of an existing command bar to Popup by using the Toolbar Properties dialog box. You can't change a command bar of another type to a shortcut menu by using Visual Basic.

Adding Built-in Menus to Your Custom Command Bars

With the new command bars feature in Microsoft Office 97, you can create and modify the various kinds of command bars: menu bars, toolbars, and pop-up menus. In Microsoft Access 97, you use the Customize dialog box, available by pointing to Toolbars on the View menu and then clicking Customize, to create command bars and set their properties.

When you create a new command bar, you use the Add button on the Customize dialog box to create and name the new command bar. You can then add built-in controls to the command bar by using the Commands tab in the Customize dialog box. There's a selection in the Categories list, Built-in Menus, that you can use to add any of the various built-in menus and their commands to your command bar.

Caution   If you modify a built-in menu that you've added to your custom command bar, the built-in menu will be modified everywhere it appears in the product. For example, if you rename a command in your command bar, this command will also be renamed in any of the built-in menu bars or toolbars on which it normally appears.

To avoid this problem, don't use the Built-in Menus selection. Instead, use the New Menu selection in the Categories list on the Commands tab to add a new blank menu to your command bar, and then drag the built-in commands you want to this menu. You can name the menu the same name as the corresponding built-in menu. For example, you could add a new menu, rename it "File", and then add all the built-in commands normally found on the File menu to your command bar.

Using the Position Property with Command Bars

The Position property for command bars is primarily used to set the position of a command bar after it's created or when you want to move an existing command bar. However, there's some additional functionality of this property that's not immediately apparent.

The Position property applies to all command bars. The syntax for setting this property is:

CommandBars("commandbarname").Position = msoBarPosition constant

You can set this property to one of seven intrinsic constants (see Table 1).

Table 1. Intrinsic Constants of the Position Property

Constant Description
msoBarLeft, msoBarTop, msoBarRight, msoBarBottom Indicates where the command bar appears on the screen.
msoBarFloating Indicates that the command bar isn't docked.
msoBarPopup Read-only. Indicates that the command bar is a shortcut menu.
msoBarMenuBar (This constant is incorrectly listed as msoBarMenu in the Help topic for the Position property.) Indicates that the command bar is a Macintosh® system menu bar (and replaces the built-in system menu bar). This constant does NOT indicate that this command bar is a Microsoft Access menu bar, and indeed this command bar can't be used with Microsoft Access.

Note that these constants are also used with the Position argument of the Add method of the CommandBars collection, which you use to add command bars and set their type and position. An important difference between the two, however, is that the msoBarPopup setting is read-only for the Position property. You can't change an existing command bar to a shortcut menu by using the Position property after the command bar has been created. You could delete the command bar and use the Add method to add it as a shortcut menu (as long as you didn't need the existing command bar anymore). You could also copy an existing shortcut menu, and modify it to contain the controls you want. For more information, see the section "Creating Custom Shortcut Menus in Visual Basic."

Example: Using the Position Property

This example repositions the specified command bar in the specified screen location, at the top, bottom, right, or left of the screen, or makes it undocked. You pass the name of the command bar in the strBarName argument and the desired location (one of the intrinsic constants for the Position property setting) in the intLocation argument.

Function MoveCommandBar(strBarName As String, intLocation As Integer)
    Dim cbr As CommandBar
    Set cbr = CommandBars(strBarName)
    With cbr
        If .Visible = True Then
            Select Case intLocation
                Case msoBarTop
                    .Position = msoBarTop
                Case msoBarBottom
                    .Position = msoBarBottom
                Case msoBarRight
                    .Position = msoBarRight
                Case msoBarLeft
                    .Position = msoBarLeft
                Case msoBarFloating
                    .Position = msoBarFloating
                Case msoBarPopup
                    MsgBox "You can't change an existing" & _
                       " command bar to a shortcut menu."
                Case Else
                    MsgBox "Invalid Position Argument"
            End Select
        End If
    End With
End Function

Copying Command Bars

Often, you'll want to create a command bar that contains almost all of the controls from an existing command bar. For example, you may have just created a custom toolbar that you use for one of your forms, and you want to create other very similar toolbars for other forms that contain the same controls with just a few modifications. The following function will copy a specified command bar and its controls to a new command bar. You can then make any modifications you want to this command bar. Note that there is no way to copy a command bar in its entirety by using the user interface; you must use Visual Basic.

Function CopyCommandBar(strOrigCBName As String, strNewCBName As String) As Boolean
    ' This procedure copies the command bar named in the
    ' strOrigCBName variable to the new command bar named
    ' in the strNewCBName variable.
    Dim cbrOriginal As CommandBar, intOrigCount As Integer
    Dim cbrCopy As CommandBar, cbrCtl As CommandBarControl
    On Error GoTo CBCopy_Err
    Set cbrOriginal = CommandBars(strOrigCBName)
    intOrigCount = cbrOriginal.Controls.Count
    Set cbrCopy = CommandBars.Add(strNewCBName)
    ' Make sure the new command bar is visible.
    cbrCopy.Visible = True
    For Each cbrCtl In cbrOriginal.Controls
        cbrCtl.Copy cbrCopy
    Next cbrCtl
Exit Function
CBCopy_Err:
    MsgBox Err.Description
    Exit Function
End Function

Adding a Combo Box Control to a Command Bar

One of the useful new features of command bars is the ability to add different types of controls to your command bars. The following example shows you how to add a combo box control to the main menu bar and fill the combo box list with values from a table. This example also shows how to delete the combo box control when you no longer need it. For example, you may want to display this combo box control when a certain form (for example, the Orders form) is open, and remove it when the form is closed or no longer has the focus. To do this, you could run the AddCombo procedure when the form's Open event occurs, and run the RemoveCombo procedure when the form's Unload event occurs.

This example can be used as is with any of the sample applications supplied with Microsoft Access. (Note, however, that the main menu bar for the Northwind Traders database is called NorthwindCustomMenuBar, not Menu Bar.) To use it with your application, replace the table and field names with those from your database.

Sub AddCombo()
    ' This procedure adds a combo box control to the menu bar
    ' and adds CompanyName information from the Customers table.
    Dim mybar As CommandBar, mycontrol As CommandBarComboBox
    Dim dbs As Database, rst As Recordset, intI As Integer
    Set mybar = CommandBars("Menu Bar")
    On Error Resume Next
    ' See if the control already exists
    Set mycontrol = mybar.Controls("Customers")
    If Err = 0 Then Exit Sub   ' Control exists so exit procedure.
    ' Add control to menu bar.
    Set mycontrol = _
       mybar.Controls.Add(Type:=msoControlComboBox, Id:=1)
    Set dbs = CurrentDb
    Set rst = dbs.OpenRecordset("Customers", dbOpenDynaset)
    rst.MoveFirst
    intI = 1
    ' Fill combo box with names from the Customers table.
    While Not rst.EOF
        With mycontrol
            .AddItem Text:=rst!CompanyName, Index:=intI
        End With
        intI = intI + 1
        rst.MoveNext
    Wend
    ' Set combo box properties
    With mycontrol
        .Caption = "Customers"
        .Width = 200
        .DropDownLines = 10
        .DropDownWidth = 300
        ' This is the function called when an item is
        ' selected from the list.
        .OnAction = "=ShowCustomerInfo()"
    End With
End Sub
Function ShowCustomerInfo()
    ' This procedure runs when an item is selected from the combo
    ' box created in the AddCombo procedure. It displays a message
    ' box showing the name, title, and phone number of the contact
    ' for the company you select in the combo box list.
    Dim mybar As CommandBar, mycontrol As CommandBarComboBox
    Dim dbs As Database, rst As Recordset
    Dim strCriteria As String
    On Error Resume Next
    Set mybar = CommandBars("Menu Bar")
    Set mycontrol = mybar.Controls("Customers")
    Set dbs = CurrentDb
    ' Create a recordset containing a single record that matches
    ' the company name selected from the combo box.
    ' This If clause handles the case where the company name
    ' contains an embedded apostrophe.
    If InStr(mycontrol.Text, "'") > 0 Then
        strCriteria = "Select ContactName, ContactTitle," & _
           " Phone From Customers Where CompanyName" & _
           " = " & """" & mycontrol.Text & """"
    Else
        strCriteria = "Select ContactName, ContactTitle," & _
           " Phone From Customers Where CompanyName" & _
           " = '" & mycontrol.Text & "'"
    End If
    Set rst = dbs.OpenRecordset(strCriteria)
    MsgBox "Name = " & rst!ContactName & vbCrLf & _
       "Title = " & rst!ContactTitle & vbCrLf & _
       "Phone = " & rst!Phone
End Function
Sub RemoveCombo()
    ' This procedure removes the combo box control created
    ' in the AddCombo procedure from the menu bar.
    On Error Resume Next
    Dim mybar As CommandBar, mycontrol As CommandBarComboBox
    Set mybar = CommandBars("Menu Bar")
    Set mycontrol = mybar.Controls("Customers")
    mycontrol.Delete
End Sub