Developing Office Wizards

Wizards are common features of many software applications. Not only do they guide you through a series of tasks and often help you save time creating documents, they also step you through many prebuilt content templates and provide you with ideas, starter text, formatting, and organization. The new style of Office wizards now lets you navigate more easily, both backward and forward, through the steps and allows you to track your progress visually through the task steps so you have a sense of where you are and where you're going.

It's even easier if you integrate the Office Assistant with wizards. The Assistant gives you tips for going through the steps as well as visual examples and step-by-step instructions for specific tasks.

Wizard Look and Style

The wizard dialog box has three main features: navigation buttons, a subway map, and tab pages. The subway map is optional but is provided in many Office wizards. Your wizard works equally well without it.

Click to view at full size.

The Energy Wizard has the same look and style as the Fax Wizard in Word. To access the Fax Wizard, click New on the File menu in Word, and in the Letter And Faxes tab, select the Fax Wizard icon and click OK. (The details of the AutoContent Wizard in PowerPoint differ slightly from those of the wizards in Word, but the look and style of the two wizard types are the same.) In this chapter, you'll use the details of the Fax Wizard in Word as the model. The code for the wizard UserForm will be very generic so that you can easily plug the same code into a wizard in any Office application.

Set Up a Multiple-Step Wizard Dialog Box

You can easily build dialog boxes with multiple steps by using the MultiPage control. The MultiPage control is a container of controls within a collection of pages. As you'll see, the MultiPage control makes it simple to design each page because you can add controls to one page and display the controls of another page.

  1. Start Word. Display the Visual Basic Editor and insert a new UserForm.
  2. In the Properties window, change the default name in the Name property of the new UserForm from UserForm1 to frmWizard.
  3. In the Toolbox, click the MultiPage control and then click the frmWizard UserForm.

  4. MultiPage control

  5. In the Properties window, change the default name in the Name property from MultiPage1 to mpgSteps. (The prefix mpg represents "multipage.")
  6. Right-click the first tab of the mpgSteps control and click New Page on the shortcut menu.
  7. This adds a new page to the mpgSteps control. The tab caption of the new page is Page3.

  8. Click the tab with the caption Page1 and change the Name property in the Properties window to pgStart. (The prefix pg represents "page.") Change the Caption property from Page1 to Start.
  9. Click the tab with the caption Page2 and change the Name property to pgStep1. Change the Caption property to Step1.
  10. Click the tab with the caption Page3 and change the Name property to pgFinish. Change the Caption property to Finish.

Your MultiPage control has three pages. The first page is the Start screen, or the screen that the wizard displays first. The last page is the Finish screen, which the wizard displays once the user completes all the steps in the wizard. The page between the first and last pages will become the step in the wizard where the user sets options and enters information that the wizard needs to complete its overall task. Each subsequent step in the wizard requires its own page. In the section later in this chapter titled "Add a New Step in the Wizard," you'll learn how to add another new page and, hence, another new step in your wizard.

By default, the program sets the style of the MultiPage control to the enumeration value fmTabStyleTabs, which represents a value of 0. Later in this chapter, when you start adding controls to each page in the control, you'll set the Style property of the MultiPage control to fmTabStyleNone so that the tabs aren't displayed in the wizard dialog box. Some wizards display tabs, but the style you're creating in this chapter doesn't.

Add Navigation Buttons

Most well-designed wizards provide a set of common navigation buttons along the lower edge of the wizard dialog box. These navigation buttons are Cancel, Previous, Next, and Finish. With the introduction of the Office Assistant, you can add another button that allows you to display tips or instructions from the Assistant.

  1. Move the MultiPage control mpgSteps to the upper-right area of the frmWizard UserForm.
  2. Resize the UserForm to slightly increase its width. Double-click the CommandButton control in the Toolbox, and then click four times in the lower area of the UserForm, working from left to right, to create four command buttons. Use the following illustration as a guide:
  3. Click to view at full size.

