Sys(2015) is a handy VFP function which returns a value unique to that session of VFP, unless you call it in a tight loop on a fast machine. The help file says "Calling SYS(2015) more than once during the same millisecond interval returns a unique character string." Tests on a Pentium @ 2.3 GHz have demonstrated that this is no longer the case. With that caveat in mind, it's very handy for generating a unique value for something which is not going to be used outside of that VFP session, such as a name for an object in a collection:
If there was a problem with sequential calls to SYS(2015) producing the same result, they are gone in version 9 sp2 on a MUCH faster processor. -- Ben Creighton
LOCAL I, loMyObject, loCollection
loCollection = CreateObject("Collection")
FOR I = 1 TO 10
loMyObject = CreateObject("myObject")
DEFINE CLASS myObject AS Custom
cUniqueID = Null
IF Vartype(THIS.cUniqueID) != "C"
THIS.cUniqueID = Sys(2015)
FUNCTION RemoveObject(toObject, toCollection)
* Easy and fast:
* Hard and slow (and fails silently if the object isn't in the collection):
FOR I = 1 TO m.toCollection.Count
IF m.toCollection.Item(m.I) == m.toObject
The advantage to that approach is that you don't have to iterate over the collection to find the index of the object to remove it, which can have significant performance implications.
This function is also handy for things like temporary file names, though you have to check to make sure the file doesn't already exist, in that case.
Never, never assume that you won't get lucky with this function and generate two of the same "unique" name if you're dealing with two different VFP sessions (multiuser). Inevitably, you won't during testing, and your clients will.
My experience has shown no issues around using SYS(2015) for many purposes including generating Primary Keys as the default value. I have limited this to software running locally on one computer only. Otherwise, I have found using a new GUID function as a wonderful way to generate keys. The only drawback so far is the keys are large and difficult to work with. However, they are unique and easily passed to SQL Server.
lc_guid_return as String, ;
lc_buffer as String, ;
ln_result as Integer, ;
lc_GUID as String
DECLARE Integer CoCreateGuid ;
IN ole32.dll ;
lc_GUID = SPACE(16) && 16 Byte = 128 Bit
ln_result = CoCreateGuid(@lc_GUID)
IF tn_mode = 0
lc_guid_return = lc_GUID
lc_buffer = SPACE(78)
DECLARE Integer StringFromGUID2 ;
IN ole32.dll ;
String pguid, ;
String @lpszBuffer, ;
ln_result = StringFromGUID2(lc_GUID,@lc_buffer,LEN(lc_buffer)/2)
lc_guid_return = STRCONV((LEFT(lc_buffer,(ln_result-1)*2)),6)
I also have found issues working with SYS(2015), especially on older versions of FoxPro. Here is a simple workaround.
DO WHILE m.Result=SYS(2015)
Contributors: Peter Crabtree, Jim Wiggins, Loris Antonangeli (problem on fast machine)
Category VFP Functions