Online Book Reader

Home Category

Access Cookbook - Ken Getz [122]

By Root 2132 0

We added four fields to tblCustomer: two fields to hold the username and date/time the record was created, and another two fields to hold the username and date/time the record was last modified. You don't have to create all four fields, only the fields for which you wish to log information.

We also created event procedures to update these columns whenever a record is inserted or updated. The Now function supplies the date and time; if you'd prefer to record only the date of the change without a time, you can use the Date function instead. The built-in CurrentUser function saves the name of the current user.

Access doesn't support the specification of calculated fields at the table level, so all of the logic presented in this solution occurs at the form level. This means that you must recreate this logic for every form that updates the data in this table. It also means that if you add new records or update existing records outside of a form—perhaps by using an update query or by importing records from another database—the fields in Table 6-1 will not all be automatically updated.

You can ensure that one of the fields, DateCreated, is correctly updated for every record by adding the following expression to its DefaultValue property:

=Now( )

Unfortunately, you can't use the DefaultValue property for either of the updated fields, because DefaultValue is evaluated only when the record is initially created. You can't use this property to update the UserCreated field, either, because DefaultValue cannot call built-in or user-defined functions (except for the special Now and Date functions).

You may have noticed that placing the four controls from Table 6-2 on the form takes up a considerable amount of screen space. Fortunately, you don't need controls to make this technique work, because Access lets you refer to a form's record-source fields directly. In the sample database you'll find a second version of the form, frmCustomer2, that demonstrates this variation of the technique. Notice that there are no txtDateCreated, txtUserCreated, txtDateModified, or txtUserModified controls on frmCustomer2, yet when you enter or edit a record using this form, the fields in tblCustomer are correctly updated. Here's the BeforeUpdate event procedure for this form:

Private Sub Form_BeforeUpdate(Cancel As Integer)

Me.DateModified = Now( )

Me.UserModified = CurrentUser( )

End Sub

Access lets you refer to fields in a form's underlying record source (in this example, the DateModified and UserModified fields in tblCustomer) as if they were controls on the form, even though they're not. Because of this, it's a good idea to name the controls on a form differently from the underlying fields. Then you can be sure that you are always referring to the correct object.

Another consideration is that the CurrentUser function is useful only if you have implemented user-level security on your database. In an unsecured Access database it will always return "Admin", which is not very informative. In that case, you can use Windows API calls to retrieve either the computer name or the network login (or both) of the current user, instead of the Access security account. In the sample application, frmCustomer3 calls acbNetworkUserName when a record is inserted or edited. Here are the API declaration and the function, which you can find in basNetworkID:

Private Declare Function GetUserName Lib "advapi32.dll" Alias _

"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Function acbNetworkUserName( ) As String

' Returns the network login name.

Dim lngLen As Long, lngX As Long

Dim strUserName As String

strUserName = String$(254, 0)

lngLen = 255

lngX = GetUserName(strUserName, lngLen)

If lngX <> 0 Then

acbNetworkUserName = Left$(strUserName, lngLen - 1)

Else

acbNetworkUserName = ""

End If

End Function

The basNetworkID module also includes the following API call, which you can use to obtain the name of the current user's computer:

Private Declare Function GetComputerName _

Lib "kernel32" Alias "GetComputerNameA" _

(ByVal

Return Main Page Previous Page Next Page

®Online Book Reader