When dealing with live systems, you need a mechanism for logging and keeping people out of an application's back end. As with most system problems, a number of different solutions exist.
One solution to keeping a property on the back end is to keep track of whether users are to be logged out. The preceding section describes the method for creating a property for a database. The difference is that this time, you have to use the back-end database, VideoDat.mdb, rather than the front-end database. Figure 26.3 shows the database properties of VideoDat.mdb, with a LogUserOut property added. You can examine this property from VBA and act accordingly. VideoDat.mdb, like VideoApp.mdb, is on the accompanying CD-ROM in the Examples folder.
There's a problem with using the “property on the back-end database” method. If you use this method for logging a person out and the back-end database is corrupted, you get an error. The solution is to create a file in the back-end folder that the user's front end looks at and then acts accordingly. The file created, LogOut.flg, has its attribute flag set as Hidden so that there isn't a problem with users deleting the file arbitrarily to get back into the system.
Section 2 of ap_AppInit()calls the function ap_CheckLogOut(), passing the variable pstrBackEndPath, which contains the last known path to the back end:
'-- Section 2: User requested to logout, quit the application If ap_LogOutCheck(pstrBackEndPath) Then Beep MsgBox "Maintenance is being performed on the backend" & vbCrLf _ & vbCrLf & "All users are requested to logout at this time.", _ vbOKOnly + vbCritical, "Logging Out for Maintenance" Application.Quit Exit Function End If
Figure 26.4 shows the message that occurs when the user needs to stay out.
You might wonder why the application passes the last known path rather than checks the current path from one of the linked tables. If a problem is encountered with the back end or someone is already trying to get everybody out, it's not necessary to make users wait to relink all the tables just to find out they need to leave the system.
Listing 26.3 shows the code for ap_LogOutCheck(), located in the modGlobalUtilities module, which performs the check to see whether the user needs to be logged out.
Function ap_LogOutCheck(strBackEndPath As String) As Integer On Error Resume Next ap_CheckLogOut = Dir(strBackEndPath & "LogOut.FLG", vbHidden) = _ "LogOut.FLG" End Function |
Notice that the error handling in the function just skips to the next line, thereby passing back the false value for ap_LogOutCheck().
Tip
Just as variables default to zero when Dim'd as an integer, so do functions. Always explicitly declare your functions and variables. Otherwise, they're implicitly declared as Variant, which is slower to process.
The last thing to note is that you're using the Dir command with the vbHidden attribute flag designated. This allows you to look for a file even when it's hidden. The average user can't see it through Windows Explorer or File Manager.
The preceding section describes how to log users out of the system when first starting up. Sometimes you need to log users out when they're in the middle of the application.
The method described here requires a hidden form that contains nothing but a timer event procedure. You can use this procedure with another form if you have one that you already have open at all times.
The form used here is UserLogOutMonitor. Figure 26.5 shows the form with its property sheet.
The Timer Interval property allows you to specify an interval of time in milliseconds. Therefore, the 60000 shown in Figure 26.5 is 60 seconds. So every 60 seconds, Access triggers the supplied OnTimer event.
Note
Because the LogOut.flg file is in the same folder as the back end, it might be that checking the network once a minute causes too much network traffic. You have to work with this property to see what timing works for your situation.
Listing 26.4 shows the code for the OnTimer event for the UserLogOutMonitor form.
Private Sub Form_Timer() If ap_LogOutCheck(ap_GetDatabaseProp(CurrentDb(), _ "LastBackEndpath")) Then If Not ap_FormIsOpen("UserLogOutCountdown") Then DoCmd.OpenForm "UserLogOutCountdown" End If Else If ap_FormIsOpen("UserLogOutCountdown") Then DoCmd.Close acForm, "UserLogOutCountdown" Beep MsgBox "The Logout Countdown has been canceled." & vbCrLf & _ vbCrLf & "You may go on with your work.", _ vbInformation, "Logout Canceled" End If End If End Sub |
The Form_Timer event procedure performs these steps:
1. | |
2. |
This last step is in case the administrator who told people to log out changes his mind. You can see the message for this cancellation in Figure 26.6.
By looking at the UserLogoutCountdown form, you can see that only two events are attached to the form. The code in UserLogoutCountdown keeps track of a countdown, starting at five minutes. The form also informs users that they'll be logged out of the system at the end of the countdown. This time span allows users to finish any work they have to do before time is up. When time is up, the system shuts them down, no matter where they are at this time.
The form itself is set up to be a pop-up non-modal form, which lets the user clean up and yet not have the countdown form get lost beneath other windows. Figure 26.7 shows the UserLogoutCountdown form in Design view.
Caution
Be careful of setting your form's Pop Up and Modal properties while removing all the Windows control buttons. You could end with a form very difficult to close. Always be sure to leave a way out of a form, either through a Close command button or the window's close (×) button.
The other way to close the form is to press Ctrl+G, opening the Immediate window. You could then type DoCmd.Close in it.
Although not shown in Figure 26.7, the Timer Interval property for this form is set to 60000 milliseconds, just as it was on the UserLogOutMonitor form. This property drives the countdown process and calls the OnTimer event procedure that contains the routine. Listing 26.5 shows the declarations section of the form module, the Form_Open event procedure, and then the Form_Timer subroutine.
'-- Declarations Section Option Compare Database Dim intCountDown As Integer Private Sub Form_Open(Cancel As Integer) intCountDown = 5 End Sub Private Sub Form_Timer() On Error GoTo Error_Form_Timer intCountDown = intCountDown - 1 If intCountDown <= 0 Then Application.Quit Else Beep Me!txtMinutesToGo = intCountDown End If Exit_Form_Timer: Exit Sub Error_Form_Timer: MsgBox "An error has occurred!" & vbCrLf & vbCrLf _ & "The application will now quit.", vbCritical, "Timing Error" Resume Exit_Form_Timer End Sub |
When the form is opened, the following events occur:
The intCountDown variable is initialized to 5 (minutes) in the Form_Open subroutine.
Every minute the Form_Timer subroutine is called, 1 is subtracted from intCountDown.
If the five minutes are up, the application quits; otherwise, a beep sounds, and the unbound txtMinutesToGo TextBox control is updated for display.
Caution
When you use timer events, the system can give an error when transactions are being used. If you're performing new file tasks inside the timer event, your work could conflict with the transaction processing. You might need to close the UserLogOutMonitor form when performing transactions.
Setting the flag file isn't much tougher than looking for it. You can find the code for this routine on the cmdLogInOut command button on the ap_SystemUtilities form, attached to the OnClick event. The ap_SystemUtilities form is used for handling various system functions and should be set up with some kind of security. The code also calls some public subroutines that are used to deal with creating and removing the flag file, as Listing 26.6 shows.
The same button is used to toggle between creating the flag file and removing it. If the Dir() function comes back with the LogOut.flg file existing, the ap_LogOutRemove sub is called with the Kill command. Otherwise, you call the ap_LogOutCreate sub that uses a good old-fashioned Open command from the ancient BASIC days. The SetAttr command is used to toggle the visibility of the file before the file is deleted and after it's created.
Tip
Use the Dir() function to create a list of files in a folder. By passing a file “skeleton” with wild cards and a path, you can repeat the call to the Dir() function until it returns the empty string.
To view the syntax of the Dir() function in the Object Browser, follow these steps:
1. |
While in any module, press F2. |
2. |
Click the Object Browser toolbar button, or choose Object Browser from the View menu. |
3. |
Select VBA - VBA from the Project/Library combo box. |
4. |
Select FileSystem from the Classes list. |
5. |
Select Dir from the Members list. |
You now see the syntax for the Dir() function. You can click the question mark command button to see further help.
The DisplayLogInOut subroutine checks to see whether the LogOut.flg file exists. If it does, it toggles the Caption property on the cmdLogInOut command button, as Listing 26.7 shows.
The routines for logging out users are used throughout the rest of this chapter.
18.217.208.72