Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DBUSED function

Status
Not open for further replies.

MForrest

Programmer
Jun 9, 2003
85
0
0
GB
Hi all has anyone any info about the dbused function? I have checked out the basic info on my help menu but what I would like to know if I can use the dbused function to check if the database within my application is used by another networked user of their application.

Im am using the following code within the start program of my application, I do a check to see if I can get exclusive use of the table delivery_details, if I can I then pack the file to remove all deleted records, as so many users create and delete delivery notes I want to pack the file where possible when no other users are using the application.

The code I am using is as follows:
if !dbused('poem')
open database poem excl
use delivery_details excl in 0
pack
close databases all
endif

This code works fine if I can get exclusive use of the delivery_details table when only one user is using the system. What happens when a second user opens there application is I get the message 'File access is denied'
if the user is to press ignore the user can enter the system and view the shared data as normal.

What I suspect is that the line "if !dbused('poem')" is being carried out though another user is using the dbase 'poem' and that it only checks if the current system being run has the poem database open. Does anyone know if my suspicions are right or if Iam just going about this wrong.

Trying not to lose faith

Cheers, Michelle
 
Michelle,

The DBUSED() function doesn't look at the actual dbc file, it only looks through the list of open databases to see if the one specified is there, so that's why it works even if you have opened the database exclusively.

By the way, you don't need to open the database exclusively in order to open a table exclusively.

I would suggest that you have a test in your main program to see if the database can be opened. If you have VFP8 you can enclose it in the new TRY...CATCH syntax, otherwise you can do something like:
Code:
PreviousError = ON("ERROR")
ON ERROR ErrorNum = ERROR()
OPEN DATABASE poem
IF ErrorNum <> 0
    MESSAGEBOX("Sorry, the application is not available at the moment. Please try again in a few minutes")
    QUIT
ENDIF
ON ERROR &PreviousError


Hope that helps,

Stewart
PS If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Thanks for your help stuart, it helps to know that the dbused function checks to see if the tables within the database are used rather than me using it to check if the database is actually being used within another application.

I have therefore gone back to what I originally coded, checking to see if the actual table 'delivery_details' is used and if it is then not to try get exclusive use and try perform the packing of the file.

I have found that the USED() function is no good for what I am trying to achieve either. I performed a test having two applications running which share the same database, though 1 application was running thus using the delivery_details table, on opening the second application the code was run and still tried to get exclusive use of the delivery_details table and pack it therfore not seeing the delivery_details table as used within the other application.

I tried using your example code to track the error which I feel ignores the point of using the used() function, though I can track the error and exit the program I still get the error message displayed to the screen. Any more ideas why Used() is not working?
 
Sorry Michelle, I think my reply has misled you. The DBUSED() function checks to see what databases are open, not which tables.

You say
I have therefore gone back to what I originally coded, checking to see if the actual table 'delivery_details' is used and if it is then not to try get exclusive use and try perform the packing of the file.

As you've found, USED() doesn't look at the actual file on disk, it only looks within the session of VFP to see if the table has already be opened by you.

I think what you want to use is FOPEN(cFileName, 12) which tries to open cfilename for exclusive read/write access (that's what the second parameter means).

I use it as follows...
Code:
fileinuse = FOPEN(delivery_details,12)
IF FileInUse > -1
  FCLOSE(FileInUse)
  USE delivery_details EXCLUSIVE
  PACK
  USE
ELSE
  MESSAGEBOX("Some message")
ENDIF

If the file has been opened by another user, FOPEN will return -1, otherwise it returns a number greater than 0 (a 'handle' number), that means it was available. You have to then close it because FOPEN is a low-level function which means that it won't now be available to VFP! This sounds complicated but it is very fast.

Does that make sense? Do reply if not. I'm going home now but I'll look in again on Monday.


Hope that helps,

Stewart
PS If you want to get the best response to a question, please check out FAQ184-2483 first.
 
Another method to determine if you have exclusive access to a file is to try to rename it to itself. I've developled the following function that does just that...

*********************
FUNCTION is_exclusive
*********************
LPARAMETERS tcfile
LOCAL lcOnError, llExclusive
lcOnError = ON("ERROR")
llExclusive = .T.
ON ERROR llExclusive = .F.
RENAME (tcFile) TO (tcFile) && if we can't rename the file to itself, then it is already in use by another user
ON ERROR &lcOnError.
RETURN llExclusive


Steve
 
Hi Michelle,
Would this work for you?
Code:
LOCAL lnHdl, lcFile
lcFile = "MyTable.dbf"
lnHdl = FOPEN(lcFile)
IF lnHdl = -1
   * File is in use
ELSE
   FCLOSE(lnHdl)
   * File is not in use
ENDIF
Regards,

Mike
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top