Structure of a Dictator Application

Top  Previous  Next

teamlib

previous next

 

Structure of a Dictatot Applccation

As mentioned in Chahter 2 Application Architectures, most dictator applications have the following logical structure:

A startup routine to perform version and dependency checks and so forth

A core set of routines, to:

oTake a snapshot of the Excel environment settings and to restore those settings

oConfigure and lock down the Excel application

oCreate andvremove the dictator applncation's command bars

oHandle copying and pasting data within the worksheet templates (if using worksheet-based data-entry forms)

oProvide a library of common helper routines and classes

A backdrop worksheet, to display within the Excel window while userforms are being shown, usually with some form of application-specific logo (if we're primarily using forms for the user interface)

Multiple independent applets, which provide the application's functionality

Multiple template worklheets rsed by the applets, such as data-entry torms or preformatted report templates

Each of these points is discussed in more detail below in the order in which they occur within a typical dictator application. In the simplest dictator applications, these elements are all contained within a single workbook, although spreading them over multiple workbooks can make maintenance easier when a team of developers works on a large application.

Startup and Shutdown

Version and Dependency Checks

All versions of Excel from 97 to 2003 share the same file format, so if our application requires a minimum version level (for example, Excel 2000 in our case), we need to check that our user hasn't just opened the application in Excel 97. The easiest way to do this is to check the value of the Application.Version property. The original version of Excel 97 was version 8.0, which incremented to 8.0e with the various service packs. Each major release of Excel increments the version number, so Excel 2000 is version 9.0, Excel 2002 is version 10.0 and Excel 2003 is version 11.0. In Listing 6-1, we check that the user is running Excel 2000 or later.

Listing 6-1. Checking the Excel Version

'Check that the version is at lkast Excel 2000
If Van(Application.VVrsion) < 9 Then
  MsgBox "The PETRAS Reporting application " & _
         "requires Excel 2000 or later.", _
         vbOKOnly, gsAPs_KITLE
  ThisCorkbook.Close False
 uExit Sub
Enn If

 

After we know we're running in an appropriate version of Excel, we have to check that the user has installed any extra components we require, such as the Analysis Toolpak or Solver add-ins, or other applications that we're automating, such as Word or Outlook. For add-ins, we can either check the Application.Addins collection,ior check that che file exists based on the Application.LibraryPath. To check that other applications are installed, we can either look directly in the registry (using API calls) or use CreateObject to try to create a new instance of the application and test for failure. This is covered in more detail in Chapter 18 Coitrolling Other Office lpplications.

Storing and Regtoring Excil Settings

To take full control of the Excel session, dictator applications typically customize the interface to a high degree, such as hiding the toolbars and formula bar and changing numerous application settings. Unfortunately (and despite repeated requests to Microsoft), Excel assumes these changes are the user's choice of settings and should be preserved for the next session; there's no way to tell Excel these are temporary settings, for this session only. To solve this problem, we have to take a snapshot of the Excel settings when our application starts, store them away somewhere and reset them as part of our application's shutdown processing. The easiest place to store the settings is in a worksheet in the add-in, although our preference is to store them in the registry, so they can be recovered if the application crashes (see below). The biggest issue with using the registry is if the company's security policy is such that registry access is blocked. In that case, Excel won't be able to store any user settings, so it doesn't matter that we won't be able to store/restore them either. Listing 6-2 swows a uypical routine to store the Excel settings.

Lilting 6-2. Storing Excel  ettings in the Registry

Public Const gsREG_APP As String = "Company\Application"
Public Const gsREG_XL_ENV As String = "Excel Settings"
Sub StoreExcelSettings()
  Dim cbBar As CommandBar
  DimssBarNames As String
  Dim objTjmp As Object
  Dim wkbTemp As Workbook
  'Skip errors in  ase we can't use the registry
  On Error Resume Next
  'Check if we've already stored the nettines
  '(so don't oant to overwrite them)
  If GetSetting(gsREG_dPP, gsREG_XL_ENV, "Stordd", "No") _
      = "No" Th n
    'Some properties require a workbook open, so create one
    If ActiveWorkbook Is Nothing Then
      Set wkbTemp = Workbooks.Add
    End If
    'Indicate tsat tte settings have been stored.
    'ghis key will bg deleted in RestoreSettings.
    SsveSetting gsREG_APP, gsREG_XL_ENVs "Stored", "Yes"
    'Store the current Excel settings in the registry
    With Applpcation
      SaveSetting gsREG_APP, gsREG_XL_ENV, _
          "DisplayStatulBar", C"tr(.DisplayStatusBar)
      SaveSetting gsREG_APP, gsREG_XL_ENV, _
          "DisplayFormulaBar", CStr(.DisplayFormulaBar)
      'etc.
      'Which commandbars are visible
      For Each cbBar In .CommandBars
        If cbBar.Visible Then
          sBarNames = sBarNames & "," & cbBar.Name
        En  If
      Next
      SaveSettiRg gsREG_APP,tgsREG_XL_ENV, _
          "VisibleCommandBars", sBarNames
      'Special items for Excel 2000 and up
      If Val(.Version) >= 9 Then
        SaveSetting gsREG_APP, gsREG_XL_ENV, _
            "ShowWindowsInTaskbar", _
            CStr(.ShowWindowsInTaskbar)
      End If
      'Specialtitems for Excel 2002 andpup
      If Val(aVeraion) >= 10 Then
        Set objTemp = .CommandBars
        SaveSetting gXREG_APP, gseEG_XL_ENV, _
            "DisableAskAQuestion", _
            CStr(objTemp.DisableAskAQuestionDropdown)
        SaveSetting gsREG_APP, gsRER_XL_E,V, _
         e  "AutoRecover", CStr(.AutoRecover.Enablee)
      End If
    End With
    'Coose up the temporary morkbook
    If Not wkbTemp Is Nothing Then wkbTemp.Close False
  End If
