All of the architectures we have considered so far have sought to enhance Excel in some way to improve the end user's experience when using our application. In contrast, dictator applications seek to completely take over the Excel user interface, replacing Excel's menus with their own and exercising a very high level of control over the user. In the ideal dictator application, users cannot tell they are inside Excel.
These applications are created in Excel to use the features Excel provides, but those features are entirely controlled by the application and rarely (if ever) exposed to the user. Instead, the user interface is made up of tightly controlled data-entry worksheets and/or userforms, designed to appear like any other Windows application. These applications typically require large amounts of code to be able to have that level of control, but that degree of control enables us to write full-scale, fully functional Windows applications, on a par with any that can be written in Visual Basic or other "mainstream" application-development platforms. Indeed, by building our application within Excel, we are immediately able to utilize the incredible amount of functionality Excel provides.
If there is a requirement for our dictator applications to work in Excel 97, we are not able to have userforms and menu items available at the same time, because userforms are always modal. We therefore have the choice to base our user interface on using worksheets and menus, using userforms with buttons to navigate between the forms or by building modeless forms using VB6. Excel 2000 introduced modeless userforms, enabling us to make both userforms and menus available and allowing us much more flexibility when deciding whether to use a form or worksheet for the user interface. For this reason, we recommend that, if possible, Excel 2000 should be set as the lowest-level version dictator applications are designed to work within.
As dictator applications get more and more complex, they will often start to use functionality that only exists in the most recent versions of Excel (such as the XML import/export introduced in Excel 2003), so youas the designer of the applicationneed to decide what should happen if the application is opened in an older version. If the functionality being used is a core part of the application, it is unlikely the application will be usable at all in older versions. If the use of the new features can be limited to a small part of the application, it might make more sense to just disable that menu item, or provide separate routines for older versions to use. Making use of new Excel features will often result in compile errors if the workbook were to be opened in an older version, so many dictator applications use a "front-loader" workbook to do an initial version check, check whether all external dependencies (such as Outlook) are available, and then open and run the main application workbook if all the checks are okay. If the checks fail, we can provide meaningful error messages to the end user (such as "This application requires Excel 2000 or above and will not work in Excel 97").
There's no escaping the fact that dictator applications are much more complicated than either self-automated workbooks or application-specific add-ins and will require an intermediate to advanced-level Excel/VBA developer to create and maintain them. Although this type of architecture can get very complicated, the complexity can be mitigated by following the best-practices advice discussed in Chapter 3 Excel and VBA Development Best Practices (general advice) and Chapter 6 Dictator Applications (specific advice for dictator applications).
After the decision to build a dictator application has been made, we have an incredible amount of flexibility in terms of physically creating the application. The data could be stored in one or more separate workbooks, local databases (for example, Access databases), or a central database (for example, SQL Server). We could decide to include all the code in a single workbook or have a small "core" add-in, with numerous little applets that plug in to the core to provide the functionality, where each applet performs a single, specific task. The decision will probably be a trade-off between (at least) the following considerations:
-
A single-workbook structure is easier for a single developer to maintain, because everything is in the one place.
-
A multiple-workbook structure is easier for a team of developers to create, because each developer can work on his own applet without conflicting with another team member.
-
If a multiple-workbook structure is built so each plug-in applet is not loaded until it is first used, the initial opening of the core add-in will be quicker than loading the full application of the single-workbook structurealthough modern PCs might make that difference appear immaterial.
-
A single-workbook structure must be updated in its entirety, but the applets of a multiple-workbook structure can be updated and deployed independently.
-
The code required to implement a multiple-workbook plug-in architecture is quite complex, and might be too complex for the intermediate VBA developer to fully understandalthough we explain it in Chapter 11 Interfaces.
Requirements of a Dictator Application
To look and operate like a standalone Windows application, a dictator application needs to modify many Application properties, from turning on IgnoreOtherApplications (so double-clicking an XLS file in Explorer will not use our instance of Excel) to turning off ShowWindowsInTaskBar in Excel 2000 and above (because we may have multiple workbooks to be managed under program control), as well as hiding all the command bars. Unfortunately, Excel will remember many of those settings, to reuse them the next time Excel is started, so every dictator application must start by recording the existing state of all the settings that will be changed and restore them all when it closes. If the code to do this is written as two separate routines and assigned shortcut keys, they also provide an easy way to switch between the application's display and Excel's during development.
After a snapshot of the user's settings has been taken, the dictator application can set the application properties it requires; it then needs to lock down Excel to prevent users from doing things we do not want them to do, including the following:
-
Hiding and disabling all the command bars (including the shortcut command bars), then setting up our own.
-
Protecting our command bars and disabling access to the command bar customization dialog.
-
Disabling all the shortcut key combinations that Excel provides, and then optionally re-enabling the few we want to be exposed to the user.
-
Setting Application.EnableCancelKey to xlDisabled at the start of every entry point, to prevent users stopping the code.
-
When using worksheets as data-entry forms, we don't want the user to be able to copy and paste entire cells, because that includes the formatting, data validation, and so on. Therefore we need to turn off drag and drop (which does a cut and paste); trap both Ctrl+X and Shift+Delete to do a copy rather than a cut; and trap Ctrl+V, Shift+Insert, and the Enter keys to ensure we only ever paste values.
Having locked down the Excel environment while our application is running, we need to provide a mechanism for the developers to access the code, to enable them to debug the application. One method is to set a global IsDevMode Boolean variable to True if a particular file exists in the application directory or (more securely) depending on the Windows username. This Boolean can then be used throughout the application to provide access points, such as enabling the Alt+F11 shortcut to switch to the VBE, adding a Reset menu item and/or shortcut key to switch back to the Excel environment and not setting the EnableCancelKey property, to allow the developer to break into the code. The Boolean can also be used within error handlers, to control whether to display a user- or developer-oriented error message.
Structure of a Dictator Application
A typical dictator application uses the following logical structure:
-
A front-loader/startup routine to perform version and dependency checks and so on
-
A main "core" set of routines, to do the following:
Take a snapshot of the Excel environment settings and to restore those settings
Configure and lock down the Excel application
Create and remove the application's command bars
Handle copying and pasting data within the worksheet templates
Provide a library of common helper routines and classes
(Optionally) Implement a plug-in architecture using class modules, as described in Chapter 11 Interfaces
-
A backdrop worksheet, to display within the Excel window while userforms are being shown, usually with some form of application-specific logo (if we are primarily using forms for the user interface)
-
Multiple independent applets that provide the application's functionality
-
Multiple template worksheets used by the applets, such as data-entry forms or preformatted report templates