RETURN fh > 0 AND FCLOSE(fh)This way the close does not happen until the very last moment. And because VFP evaluates expressions from left to right and there is an AND, if the file was not opened then the FCLOSE() will not be attempted.
IF fUse( "MyTable", "EXCLUSIVE", "Path", "Alias", "Order", etc. ) *- Ok to PACK, rebuild Indexes, etc. ELSE *- Inform User if interactive, or write to log file if batch (unattended). ENDIF #DEFINE CURRENT_LOCK_STATUS 2011 #DEFINE DEFAULT_ERROR_HANDLER DO SysError WITH ERROR(), MESSAGE(), etc. ***************************************************** FUNCTION fUse( cTable, cMode, cPath, cAlias, cOrder ) ***************************************************** *- cTable is the only mandatory parameter, all others are optional. *- cMode : If specified MUST be one of "SHARED" or "EXCLUSIVE", defaults to "SHARED". *- cPath : Relative, Aabsolute, or UNC. *- cAlias : Self explanatory. *- cOrder : Index tag name. *- Returns empty string if successful, otherwise returns an error message, which *- always begins with "ERROR: fUse() " *- To increase the robustness of this function, all of the parameters *- should be checked for correct data type (if passed in). LOCAL cActualDbf, cOpenResult, cCurrentLockStatus, cUseArguments IF EMPTY( cTable ) *- If running unattended then this might be the ideal point to record *- failure to a log file. RETURN "ERROR: fUse() cTable not specified." ENDIF IF EMPTY( cMode ) *- Assign default value, cMode = "SHARED" ENDIF IF USED( cTable ) *- Table is already open. IF NOT EMPTY( cAlias ) AND USED( cAlias ) *- Dang! Table is open and alias is also in use. So close both and *- re-open table with the desired alias. USE IN (cTable) USE IN (cAlias) ELSE *- Table is open and alias has not been specified, so do not need *- to do anything further. SELECT (cTable) RETURN "" ENDIF ENDIF IF NOT EMPTY( cAlias ) AND USED( cAlias ) *- Alias has been specifed but is already in use, so verify that table *- is correct - since it is possible that the table might be other than *- the one specified in cTable. cActualDbf = DBF( cAlias ) cActualDbf = SUBSTR( cActualDbf, RAT( "\", cActualDbf ) + 1 ) IF cActualDbf # cTable = ".DBF" *- Table is already open with the desired alias, but what about cMode? SELECT (cAlias) IF EMPTY( cMode ) *- Do not need to do anything else. RETURN "" ELSE *- Determine mode that the table is currently opened with. cCurrentLockStatus = UPPER( SYS( CURRENT_LOCK_STATUS )) == "EXCLUSIVE" IF cCurrentLockStatus = cMode *- Do not need to do anything. RETURN "" ENDIF *- cMode is not the same as the cCurrentLockStatus, so need to close and *- re-open the table with the desired cMode. USE IN (cAlias) ENDIF ELSE *- Need to close cAlias and open cTable USE IN (cAlias) ENDIF ELSE *- Either the alias was not specified, or it is not currently in use, *- either way nothing needs to happen here, so this ELSE code could be *- deleted. ENDIF *- To get here, either the table is not already open, or if it was open it has *- been closed because either the cAlias was incorrect or the cMode. *- Fabricate USE arguments. IF NOT EMPTY( cPath ) cPath = ADDBS( cPath ) ENDIF cUseArguments = IIF( NOT EMPTY( cPath ), cPath, "" ) ; + cTable ; + IIF( NOT EMPTY( cAlias ), " AS " + cAlias, "" ) ; + " " + cMode ; + " IN 0" cOpenResult = "" ON ERROR cOpenResult = "ERROR: fUse() " + MESSAGE() USE &cUseArguments. *- Restore default error handler. ON ERROR DEFAULT_ERROR_HANDLER IF EMPTY( cOpenResult ) *- Table was opened sucessfully. IF EMPTY( cAlias ) SELECT (cTable) ELSE SELECT (cAlias) ENDIF IF NOT EMPTY( cOrder ) SET ORDER TO (cOrder) ENDIF ENDIF RETURN cOpenResult ENDFUNC && fUse( cTable, cMode, cPath, cAlias, cOrder ).