RegisterLog In/Log OutView Cart
O'Reilly Ron's VB Forum Ron's VB Forum
BooksSafari BookshelfConferencesO'Reilly NetworkO'Reilly GearLearning Lab
 


Traveling to
a tech show?

Hotel Search
Hotel Discounts
Discount Hotels
Chicago Hotels
Canada Hotels
California Hotels
Hotels




Date: Jan 5 2000
From: Lisa
To: ron@oreilly.com
Subject: Creating a combo drop down box in MS Word 2000

Hi Ron,

I know nothing about VB and I've been trying to create a drop down combo box in a MS Word 2000 document. I did a view/toolbars/control box and inserted it in the document. I then went in to the properties of the drop down box and inserted the value fields, i.e., blue; red; green. When I went back to view the drop down box (outside) of the design view, my values weren't in a list format, rather they were showing up side by side. I know I didn't do something right.... Is there some code that I need to put in somewhere??

Thanks a lot,

Lisa


Hi Lisa,

As primarily a Visual Basic (that is, not an Office VBA) programmer, I've always considered the Microsoft Forms controls (the library of controls included with all of the Office applications) to be interesting and very quaint, largely because the controls lack many of the features and amenities that are available with Visual Basic controls. (Actually, I've wanted to do a book on the MSForms library in our In a Nutshell series, though I'm not sure how many programmers would actually be interested.) So in any case, your question should be of interest not only to users who are designing custom documents and beginning to experiment with programming, but also to Visual Basic programmers who are interested in doing a little bit of Word VBA programming.

Your guess that you needed to add some code to populate your drop-down combo box is quite correct. VBA allows you to assign a value to the combo box's Value and Text properties (in reality, they're the same property) from the user interface, which lets you add only a single item to a drop-down combo box. This, of course, isn't terribly useful, since presumably you're using the combo box to allow the user to choose from among multiple items. This is precisely one of those quaint features of the MSForms controls--in Microsoft's retail Visual Basic product, it's very easy to populate a combo box at design time.

In almost all cases, you want to populate the combo box before the user sees it, so that the user can select from among the available items. Fortunately, Word makes this easy. Whenever a document opens, Word checks the code behind a Word document for the presence of a procedure named Document_Open. If it is found, the code is executed. (The procedure, incidentally, is called an event handler, since it's automatically executed by Word in response to some event, in this case the document's being opened by the user.)

To open the code window and supply the code you need for the Document_Open event procedure, do the following:

  1. Have Word display the Visual Basic toolbar. (Select View / Toolbars / Visual Basic from the Word menus.)

  2. Click the Design Mode button to put your document in design mode.

  3. Click the View Code button in the toolbox. Word will open the VBA editor.

  4. In the editor's code window, select the Document item in the drop-down list in the upper left corner of the window, and the Open item from the drop-down list in the upper right corner of the window (see Figure 1).

  5. Word should automatically provide a code shell for the Document_Open event. You just need to add some code so that the code and shell appear as follows:
Private Sub Document_Open()
    Dim vColor, vColors

    vColors = Array("Green", "Red", "Blue")

    For Each vColor In vColors
        ComboBox1.AddItem vColor
    Next
    ComboBox1.ListIndex = 0
End Sub

Since you're not a programmer, let's discuss what this code does. First, it defines an array named sColors that holds the items you want to add to the combo box. (An array is a structured variable that is capable of holding more than one value or item.) The For Each...Next construct then iterates the array and adds each item to the drop-down combo box. Finally, the combo box's ListIndex property is set to 0. The ListIndex property determines which item in the list is selected. It has a zero-based index, meaning that the index of the first item is 0 rather than 1.

This code is quite extensible. You can change the values within the Array function to whatever you want. You can also add new values, as long as you separate them from the other values with a period. (And string values, of course, must be surrounded by quotation marks.)

Incidentally, in its current (default) form, this is a drop-down combo box rather than a drop-down list box. Our programming task will be a bit easier if we use a drop-down list box. The difference is that with the latter control, the user has to select from among options available in the list; in the former, the user can also add items to the list. To change the control to a drop-down list box, use the Properties window to change the drop-down combo box's Style property to 2 - fmStyleDropDownList.