NOTE
By double-clicking a control in the Toolbox, you can add more than one of a particular control to a UserForm without having to continuously click the control in the Toolbox. You can't resize or select any other control in the UserForm until you click the Select Objects arrow in the Toolbox.

  1. Click the Select Objects arrow in the Toolbox so that you can select the controls in the UserForm, and then change the properties of the CommandButton controls to the following:

  2. Select Objects arrow

    Control Property Value
    CommandButton1 Name cmdCancel
    CommandButton1 Caption Cancel
    CommandButton1 Cancel True
    CommandButton2 Name cmdPrevious
    CommandButton2 Caption < Previous
    CommandButton2 Accelerator P
    CommandButton3 Name cmdNext
    CommandButton3 Caption Next >
    CommandButton3 Accelerator N
    CommandButton4 Name cmdFinish
    CommandButton4 Caption Finish
    CommandButton4 Accelerator F

    You should set the Cancel property of the Cancel button to True so that the user can press ESC to cancel the wizard dialog box. Allowing the user to cancel a dialog box by pressing ESC is a standard Windows programming practice.

  1. Double-click the Previous button and add the following line to the cmdPrevious_Click event procedure:
  2. mpgSteps.Value = mpgSteps.Value - 1
    

    The Value property of the MultiPage control mpgSteps is an integer that indicates the currently active page. A value of 0 represents the first page in the control. The maximum value of this property is the number of pages minus 1. Each time you click the Previous button, the program decreases the value of the mpgSteps control by 1 and displays the previous step.

  3. In the Object drop-down list of the frmWizard Code window, select cmdNext and add the following line to the cmdNext_Click event procedure:
  4. mpgSteps.Value = mpgSteps.Value + 1
    

    Each time you click the Next button, you increase the value of the mpgSteps control by one and display the next step.

  5. In the Object drop-down list of the frmWizard Code window, select cmdCancel and add the following line to the cmdCancel_Click event procedure:
  6. Unload Me
    

    The Visual Basic keyword Me is an implicit reference to the UserForm in which the code is currently running. Thus, Me represents the frmWizard UserForm. When you click the Cancel button or press ESC, you close the dialog box and unload it from memory.

  7. In the Object drop-down list of the frmWizard Code window, select cmd-Finish and add the following line to the cmdFinish_Click event procedure:
  8. Unload Me
    

    For now, the Finish button closes the UserForm. Later in this chapter, however, to the cmdFinish_Click event procedure you'll add code that checks the values entered in the steps in the wizard and then calls a number of procedures to perform the wizard's overall task before unloading the dialog box from memory.

  9. In the Object drop-down list, select mpgSteps and add the following lines to the mpgSteps_Change event procedure:
  10. Select Case mpgSteps.Value
        Case 0
            cmdNext.Enabled = True
            cmdPrevious.Enabled = False
            cmdFinish.Enabled = False
        Case m_iTotalSteps - 1
            cmdNext.Enabled = False
            cmdPrevious.Enabled = True
            cmdFinish.Enabled = True
        Case Else
            cmdNext.Enabled = True
            cmdPrevious.Enabled = True
            cmdFinish.Enabled = False
    End Select
    

    When the value of the MultiPage control mpgSteps is changed by the cmdNext_Click or cmdPrevious_Click event procedure, the Change event of the mpgSteps control is triggered. The Select Case statement you added evaluates the current value of the mpgSteps control and determines the appropriate course of action. If the value is 0, the program displays the Start page and disables the Previous button because there are no more pages before the Start.

    If the value is equal to the module-level variable m_iTotalSteps minus one, the program displays the Finish page and disables the Next button because there are no more pages after the Finish. In this case, however, it enables the Finish button. The variable m_iTotalSteps is declared in step 10 and represents the total number of pages in the mpgSteps control. If the value of the mpgSteps control is neither the first nor last page, both the Previous and Next buttons are enabled.

  11. In the Object drop-down list of the frmWizard Code window, select UserForm. In the Procedure drop-down list of the module, select Initialize and add the following lines to the UserForm_Initialize event procedure:
  12. m_iTotalSteps = mpgSteps.Pages.Count
    mpgSteps.Value = 0
    Call mpgSteps_Change
    

    Before the dialog box is displayed, you need to initialize the state of some controls and then set the value of the variable m_iTotalSteps. This is done in the UserForm_Initialize event procedure, which runs just before the dialog box is displayed on the screen. In the Initialize event procedure of the frmWizard UserForm, m_iTotalSteps is set to the number of pages in the mpgSteps control.

    The second line of code above sets the value of the mpgSteps control to 0 so that the Start page is shown when the UserForm is displayed. Despite the fact that the value of the mpgSteps control is set, the mpgSteps_Change event procedure may not run if the value of the mpgSteps is 0 while you're designing the UserForm. Thus, you explicitly call the mpgSteps_Change event procedure so that the navigation button is also initialized.

  13. In the Declarations section of the frmWizard Code window (at the top of the code window before the first procedure), add the following module-level declaration:
  14. Dim m_iTotalSteps As Integer
    

