UtterAccess HomeUtterAccess Wiki

Welcome Guest ( Log In | Register )

Custom Search
Edit Discussion
> Options Design    
Revision as of 09:49, 20 June 2018; view current revision
←Older revision | Newer revision→
Options Design

Image:NotifWarningWeak.gif This page has been marked as incomplete

No notes were left concerning the page's incomplete status.

If this page has been completed please remove the {{INCOMPLETE}} template from the page's source markup.

This article gives an overview of some consideration for designing an options system for an application. There's a few ways to approach this (none of which are wrong), generally falling into one of the following categories: very few options with a well designed GUI, a basic options system which provides decent user control over the interface, or a large and complex options system which allows the user to completely customize their application interface.


The Important Part

SeeAlso: GUI Design

Regardless of whether we intend to implement a small, compact options system or a large complex UI customization system in our application, the bottom line remains the same: the interface must be designed to ensure the user will be able to quickly gain a fluent control of the core application features. Anything less can be very frustrating to users.

No amount of options given to a user will help them find their way through a bad UI. If the user is discouraged at the onset of using the application due to it's non-intuitive user interface, they are not likely to go sorting through a complex options system (which is likely to be at least as bad as the UI to begin with). Likewise, having little or no options only works if the UI is very well designed to begin with. The idea in this scenario is to not give the user a reason to want to customize because it works so well to begin with.

The ideal situation is one where the user is immediately (or as reasonably close to as possible) comfortable with the UI in its default settings. This should be the same regardless of the extent of available options. Bear in mind that options are merely an extension of the UI and are... go figure... completely optional for the user. However, a thorough customization implementation can add much value to a well designed GUI.

No Options vs. Many

Content Forthcoming. The author of the article has included this section as a placeholder or otherwise noted that it is incomplete.

Making Options Available & Understandable

When considering the design of an options system, it is important, especially with complex customizations, that the options be easy to find and well organized once found. For instance, when using traditional menus, the Options command is found under the "Tools" main menu. In the Ribbon, Options are found either on the Office Button (2007) or in the Backstage Menu (2010). Applications should implement placement of the options entry accordingly in order to maintain consistancy with other Windows software.

The Options Dialog

The Options window should always be a modal window: not allowing users to return to the application until that window is closed. This avoids confusion if a user were to change an option but not apply it, then return to application form do perform a task while the Options window is left open.

Generally, the Options window consists of one main window with a tab control if the number of options warrants it. Below the tab control there is traditionally three buttons: Cancel, Apply and OK. It is recommended to make use of these three buttons as well in order to provide for a familiar and comfortable feel when the user is working with options.

Organization of Options

The organization of options within the Options dialog is essential to the overall "feel" of the application. A poorly organized options dialog is little better than useless. Options should be well categorized, grouped and sorted as well as classed by "Common" and "Advanced" options.

Option categorization is generally defined through a main tab control in the Options Dialog. Option Grouping is generally a sub-organization of each category: placing related options per category in their own group such as a "Reporting" category (tab) and a "Printing" group. The sorting of options is generally done by the pertinence of the options (and groups) rather than alphabetically. Realize that users should be able to intuitively find things, and an alphabetic list of options is not intuitive for any user except perhaps those that know every option by heart anyway.

Common & Advanced Options

Common options would be those that the new user would be interested in and can easily imagine their effect. These options should be given space in their respective categories (tabs) and be made prominant and very easy for new users to identify and understand.

Advanced options would be options that are pertinent to intermediate to experienced users of the application, and thus should be kept out of the way of the common options. Advanced options for a category or group are generally called by a button click which opens another (modal) window to deal with those particular options.

By adopting this approach to options, one can implement a highly organized system of complex options that is easy for both new users as well as experienced users.

Documentation & Usage Hints

In an effort to make options understandable, it may be advisable to provide some on-screen descriptions of what options actually do. Generally speaking, short worded option texts are ideal, as long lists of long worded options can be confusing and less "clear cut." The label of the option control itself should be as short as feasible.

By implementing a description box (below the main Options Dialog Tab, to the left of the "Cancel, Apply and OK" buttons perhaps), a user can select any given option and see a much more detailed description in that display. This wording can give overview information on what effects this option will have on the application experience. This is especially important for advanced and obscure options where the effect may not be entirely clear.

Likewise, a screentip can hold similar or identical information as a description box, and F1 context help (or help buttons) can provide a means for the user to view complete documentation on the option.

Always attempt to provide your users with as much information about the options without requiring them to backtrack out of the Options Dialog to do so. Failure to do so will make users far less likely to play with options, and thus ultimately view the application in a lesser quality than could be.

Implementing the Options System in the Application

The implementation of an options system can be broken down into three areas as follows:

  1. UI Design (Options Dialog and layout)
  2. Storage of Option Values
  3. Coding for Option Implementation

In general application design, the coding is often most time consuming task, but this is not so true when working with an option system. The section #A Comparison of Hardcoding & Options Coding sheds some light on how the actual task of programming for option effects can be a very simple process.

Storage and retrieval of Option settings is also a lightweight task as far as RDBMS's are concerned. In most cases, this can be accomplished with the addition of only one or two tables to the database.

However, designing and coding the Options UI (the Options Dialog) can be a tedious task. The form layout and binding situation of an Options Dialog is usually nonstandard from other Access forms. The task generally involves custom code to manage the controls and values in the Options Dialog.

Option Storage and Retrieval

Storage of options will vary based on whether they are Application Options (shared by all users) or User Options (where each user manages their own options). For the purpose of this article, we will be considering User Options as implementation of Application Options is very similar and easily put in perspective.