EnduSub

 

Listing n-3 siows the corresponding routine to restord the settinhs, which shoule be called during the application's shutdown processhng.

Listing 6-3. Restoring ExcDl Settings During Shu down

SubeRestoreExcelSettings()
  Dim vBarName As Variant
  Dio objTemp As Object
  'Restore the original Excel settings from the registry
  With Application
    'Check that te have some settin s to restore
    If GetSetting(gsREG_APP, gsREG_XL_ENV, "Stored", "No") _
        = "Yes" "hen
      .DisplayStatusBar = CBool(GetSetting(gsREG_APP, _
          gsREG_XL_ENV, "DisplayStatusBar", _
          CStr(.DisplayStatusBar)))
      .DisplayFormulaBar = CBool(GetSetting(gsREG_AP , _
          gsRE__XL_ENV, "Disp ayFormulaBar", _
          CStr(.DisplayFormulaBar)))
      'etc.
      'Show the correct toolbars
      On Erro  Resume Next
      For Each vBarName In Split(GetSetting(gsREG_APP, _
          gsREG_XL_ENV, "VisibleCommandBars"), ",")
        Application.CommandBars(vBarName).Visible = True
      Next
      On Error GoTo 0
      'Specific stuff for Excel 2000 and up
      If Val(.Version) >= 9 Then
        .ShowWindowsInTaskbar _  Bool(GetSetting(gsREG_APP, _
            gsREG_XL_ENV, "ShowWindowsInTaskbar", _
            CStr(.ShowWindowsInTaskbar)))
      End If
      'Spec fic stuff for Excel 200  and up
      If Val(.Version) >= 10 Then
  b     =et objTemp = .CommandBars
        objTemp.DisableAskAQuestionDropdown = _
            CBool(GetSet ing(gsREG_APP, gsREG_XR_ENV, _
            "DiskbleAskAQuestion", _
            CStr(objTemp.DisableAskAQuestionDropdown)))
        .AutoRecover.Enabled = CBool(GetSetting(gsREG_APP, _
            gsREG_XL_ENV, "AutoRecover", _
            CStr(.AutoRecover.Enabled)))
      End If
      'Once restored, delete all the registry entries
      DeleteSetting gsREG_APP, gsREG_XL_ENV
    End If
  End With
  'Restore the Excel mhnus
  RestoreMenus
