************************************************************ * --- Nextkey * get the next primary key value * for any table * Parameters: lcKeyName is the name of the field/table for * which the next PK is required. * Returns: 0 on any error * liReturn - the value of the next key for the required table. * * * If you create a global variable called giPrimaryKey in your main application * This routine will store to it the last primary key it has generated. * This is useful since you will be able to populate a view with the correct pk field for * a new record after a TABLEUPDATE() without having to select out all the records again * Routine has been modified to ensure the right NextKey table is updated in all circumstances *********************** Function NextKey *********************** Lparameters lcKeyName * --- check if parameter passed If TYPE("lcKeyName")<>"C" * changed the 2 lines below because I want a crash here if there is a problem *WAIT WINDOW 'Invalid parameter: Not a character string passed' *RETURN 0 Error 'A Valid Parameter was not sent to NextKey' Endif TYPE("lcKeyName")<>"C" lcKeyName=UPPER(ALLTRIM(lcKeyName)) * --- Save environment Local lcAlias, liReturn,lcTablePath,lcTabledbc,lcNextKeyDBC lcAlias=ALIAS() lcTablePath=justpath(dbf(lcAlias)) lcTabledbc=cursorgetprop('database',lcAlias) && identify owning DBC for the table * --- Open table of next keys * If its open then keep it open for speed but do a double check later to make sure its the right table If NOT USED("NextKey") Select 0 Use (FORCEPATH('Nextkey.dbf', lcTablePath)) ALIAS NextKey Else Select NextKey Endif not used("nextkey") lcNextKeyDBC=cursorgetprop('database','NextKey') && identify owning DBC for the nextkeytable * check that the NextKey table lives in the same folder as the table the key is being generated for * and also belongs to the same database container (better safe than sorry) * This is just in case a Nextkey table was left open if lcTablePath # justpath(dbf('nextkey')) or lcNextKeyDBC # lcTabledbc&& oops wrong nextkey table being used somehow use in nextkey * --- Oen table of next keys Use (FORCEPATH('Nextkey.dbf', lcTablePath)) ALIAS NextKey lcNextKeyDBC=cursorgetprop('database','NextKey') && identify owning DBC for the nextkeytable endif if lcTablePath # justpath(dbf('nextkey')) or lcNextKeyDBC # lcTabledbc && still wrong table so give up and crash ERROR 'Attempt to update a Nextkey table from a different folder or dbc to currently selected table' endif * --- Find the record for this table * LOCATE FOR cKeyName=lcKeyName && replaced this with the line below because * similar table names would confuse it with very bad results ie. INV and INVOICE Locate FOR alltrim(cKeyName)==lcKeyName If NOT FOUND() * --- No record for this table - create one *APPEND BLANK *REPLACE iNextKey WITH 1 *REPLACE cKeyName WITH lcKeyName Wait WINDOW '******** NO KEY FOUND FOR '+alltrim(cKeyName)+' so creating an new value starting at 1 *********' Insert into NextKey (iNextKey,cKeyName) VALUES (1,lcKeyName) liReturn=0 Endif not found() lnCounter=0 * --- Lock this record Do WHILE NOT RLOCK() * --- a short delay to give the locking user a chance to complete lnCounter=lnCounter+1 If lnCounter>25 Error 'Unable to get a lock on the Nextkey Table' Endif Inkey(0.2,"H") *wait window '' timeout .2 Enddo while not rlock() * --- Get the PK *liReturn=iNextKey giPrimaryKey=iNextKey Replace iNextKey WITH iNextKey+1 Unlock * --- Restore environment If NOT EMPTY(lcAlias) Select(lcAlias) Else Select 0 Endif * --- Return the NextKey *!* IF glindev *!* wait window 'NEXTKEY '+lcKeyName+' '+trans(giPrimaryKey) *!* endif Return giPrimaryKey >