You can use your favorite social network to register or link an existing account:
Or use your email address to register without a social network:
Sign in with these social networks:
Or enter your username and password
Forgot your password?
Yes, please link my existing account with for quick, secure access.
No, I would like to create a new account with my profile information.
Reader Štefan Masič provides today's Power Tip.
In today’s post I would like to share with you some tips about form design that I’m using consistently in all applications I develop. Maybe you can get some benefit from my approach to form design.
As we all know, analysis and preparation of user needs are essential in building all elements of an application. This approach results in forms that are easy to use, are uniform throughout the whole application, and are easy to maintain.
Here are some design needs which must be satisfied on every Access form:
It is common to put the name of a form into the window’s title with the Forms!FormName.Caption property. I prefer to use the Form Header Section with the label called lblFormName. This label can be larger and is therefore much more visible.
Figure 1: Title of the presented form is larger and more visible than the window’s title.
In my applications all mandatory fields have bold labels with the additional foreground color, named mandatoryLabelColor. All mandatory fields are surrounded with the border color, called mandatoryBorderColor.
Picture 2: Mandatory fields are visible on the first view.
All mandatory fields are positioned on the first page. All other non-mandatory fields are positioned after first page break. With this design, the user can immediately determine which fields are required. All other fields are below them and on a second page, which is immediately visible with moving of the scrollbar. I prefer designing a form with page breaks and using the scrollbar for easy moving between pages. From my experience, this works better than a Tab control on forms with many fields.
All fields with default values, fields with the auto number functionality or read-only fields should have a different background color. For example: I use a yellow background color, called specialBackgroundColor. Additionally, all those fields have the AutoTab property set to No.
As mentioned above I use three colors, mandatoryLabelColor, mandatoryBorderColor, specialBackgroundColor. For all those colors I always use company colors or ask the customer to pick specific colors.
In my examples the following colors were used:
If all the colors are determined during the analysis phase, and they’re not likely to change later, I always use a solution that does not require any programming. Here are Access numbers for all three colors, which I put into the appropriate properties of the labels and fields:
If I think the customer might prefer different colors at a later date, I use variables instead of constants. This solution requires creation of a new module, with declarations of three public constants and three public variables. See the example modGlobalConstantsAndVariables below.
Public constants can be used when colors are defined in an early phase and are not likely to be changed. Public variables can be used when it’s possible that the colors might be changed in the future.
Module modGlobalConstantsAndVariables looks like:
'------------------------------------------------------------ ' Element: Module, 2010 ' Description: Definition of global constants and variables. ' - mandatoryLabeleColor ' - mandatoryBorderColor ' - specialBacgroundColor '' Purpose : Global constants, global variables. '' Author: Stefan Masic, january 2010 ' Information: con = Constant; R=Red; G=Green; B=Blue ' See also: - ' Changes: ' (dd.mm.yyyyy, Author) Text '------------------------------------------------------------ '-------------------------------------------------------------------- ' Public constants. Public Const conMandatoryLabelColor = 5334976 ' R=0 G=117 B=84 Public Const conMandatoryBorderColor = 31983 ' R=239 G=124 B=0 Public Const conSpecialBackgroundColor = 57087 ' R=255 G=222 B=0 '-------------------------------------------------------------------- '-------------------------------------------------------------------- ' Public variables. Public lngMandatoryLabelColor As Long Public lngMandatoryBorderColor As Long Public lngSpecialBacgroundColor As Long '-------------------------------------------------------------------- ' End of module '--------------------------------------------------------------------
The simplest programming solution requires creation of a new OnOpen event on each form, with the following code for every mandatory field and every special field:
Private Sub Form_Open(Cancel As Integer) On Error GoTo Err_Form_Open Me.MandatoryLabelName.ForeColor = conMandatoryLabelColor Me.MandatoryFieldName.BorderColor = conMandatoryBorderColor Me.SpecialFiledName.BackColor = conSpecialBackgroundColor Exit_ Form_Open Exit Sub Err_Form_Open MsgBox Err.Description Resume Exit_Form_Open End Sub ‘ Form_Open
When I’m creating a general purpose application where colors are likely to change, I use a special table, called tabDefaultApplicationValues. In its simplest definition, this table includes only one row and many fields. This table includes three fields MandatoryLabelColor, MandatoryBorderColor, and SpecialBackgroundColor. I also need function getDefaultApplicationValue(ValueName).
With this method, the simple procedure Form_OnOpen needs a little rearranging:
Me.MandatoryLabelName.ForeColor = lngMandatoryLabelColor Me.MandatoryFieldName.BorderColor = lngMandatoryBorderColor Me.SpecialFiledName.BackColor = lngSpecialBackgroundColor
Public variables can be filled during the loading process of Main form or Switchboard with the following code:
lngMandatoryLabelColor = getDefaultApplicationValue(“MandatoryLabelColor”) lngMandatoryBorderColor = getDefaultApplicationValue(“MandatoryBorderColor”) lngSpecialBackgroundColor= getDefaultApplicationValue(“SpecialBackgroundColor”)
Here is a simple function you can use to retrieve the color values from the table:
'------------------------------------------------------------ ' Element: Function, 2010 ' Purpose: Get value from table tabDefaultApplicatonValues. ' ' Input: Default value field name (String) ' Output: Value (String) ' ' See also: tabDefaultApplicationValues ' Avtor: Stefan Masic, january 2010 ' Remark: ' Changes: '------------------------------------------------------------ Public Function getDefaultApplicationValue(strDefaultValueName As String) As String On Error GoTo Err_getDefaultApplicationValue Dim dbs As DAO.Database Dim rst As DAO.Recordset Dim strDefaultValue As String Dim strSqlStmt As String ' Check default value name. If IsNull(strDefaultValueName) Then strDefaultValue = "" Else ' Define current DB. Set dbs = DBEngine.Workspaces(0).Databases(0) strSqlStmt = "SELECT " & strDefaultValueName & " FROM tabDefaultApplicationValues" Set rst = dbs.OpenRecordset(strSqlStmt) ' Get value if record exists (rst.RecordCount>0). If rst.RecordCount > 0 Then ' Check NULL. If Not IsNull(rst.Fields(0).Value) Then strDefaultValue = rst.Fields(0).Value Else strDefaultValue = "" End If Else strDefaultValue = "" End If ' Free rst in dbs. rst.Close dbs.Close End If ' IsNull getDefaultApplicationValue = strDefaultValue Exit_getDefaultApplicationValue: Exit Function Err_getDefaultApplicationValue: MsgBox Err.Description & " (Error no.: " & Err.Number & ")" Resume Exit_getDefaultApplicationValue End Function ' getDefaultApplicationValue
If the solution requires personalization of default application values, or if the solution will be used by many companies, then this table will have two or more rows of default values for every configuration, and the function will have two parameters. Here are two examples:
getDefaultApplicationValue(UserId, ValueName). getDefaultApplicationValue(CompanyId, ValueName).
The first described approach does not require any programming, and as such it is easier to manage the application over time and with new versions of Access. I recommend this approach.
Comments: (5) Collapse
Does changing this make us any more or less vulnerable to the bot attacks which have become so prevalent these days? We are specifically not using a forum because it is impossible for us, as a small company, to control.
Some other suggestions for dealing with this flexibly: 1. define an Enum with meaningful color names instead of using constants. This means that you can define a parameter for a sub/function that sets colors and have it be limited to the values defined in the enum. You also get Intellisense for the parameters when typing the sub/function in code. 2. if using a lookup table, don't just look up the values each time the function is called, but store them somewhere. I like using self-initializing standalone class modules or functions that use static variables internally (which are initialized on the first call and then not looked up again on further calls). Other experienced developers will use a hidden form and just store the values in controls on that hidden form. 3. rather than write the repetitive code in each OnOpen event, use a sub/function that you pass a form variable and then operate on each form the same way, utilizing the form's Controls collection. You'll need to define the groups of controls that need each particular type of formatting, and the Tag property is very useful for this. As an alternative to the Tag property, you could also check the controls to see if the field that is the ControlSource is required, an Autonumber or has a default value, and choose the color based on that, but I think it's easier to just set the Tags. In addition to setting visual formatting, you may also incorporate enable/disable and showing/hiding particular controls at runtime. However, most of the time you're doing that, you're likely to do it more often than just when the form opens (e.g., in the OnCurrent event), in which case it becomes noticeably faster if you define custom collections in the form's OnLoad and then operate on those collections (those can be passed to a common sub/function for processing, just like the suggestion above for setting colors).
Dear David! Thank you for your adivice. All three steps and the addition are true and will be meaningfull for me and other developers. Originaly my first tought was to show how important is design phase when we "convert" database and process characteristics into form elements. Regarding step 2. When I use data from table for local definitions (personalization of single instance of application) then this is true. If I use data for global definitions (between many users), then I must read value from table. Thank you again. With best regards, Štefan Masič.
M 0386 41 672 487
E stefanmasicsp@gmail.com
Good design - I pretty much follow your form design but I am concerned with speed and accuracy on forms and also use hotkeys so data entry people won't have to use a mouse which takes the hands off keys and slows down input. Thanks!
Dear DataPlus developer (mr. bhicks11). Thank you for your comment. Above forms are only part of whole design "story". When I'm designing application (and DB) for OLTP needs, I always consult my users ("data entry users"). We designed together also their process (for example: it is better to manually order atomic input elements (input documents of any kind) before entry start) and then use special steps like "Copy last document into new one" or "Next document will be like last one" and so on. In such scenario users must insert only small numbers of data fields (1 or 2). I also always strictly follow Referential and Domain integrity rules and special rules like “key data must be inserted – NOT NULL. It is key thing for users also. In OLAP phase I really do not need cleaning and transformation step and also OLAP step can be done on-line. From the user perspective it is also better because they see only latest information (for example: last information in process always close all other data). Regarding hotkeys – I do not use them – but I will – soon. I promise. Thanks for advice. My users all get Access Reference Card with all integrated keys and knowledge of QBE steps. If you wish I can send you one for Access 2000 and one for Access 2003. After that they have good knowledge for elegant and fast data entry, retrieval and data mining tasks. After couple of weeks I'm always afraid when I see "my" users how fast (really fast) they are working with Access forms. Thank you for your Comment, Štefan Masič. P.S. If you have time you can look on one of my application at http://odvetnik.wordpress.com (it is designed for layer office, it is called MY layer office).
Comments: (loading) Collapse