TIP
If the Option Explicit statement isn't included at the beginning of the frmWizard Code window, you should add it by typing "Option Explicit" before the module-level declaration you added in the previous step. If you want the Option Explicit statement to be added to any code module by default, on the Tools menu in the Visual Basic Editor, click Options, and then click Require Variable Declaration in the Editor tab of the Options dialog box. See "Do I Need to Declare My Variables and Constants?" in Chapter 2 for more information.

  1. In the frmWizard UserForm, resize and move the navigation Command-Button controls, using the following illustration as a guide. Then press F5 to display the dialog box.
  2. The program disables the Finish and Previous buttons and shows the first page (the Start page) in the MultiPage control when the wizard is displayed. Click the Next and Previous buttons to see the pages of the MultiPage control being activated and the navigation buttons being enabled and disabled.

  3. Click Cancel, and then in the Project Explorer, right-click the frmWizard project item located in the Forms folder. Click Export File on the shortcut menu.
  4. In the Export File dialog box, change to the Chapter 3 subfolder in the Office VBA practice folder, type the name frmWizardTemplateBasic in the File Name text box, and click Save.

This example gave you the basics of setting up a wizard dialog box. In steps 12 and 13, you exported the UserForm so that you can use it as a starting point when you create a new wizard. In the next example, you'll continue building onto your wizard by adding the subway map panel on the left side of the UserForm.

Create a Subway Map