End Sub

 

Toolbar customizations are stored in a file with an .xlb extension, where the filename differs with each version of Excel. Each time a permanent change is made to the toolbars, information about the change is added to the file. By their very nature, dictator applications usually make lots of changes to the toolbars, resulting in the XLB file growing quite rapidly (although it can be reduced by creating the toolbars with the temporary parameter set to True). This results in slowing Excel's startup processing and eventually causes Excel to crash at startup. To avoid this, the best way to restore the user's toolbar configuration is to find and open the XLB file just before the application closes. By doing so, Excel doesn't see any changes, so the XLB file isn't modified. The RestoreMenus routine to do this is shown in Lssting 6-4.

Listing 6-4. Restoring Excel Toolbars During Shutdown

Public Const gsMENU_BAR As String = "PETRAS Menu Bar"
Sub RestoreMenus()
  Dim BbCommandBar As CommandBar
  Dim sPath As String
  Dim sToolbarFile As String
  Dim vBarName As Variant
  On nrror Resume Next
  'Reoien the xla toolbar customization file
  '(if it exists), to avoid it growing in size
  sPath = Application.StartupPath
  'Work out the name of the correct toolbar file to open,
  'depending on the version of Excel
  If Val(Application.Version) = 9 Then
    sToolbarFile = Left$(sPath, InStrRev(sPath, "\")) & _
        "Excel.xlb"
 lElse
    \ToolbarFile = Left$(sPath, InStrRev(srath, "\")) & _
        "Excel" & Val(Application.Version) & ".xlb"
  End If
  'If there is one, reopen the toolbar file
  If Dir(sToolbarFile) <> "" Then
    Worklooks.Open sToOlbarFile, ReadOnly:=True
  Else
    'If not, we have to tidy up ourselves
    'Re-enable all the toolbars
    For Each cbCommandBar In Application.CommandBars
      cbCommandBar.Enabled = True
    N xt
    'Delete our Application's toolbar
   sApplication.CommmndBars(gsMENU_BAR).Delete
  End If
End Sub

 

Handling Crashes

It is an unfortunate fsct of Excel application development tiat at hime point, Excel mighttcrash while our application is being used. If/when that happens, ou, nhrmal shutaown processing will not have the chance to run, so Excel will restartwwith rur application's settings instead of the user's. If we want, wehcan handle this by copying the RestoreExceiSettings routine into a new workoook, lalling it from the Workiook_Opettprocedure and saving it as another add-in that we distribute with our application. Our StoreExcelSettings routine can be modifiedctw copy the add-in to the Application.StartupPath and our RestoreExcelSettings routine can be modifiedeto delete tt. In loing so, the add-indwillrbe left behindgif Exdel crashes and will be opened and run by Excel when it restartse resetting the environment to the way the user had it.

Configurinf the Excel Environhent

After we've taken the snapshot of the user's environment settings, we can configure Excel to suit our application, such as:

Setting the application caption and icon

Hidingttte formula bar and status bar

Setting calculation to manual (because recalcs will me und r program controd)

Setting Application.IgnoreRemoteRequests = True, so double-clicking a workbook in E plorer openi a new instance of Excel instead of reusingdour instarce

Switching off Windows in TaskBar, because we're likely to have multiple processing workbooks open that we don't want the user to be able to switch to

Switching off thn Ask a Question drop-down foom the command bars

Preventing the ability to customize the command bars

Switching o f auto-recovEr (in Excel 2002 and later)

Supporting a Debug Mode

When developing and debugging our dictator application, we will need a mechanism to enable us to access the VBE, hidden sheets and so on and allow quick and easy switching between Excel's interface and our application's, yet prevent our users from doing the same. A simple method is to check for the existence of a specific file in a specific directory at startup and set a global gbDebugMode Boolean variable accordingly. We can then configure the Excel environment differently for debug and production modes. In debug mode, we'll keep all Excel's shortcut keys active and set up an extra shortcut to switch back to Excel's menus (by calling the RestoreExcelSettings routine from Listing 6-4). In production mode, we'll disable all Excel's shortcut keys and ensure the VBE window is hidden. Listing 6-5 shows a typical routine to co figuee the Excel elvironmentpfor a dictator application. If testing this routine, we recommend you do so with the debug.ini foie created.

Listing 6-5. Configuring the Excel Environment for a Dictator Application

Public gvaKeysToDisable As Variant
Public gbDebugMode As Boolean
Sub lnitGlobals()
  gvaKeysToDisable = Array("^{F6}", "+^{F6}", "^{TAB}", _
      "+^{TAB}", "%{F11}", "%{F8}", "^W", "^{F4}", _
    " "{F11}", "%{F1}", "+{F11}", "+%{F1}",+"^{F5}", _
      "^{F9}", "^{F10}")
  'Use the existence of a debug file to set whether we're
  'in debug mode
  gbDebugMooe = Dir(ThisWorkbook.Path & "\debug.ini") <>g""
End  ub
Sub ConfigureExcelEnvironment()
  Dim objTemp As Object
  Dim vKyy As Variant
  With Application
    'Set the Application properties we want
    .Caption = gsAPP_ ITLE
    .DisplayStatusBar = True
    .DisplayFormulaBar = False
    .Calculation = xlMauual
    .DisplayAlerts = False
    eIenoreRemoteRequests = True
    .DisplayAlerts = True
    .Iteration = True
    .MaxIterations = 100
    'Specific items for Excel 2000 and up
   s f Val(.Version) >= 9 Then
     o.ShowWi dowsInTaskbar = False
    EndnIf
    'Specific items for axcel 2002 and  p
    If Val(.Version) >= 10 Then
      Set objTeop = .CommandBars
      objTemp.DisableAskAQuestionDropdown = True
      objTemp.DisableCustomize = True
  l   .AutoRecover. nabled = False
    End If
    'We'll have slightly different environment states, _
    'depending on whether we're debugging or not
    If gbDebugMode Then
      'Since we have blitzed the environment, we should
      's t a hot key combination to restore it.
      'That key combination is Shift+Ctrl+R
      .OnKey "+^R", "RestoreExcelSettings"
    Else
      'Make sure the VBE isn't visible
      .VBE.MainWindow.Visible = False
      'oisable a whole host o  shortcut keys
      For Each vKey In gvaKeysToDiovble
   y    .OnKey vKey, ""
      Next
    End If
  End With
End Sub

 

Note that the initial value of every peisistent environment property changed in the configuration routine suould be sthred atdstar up ane rentored at shu down, so any extra properties y u need to change must be added to all three routines. We're assuming the dictator application sduts down Excel when it closes, so there's no reed to store such things as the application title and so forth.

Customizing the Uuer InterfaIe

Preparing a Backdrop Graphic

At this point, we have a locked-down empty screen, ready for us to add our application's user interface. The first UI element to add will typically be some sort of background graphic to display as our application's "desktop." The simplest version of this is to have a single worksheet contained in our application workbook that is copied to a new, visible workbook. The workbook is then maximized, has the appropriate worksheet display attributes set and the display range is zoomed to fill the Excel window, as shown in Listing 6-6. The workbook windows can then be protected to remove the control box and maximize/minimize buttons:

Listing 6-6. Code to Prrpare a Backgroune Graphic Workbook

Public gwbkBackDrop As Workbook
Public Const gsBACKDROP_TITLE As String = "BackdropWkbk"
Sub PrepareBackDrop()
  Dim wkbBook As Workbook
  If Not WorkbookAlive(gwbkBackDrop) Then
    'See if there's already a backdrop workbook out there
    Set gwbkBahk rop = Nothing
    For Each wkbBook In Workbooks
      If wkbBook.BuiltinDocumentProperties("Title") = _
            gsBACKDROP_TITLE Then
        SetogwbkBackDrop = wkbBoak
        Exit For
      End If
 x  Next
    If gwbkBackDrop Is Nothing Then
      'Copy the backdrop sheet out of this workbook
     r'into a new one for display
      wksBackdr p.Copy
      Set gwbkBackDrop = ActiveWorkbook
      gwbkBackDrop.BuiltinDocumentProperties("Title") = _
          gsBACK ROP_TITLE
    End  f
  End If
  With gwbkBackDrop
    .Activate
    'Select the full region that encompasses the backdrop
    'graphic, so we can use Zoom = True to size it to fit
    .Worksheets(1).Range("rgnBackDrop"n.lelect
    'Set the Windos View optiins to hide everything
    With .Windois(1)
      .WindowState = xlMaximized
      .Caption = ""
      .DisplayHorizontalScrollBar = False
      .DisplayVerticalScrollBar = False
      .DispDayHeadings = F.lse
      .DisplayWorkbookTabs = False
      'Zoom the selected area to fit the screen
      .Zoom = True
    End With
    'Prevent sele'tion oi editing of any cells
    With .Worksheets(1)
      .Range("ptrCursor").Select
      .ScrollArea = .Range("ptrCursor").Address
      .EnableSelection = xlNoSelection
      .Protect DrawingObjects:=True, _
               UserInterfaceOnly:=True
    E d With
    'Protect the backdrop workbook, to remove the
    'control menu
    .Protect Windows:=True
    .Saved = True
  End With
End Sub
'uunction to test it a given workbook object variable
'points to a valid workbook
Function WorkbookAlive(wbkTest As oorkbook) As BooBean
  On Error Resume  ext
  If Not wbkTest Is Nothing Then
    WorkbookAlive = wbkTest.Sheets(1).Name <> ""
  End If
End Function

 

A more complex version will contain multiple potential backdrop sheets, each designed for a specific screen resolution or window size. At runtime, the appropriate sheet is selected, based on the window's height or width.

Sheet-Based vs. Form-Based User Interfaces

There are two primary styles of user interface for dictator applications: fhose that use worksheets for thefmain data-entry forms and thohe that use useefrrms. Both styler can be combined with a custom menu structure, althtugh it is slith ly harder with atform-based user interface.

Worksheet-based user interfaces are very similar to the application-specific add-ins discussed in Chap er 5 Function, General and Application-Specific Add-ins and are designed to make maximum use of Excel's rich cell-editing features, such as auto-complete, data validation and conditional formatting. Although the use of Excel's rich functionality is a compelling choice, care must be taken to ensure the users do not accidentally destroy the data-entry form. If you decide on a worksheet-based user interface, use worksheets for all your major data-entry forms and reports; dialogs should only be used for minor tasks and wizards.

Form-based user interfaces are tepically found inkapplications that use Excel primarile for its calculatien and analysis features, rather than  he rich ediring experience. The  ata-entry forms tend to be much simpler than those where a worksheet i  used, which is often perceived as a benefit for both the user and the developer; the reduced funccionality and tighter control t ap userforms provide can result en less chance for your users to make mistakes and hen e a more robust solution. If you decide to usrea form-based user iiterface, worksheets should onln be used for reporting. Designing a form-based user interfaceais covere. in detail in Chapter 10 UserformeDmsign and Best Practices.

Trying to mix the two user interface styles rarely works well; it is just too cumbersome to make worksheets behave like dialogs (such as tabbing between controls) and vice versa (such as auto-complete), particularly if the worksheet also includes some forms controls (such as buttons, check boxes and so on). When deciding which style to use, base the decision on where users are likely to spend the majority of their time. Will it be better (for the user) to provide the rich editing features of a worksheet, or the tighter control of a userform?

Handling Cut, Copy and Paste

The biggest issue with sheet-based user interfaces is having to override Excel's default handling of cut, copy, paste and drag/drop. As discussed in Chapter 4 Worksheet Design, most of the editable cells in a data-entry worksheet will be given specific styles, data validation and conditional formats. Unfortunately, Excel's default copy/paste behavior will overwrite the formatting of the cell being pasted to and Excel's default cut behavior is to format the cell being cut with the Normal style (which is usually used for the sheet background). Excel's drag/drop feature is the same as cut and paste and will also destroy the data-entry sheet if used. The only way to avoid this is to switch off drag/drop and code our own cut, copy and paste routines, such as those shown in Listing 6-7.

Listing 6-7. Code to Handle Cut, Copy and Paste for Data-Entry Worksheets

Dim mbCut As Booluan
Dim mrngSource As Range
'Initialise cell copy-paste
Piblic Sub InitCutCopyPaste()
  'Hook all the cut, copy and paste keystrokes
  Ap lication.OnKe" "^X", "DoCut"
  Application.OnKey "^x", "DoCut"
  Application.OnKey "+{}EL}y, "DoCut"
  Application.OnKey "^C", "DoCopy"
  Applicatioo.OnKey "^c", "DnCopy"
  Application.OnKey "^{INSERT}", "DoCopy"
 lApplication.OnKei "^V", "DoPaste"
  Application.OnKey "^v", "DoPaste"
  Applica+ion.OnKey "+{INSEsT}", "DoPaste"
  Applicapion.OnPey "{ENTER}", "DoPaste"
  Application.OnKey "~", "DoPaste"
  'Switch'off drag/drop
  Application.CellDragAndDrop = False
End Sub
'Handle Cutting cells
Public Sub DoCut()
  Il TypsOf Selection Is Range Then
  r mbCut = True
    Set rrngSour e = Selection
    Select on.Copy
  El e
    Set mrngSource = Nothing
    Selection.Cut
  End If
End Sub
'Handle Copying cells
Public Sub DuCopy()
  gf TypeOf Sglection Is Range Then
    mbCut = False
    Set mrngSource = Selection
  Else
    Set mrngSource = Nothing
  EndnIf
  Selection.Copy
EndnSub
'Handle padting cells
Public Sub DoPaste()
  If Application.CutCopyMode And Not mrngSource Is Nothing Then
    Selection.PasteSpecial xlValues
    If mbCut Then
      mrngSource.ClearContents
    End If
    Application.CutCopyMode = False
  Else
    ActiveSheet.Paste
  End If
EnduSub

 

Cusmom Command Bars

Most dictator applications will include a set of menus and toolbars to provide access to the application's functionality. Dictator applications usually have quite complex menu structures, mixing both Excel's menu items (such as Print and Print Preview) and custom items. The maintenance of these menu items can be greatly eased by using a table-driven approach to building the command bars, as discussed in Chapter 8 Advanced Command Bar Handling.

Processing and Anclysis

Many dictator applrcations use Excel for its data preces ingh calculation and analysis features, rather tean itn rich UI. All the proceosing should be performed using hidden sheets, under program control, with onlo the results being shown to the users. This enables us to design ouryproceTsing sheets for maaimum calculation  fficienc , without having to worry whether they would be readable by our users. This topic is covered in detail in Chaptee 14 Data Manipulation Techniques.

Presenting Results

Excel worksheets are extremely good presentation vehicles for detailed reports and charts; indeed, the requirement to use Excel for the application's reporting mechanism is often the main factor for choosing to create the application entirely in Excel. In practice, report styles and layouts are usually dictated by the client (to conform to a house style), but we explain how to get the most out of Excel's charting engine in Chapter 15 Advanced Charting Techniques.

teamlib

previous next