One thing I'd add to what's been said already is the importance of error
handling. Otherwise your users might be faced with cryptic error messages,
and be uncertain as to what to do next. Its important to understand that an
'error' does not mean something has gone wrong. Errors will happen during
the normal course of events. To take a simple example, say you have a button
to print a report for an employee selected in a combo box with:
Dim strCriteria as String
strCriteria = "EmployeeID = " & Me.cboSelectEmployee
DoCmd.OpenReport "rptEmployeeProjects", WhereCondtion:=strCriteria
In the report's NoData event procedure you have some code which informs the
user if there is nothing to report (e.g if the employee hasn't been assigned
to any projects):
Const conMESSAGE = _
"No projects have been assigned to this employee."
' inform user
MsgBox conMESSAGE, vbInformation, "Warning"
' cancel report
Cancel = True
If the report is cancelled the code in the button's Click event procedure
will raise an error (number 2501), and the user would get a system generated
error message in addition to your custom one. To avoid this you can handle
the error like so:
Const conREPORTCANCELLED = 2501
Dim strCriteria as String
strCriteria = "EmployeeID = " & Me.cboSelectEmployee
On Error Resume Next
DoCmd.OpenReport " rptEmployeeProjects ", WhereCondtion:=strCriteria
Select case Err.Number
Case 0
' no error so do nothing
Case conREPORTCANCELLED
' anticipated error so do nothing
Case Else
' unknown error so inform user
MsgBox Err.Description, vbExclamation, "Error"
End Select
If the anticipated error occurs then the user will be unaware of this. Only
if an unknown error occurs, i.e. if something really has gone wrong, will
they get the error message, but this will be via a simple message box, not
the usual potentially confusing error message dialogue, so they can back out
gracefully.
When developing the interface, if an anticipated error might occur, you can
at first deliberately generate it to get its error number, so you then know
what number to use when 'trapping' the error.
As well as runtime errors like the above there may well be situations where
a 'data error' occurs, e.g. an index violation if an attempt is made to save
a row to a table with a value in a uniquely indexed column which already
exists. These can be handled in a form's Error event procedure where you can
examine the value of the DataErr argument to see what error has occurred, and
take the appropriate remedial action.
Errors might also occur when executing an 'action query'. These can be
trapped by using the dbFailOnError option of the Execute method. This is
frequently done within a Transaction, so that the transaction can be rolled
back so as to avoid data being updated inconsistently; you would not want
only the first (debit) half of a transaction which moved money from one
account to another to succeed for instance, if there were an error executing
the second (credit) part!
Ken Sheridan
Stafford, England