The "subway map" is a new style of Office wizard that permits easy navigation through the wizard's steps by giving a visual representation of where you are within the wizard. Each "station" on the subway map represents a step in the wizard, and the current station, or step, is green. If you want to skip a step or jump to a specific step, you can do so by using the subway map panel.

  1. In the Editor, in the Project Explorer, double-click the frmWizard project item. In the Toolbox, click the Image control, and then click in the upper-left area of the UserForm. In the Properties window, change the name of the Image control from Image1 to imgLeftPane.

  2. Image control

  3. Click the Image control in the Toolbox again and click the UserForm just below the imgLeftPane control. Change the name of the Image control from Image1 to imgBottomStripe.
  4. To change the color of the Image controls you just inserted, select both Image controls by first selecting either one and then holding down the CTRL key to select the other. In the Properties window, click the value of the BackColor, and then click the arrow. Click the Palette tab and select the color black.
  5. Move and resize the imgLeftPane and imgBottomStripe controls so that the UserForm looks like the following illustration:
  6. Click the Image control in the Toolbox and then click the imgLeftPane control. Change the name of the newly inserted Image control to imgSubway. You're placing imgSubway on top of imgLeftPane.
  7. In the Properties window, change the BackStyle property of the imgSubway control to 0 - fmBackStyleTransparent. Change the BorderColor property by clicking the arrow, clicking the Palette tab, and selecting light gray. The value &H00C0C0C0& appears, which represents light gray.
  8. Add another Image control and place it in the upper-left corner of the imgSubway control. Change the name to imgStart and set the BorderStyle property to 0 - fmBorderStyleNone. Resize the control so that it looks like the following illustration:
  9. Click the imgStart control. On the Edit menu, click Copy. On the Edit menu, click Paste twice to create two copies of the control. In the Properties window, select Image1 from the drop-down list and change its name to imgStep1. Similarly, change the name of Image2 to imgFinish.
  10. Move the imgStep1 and imgFinish controls so that they are on the border of the imgSubway control.
  11. If the imgStep1 and imgFinish controls are underneath the mpgSteps control, select the selection border around the mpgSteps control and move the control temporarily out of the way. Also, if one image is underneath the other, select one by clicking its name in the drop-down list in the Properties window to select the control on the UserForm. Then drag the control to a new location on the UserForm.

  12. In the Toolbox, click the Label control, and then click the UserForm just beside the imgStart control. Set the following properties for the Label control:
  13. Property Value
    Name lblStart
    BackStyle 0 - fmBackStyleTransparent
    Caption Start
    ForeColor &H00FFFFFF& (or white in the Palette tab)

  14. Select the lblStart control by clicking any other control and then clicking the lblStart control. (If you initially click only the lblStart control, you'll select the caption of the control, not the control itself.) On the Edit menu, click Copy, and then paste the control twice.
  15. Move one of the pasted Label controls beside the imgStep1 control, name it lblStep1, and set the Caption property to Step1. Move the second pasted Label control beside the imgFinish control, name it lblFinish, and set the Caption property to Finish.
  16. Move and resize the controls so that the UserForm looks like the following illustration:
  17. Make sure the label controls are slightly wider than the text they contain.

  18. Select the controls imgStart, lblStart, imgStep1, lblStep1, imgFinish, and lblFinish, and then in the ControlTipText property in the Properties window, type To skip to this step, click here. Each subway map image and label has the same ToolTip text, which is the same as that in Word's Fax Wizard.

You've completed the layout of the subway map. What remains is to add the code that allows you to use the map to navigate through the steps.

Indicate Active and Visited Steps in the Subway Map

The subway map has to indicate which step is currently active and which steps you have visited. You indicate the currently active step by setting two properties of the controls in the subway map. First, set the BackColor property of the Image control, or station, to light green. Second, set the font of the station label to bold. Once you move on to another step in the wizard, the program sets the BackColor property of the Image control of the previous station to dark gray to indicate that you have previously visited it.

  1. In the Project Explorer, select the frmWizard project item and click the View Code button, which is the leftmost button on the Project Explorer toolbar.

  2. View Code

  3. At the top of the module, just after the module-level declaration m_iTotalSteps, add the following module-level declaration:
  4. Dim m_sCurStep As String
    

    The variable m_sCurStep is the name of the current step, and it's used to keep track of the current step. Once you move to another step, you can use the value in the variable m_sCurStep to determine what the previous step was and to reset its properties so that the previous step appears visited.

  5. In the Object drop-down list of the frmWizard Code window, select mpgSteps so that the mpgSteps_Change event procedure appears. Add the following procedure call just before the Select Case statement so that the call is the first line of the mpgSteps_Change event procedure:
  6. SetSubwayMap
    

    Every time the mpgSteps_Change event procedure runs, the SetSubwayMap procedure is called so that the images and labels of the map can be initialized.

  7. At the bottom of the module, create the SetSubwayMap procedure by adding the following code:
  8. Sub SetSubwayMap()
        Controls("img" & m_sCurStep).BackColor = &H808080
        Controls("lbl" & m_sCurStep).Font.Bold = False   
        Select Case mpgSteps.Value
            Case 0
                m_sCurStep = "Start"
            Case m_iTotalSteps - 1
                m_sCurStep = "Finish"
            Case Else
                m_sCurStep = "Step" & mpgSteps.Value
        End Select
        Controls("img" & m_sCurStep).BackColor = vbGreen
        Controls("lbl" & m_sCurStep).Font.Bold = True
    End Sub
    

    The SetSubwayMap procedure performs three tasks. The first task is to use the m_sCurStep value to determine what the previous step is. The program calls the SetSubwayMap procedure when the value of the mpgSteps control has been changed. Before you update the value of m_sCurStep to reflect the current step, you reset the control properties of the previous step so that it appears visited. You do this by setting the BackColor property of the Image control to dark gray (&H808080) and the font of the Label control to roman (not bold).

    For the second task of the procedure, the Select Case statement evaluates the current value of the mpgSteps control and sets the variable m_sCurStep to the name of the current step. You then use the value of m_sCurStep to set the BackColor property of the current Image control to light green (vbGreen). The Visual Basic color enumeration vbGreen represents the value &HFF00.The third task of the procedure is to set the associated Label control's font to bold.

  9. In the Object drop-down list of the frmWizard Code window, select UserForm. In the Procedure drop-down list in the upper-right area of the Code window, select Initialize and add the line:
  10. m_sCurStep = "Start"
    

    The UserForm_Initialize event procedure should now look like this:

    Private Sub UserForm_Initialize()
        m_iTotalSteps = mpgSteps.Pages.Count
        m_sCurStep = "Start"
        mpgSteps.Value = 0
        mpgSteps_Change
    End Sub
    

  11. In the Project Explorer, select the frmWizard project item and click the View Object button, which is just to the right of the View Code button on the Project Explorer toolbar.

  12. View Object

  13. Select the imgFinish control on the frmWizard UserForm. In the Properties window, change the BackColor property to red in the Palette tab (a value of &H000000FF&).
  14. The color red is used as an initial indicator that this step is the last one in the wizard (or the last station on the subway map).

  15. Click anywhere on the frmWizard UserForm and press F5 to run the UserForm.
  16. Click to view at full size.

    Click the Next and Previous buttons to see the program activate the pages of the MultiPage control, enable and disable the navigation buttons, and update the properties of the subway map's Image and Label controls. The last remaining task is to add the code that allows you to click the controls on the subway map to navigate between the steps.

Add Code to the Subway Map

  1. Close and unload the frmWizard UserForm by clicking the Cancel or Finish button.
  2. Double-click the imgStart control of the subway map and add the following line to the imgStart_Click event procedure:
  3. mpgSteps.Value = 0
    

  4. In the Object drop-down list, select lblStart and add the following line to the lblStart_Click event procedure:
  5. mpgSteps.Value = 0
    

  6. In the Object drop-down list, select imgStep1 and add the following line to the imgStep1_Click event procedure:
  7. mpgSteps.Value = 1
    

  8. In the Object drop-down list, select lblStep1 and add the following line to the lblStep1_Click event procedure:
  9. mpgSteps.Value = 1
    

  10. In the Object drop-down list, select imgFinish and add the following line to the imgFinish_Click event procedure:
  11. mpgSteps.Value = m_iTotalSteps - 1
    

  12. In the Object drop-down list, select lblFinish and add the following line to the lblFinish_Click event procedure:
  13. mpgSteps.Value = m_iTotalSteps - 1
    

  14. Press F5 to run the UserForm.
  15. Click the Image and Label controls on the subway map to see the program enable and disable the Previous and Next buttons and activate the pages of the MultiPage control.

Add a New Step in the Wizard

You need to use the naming convention for the controls of the subway map so that a new step can be added easily. The following example shows how to set up your code to add more steps as needed.

  1. Close and unload the frmWizard UserForm by clicking the Cancel or Finish button.
  2. In the frmWizard UserForm, select the imgStep1 control. With the CTRL key pressed, select the lblStep1 control adjacent to it.
  3. On the Edit menu, click Copy and then click Paste. The program pastes copies of the controls imgStep1 and lblStep1 into the center of the UserForm and selects both copies.
  4. Click the selection border of either one of the controls and drag the two controls so that the imgStep1 control sits on the border of the imgSubway control.
  5. Rename the pasted Image control to imgStep2 and the Label control to lblStep2. Change the Caption of lblStep2 to Step2.
  6. Move imgStep1, lblStep1, imgStep2, and lblStep2 so that these controls are evenly spaced on the border of the imgSubway control.
  7. Click the mpgSteps MultiPage control and then right-click any of the tabs. On the shortcut menu, click New Page. The program adds a new page to the control with the default tab caption Page1.
  8. In the Properties window, change the Caption property of Page1 to Step2 and then change the Name property to pgStep2.
  9. Right-click any tab in the MultiPage control. On the shortcut menu, click Move. The Page Order dialog box, which lists the pages within the MultiPage control, is displayed.
  10. In the Page Order dialog box, select Step2 in the Page Order list and click the Move Up button to move the Step2 page after the Step1 page and before the Finish page. Click OK.
  11. Double-click the imgStep2 control. In the imgStep2_Click event procedure, add the following line:
  12. mpgSteps.Value = 2
    

  13. In the Object drop-down list, select lblStep2 and add the following line to the lblStep2_Click event procedure:
  14. mpgSteps.Value = 2
    

  15. Press F5 to run the UserForm. Click the Next button, or click the label Step2 to navigate and activate the second step in the wizard.
  16. Close and unload the frmWizard UserForm by clicking the Cancel or Finish button.
  17. Right-click the frmWizard project item in the Project Explorer and then click Export File on the shortcut menu. In the Export File dialog box, change to the Chapter 3 practice folder and in the File Name text box, type the name frmWizardTemplateSubway and click Save.

You've completed the wizard UserForm with its subway map. In step 15, you exported the UserForm so that you can use it as a starting point when you create a new wizard with a subway map. The final process in setting up the wizard UserForm is to add the new element that all wizards in Office can include: the Office Assistant.

NOTE
Because none of the code in the UserForm you've created so far is specific to any Office application, you can import the wizard UserForm into a Visual Basic for Applications project in any application.