Depending on exactly what you want this document to do and how you intend to use the drop-down list box, though, there may be one major problem: the item selected in the combo box is not persistent. That is, a user selection is not preserved between sessions. Fortunately, it's fairly easy to address this limitation.

To make the item selected in the drop-down list persistent, we need to store its value somewhere when the document closes and read its value when the document opens. In deciding what this "somewhere" might be, we have a number of choices:

  • We could include it in the text of the document itself. But this isn't an elegant solution, since it means that we have to add some unnecessary (at least, from the viewpoint of the user) text to our document. Since it's unnecessary text, it's also prone to deletion, which means that our user settings will be lost.

  • We could store it in a separate file. This isn't a good solution either. At some time in the life of the document, it and this file are almost sure to be separated, and our data will be lost.

  • We can store it "behind the scenes" in the document. Word has a feature called custom properties which was designed expressly for this purpose. It's this feature that we'll use--we'll add a custom property to our document to store the string that the user has selected from the drop-down list box.
When the document opens, we can populate the list box and retrieve the information about the user's selection. But how do we save the selected item? Fortunately, that's a question easily answered as well: Word supports a Document_Close event procedure that directly parallels the Document_Open event procedure. As you've probably guessed, the Document_Close event is fired when a document closes. (You can access the code shell for the Document_Close event by following the steps outlined earlier in selecting the Document_Open event. Just select the Close item from the drop-down list in the upper right corner of the VBA editor's code window.

You can then add code to the Document_Close event and modify the Document_Open event so that your code appears as follows:
click here for code example.

Here again, a bit of explanation is in order. Let's start with the Document_Open event procedure. Once again, we begin by populating our list box. Next, however, we don't want to arbitrarily determine which one is selected, as we did in our previous code example. Instead, we want to retrieve the user's selection.

There's a problem here, though. If the user hasn't made a selection (and if our code has never executed before), there won't be a selection to retrieve. This requires that we proceed with caution, since we're using the CustomDocumentProperties collection (an object that stores only information about custom properties) to store the value of the selected item in the drop-down list box. If no custom properties are defined (and most documents have no custom properties), attempting to extract information about a non-existent item from the collection will generate a syntax error.

To handle this eventuality, our code initializes a flag named bPropExists to let us know if we should actually retrieve the custom property or if we should create the custom property and arbitrarily assign its value. By default, the value of this flag is False, meaning that the property does not exist and should be added to the document. However, the code first checks the number of items in the CustomDocumentProperties collection. If at least one is present, it attempts to retrieve an item named SelColor. It then checks to see if it was successful in retrieving the item or not. In the former case, bPropExists is set to True.

If bPropExists is False--that is, if the custom property was not found--the code calls the Add method of the CustomDocumentProperties collection, which adds a persistent custom property to the document. Its value is arbitrarily set to "Green", and we also set the drop-down list box's ListIndex property to 0 (which corresponds to the "Green" item). (Note that the MSForms drop-down list box, drop-down combo box, and list box controls are all zero-based; that is, their first item is at position 0 in the list, not position 1.)

If bPropExists is True, our oProp object variable contains all the information about the custom property. So our program uses a For...Next loop to iterate the items in the list. It compares the text of each item with the stored selection. When a match is found, that item is designated the selected item and the loop is exited immediately.

The Document_Close event is quite simple. It just stores the text of the list box selection to the SelColor custom property.

This code can be used as a basic template for saving the selected item from a drop-down list box. It can also be extended by changing the drop-down list box to a drop-down combo box, which allows the user to add additional items to the list. Although I won't do it here, it's fairly easy to save the text of the items to a custom property so that they persist across Word sessions.

Thanks for submitting your question, and good luck getting those controls to work on your Word documents.

--Ron

Return to: Ron's Archive



O'Reilly Home | Privacy Policy

© 2007 O'Reilly Media, Inc.
Website: | Customer Service: | Book issues:

All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.