User Options are generally stored in two tables, one which defines all available options, and another junction table which links the available option to the user. Let us proceed based on the following assumptions:

  • There exists a Users table with user information
  • We will create an Options table to store all available options
  • We will create a UserOptions junction table with a many-to-many relationship between Users and Options

The Options Table

For performance purposes, it's recommended that the Primary Key of the Options table be of Long Integer type. This table should include a default value as well as a description. (the Options Module will provide an enumeration of options in a textual format for ease of coding).

One method of storing option values is to create one field of Text datatype and convert all numeric and boolean values to store as text, and convert to their required types upon retreival. Another method is to include different fields for each type (e.g - NumericValue, StringValue, BoolValue, MemoValue) along with a field to denote which value field this option will retrieve from.

The UserOptions Table

The UserOptions table is a simple junction between Users and Options (ie. - each user can have many options; each option can have many users). This is generally a three-field table: User, Option and Value. An appropriate query can be written to display all options per user while pulling the option descriptions from the Options table as required for display purposes.

The Options Module

The Options module is where the management of option values will during runtime will be handled. This generally consists of two main sections: the Enumeration of options and the Collection of values, as well as a small handful of functions to Get, Set and Refresh the options.

Enumeration of Options

An enumeration of options can make the developer's life far easier. The textual values of the enumeration provide a means to easily refer to options throughout the project in a human readable manner while maintaining the performance of having a numeric-driven database key system for the options.

Using a singleton Options collection class with a default Item method we can greatly simplify the calling procedure throughout the VBA project by calling the class name followed by a parethese:

The Options Collection

Using a Collection to store the options in provides fast, in memory access to all the user options after they have been initially loaded. This collection is the core of the Option module and holds all of the realtime values that will be retrieved as the user runs the application. For example, when a form opens, the Open or Load event will refer to a function in the Options module which retrieves the value, which in turn pulls the value from the module's collection. Likewise, saving a new value would update the collection's value and also the table value.

Collections take a string key and a variant value. In the case of our Options collection, we can easily convert the unique, enumerated OptionID into a string using the built in Str() function to set and retrieve the values.

A Quick Note on Performance

The reason a Collection is preferable over reading directly from the table at every option request is because the table is a disk read where the collection is a memory read. This has a significant impact on performance, and for the greater majority of cases our users will greatly benefit from a slight delay on login to read the entire table into the collection at once rather than a slight delay every time an option value is required throughout the application (as it must then construct the SQL, access the disk to read the table, then return). Disk reads are always very slow in comparison to memory reads.

A Comparison of Hardcoding & Options Coding

A common trait for VBA beginners is to hardcode values into their code. As we gain experience, we learn that a better method is to instead provide constants for these values, and, in essence, hardcode the constants so they need only be changed in one place.

As we become "option aware" it becomes apparent that we can go one step further from this and reduce the amount of constants in our code, replacing them instead with an Options value. If the option is not set, it remains the default property, but provided we make this very slight change in coding style, we are then opening the door for much customization in our applications. Consider the following code:

Const BACKCOLOR = vbRed
Me.MyThing.Backcolor = BACKCOLOR

as opposed to this minor change:

Me.MyThing.Backcolor = Options(UOptMyThingBackcolor)

As easy as that (provided of course we have the Options Module in place), we have allowed our users to customize the properties of many things.

Abstracting Code: The Option Developer's Sanity

As easy as the above may seem, this still leaves many situations where a particular option will cover a multitude of effects in the application rather than just a single property. Of course, this becomes slightly more complex, but with a good grasp of abstraction, it need not be.

Abstraction is an OOP (Object Oriented Programming) term which more or less says that each portion of code (each object) will concern itself only with itself. Details of abstraction is beyond the scope of this article, but we need not completely understand it to make use of it for our purposes here. Instead, we'll consider a fairly extreme options scenario:

  • Application has a Switchboard
  • Application provides an option to view the switchboard in two drastically layouts - different buttons, controls, etc
  • Application switchboard(s) have commands that invoke functions in our project in order to carry out tasks such as opening detail forms or exporting data

In this case, we'll have three different sections of code:

  1. Login and load a switchboard
  2. Switchboard says "someone clicked this button, time to give out a command!"
  3. Program logic carries out the command.

The key to abstraction is this: The Login procedure has no idea (nor care) what switchboard is loaded. The program logic has no idea (nor care) which switchboard woke it up. Abstraction isolates each section and doesn't interact with others except through generic commands.

What does this mean for us as far as options go? Maybe not much, but if we're looking at a highly customizable application UI, this could mean all the difference in the world when it comes to developing and maintaining the code that makes everything work.

In this scenario, we can have two drastically different switchboards whose selection is Option-driven, and we need not add any extra code to handle it (except writing a secondary switchboard). Consider the following psuedo-code:

Public Sub Login()
End Sub
Public Sub OpenSwitchboard()
    If CStr(Options(UOptSwitchboard)) = "Switchboard1" Then
        DoCmd.OpenForm "Switchboard1"
        DoCmd.OpenForm "Switchboard2"
    End If
End Sub

And finally, each switchboard would proceed to call standard commands for getting things done in the application (such as opening this form, or running that report, etc.)

Through abstraction, that is, by isolating each code section from the others, we can implement what may initially seem like very complex changes in the behavior of our applications through some very simple means.

Changing Options & Reloading Objects

Advanced Integration: Handling Realtime Changes with Events

Summary: Considerations on Option Developement vs. Practicality

Edit Discussion
Custom Search

Thank you for your support!