FoxPro Programming
Gather NAME oFileStructureCollection
Gravatar is a globally recognized avatar based on your email address. Gather NAME oFileStructureCollection
  Harvey Mushman
  All
  Jan 3, 2020 @ 06:44pm

What am I missing ?

lcBasePath='x:\data\'
 
oFileStructureCollection=CREATEOBJECT('Collection')
USE lcBasePath + 'users' && 30 fields
COPY STRUCTURE EXTENDED TO tFileStru
USE ('tFileStru') EXCLUSIVE
SELECT('tFileStru')

SCAN
 SCATTER NAME oXFld memo
 oFileStructureCollection.Add(oXFld)
 ? oXFld.Field_Name
ENDSCAN
ZAP
FOR EACH oFld IN oFileStructureCollection  && 30 items
 ? oFld.Field_Name
 APPEND BLANK
 GATHER NAME oFld MEMO
ENDFOR 

? RECCOUNT() && 30

All of the records were added back in after the ZAP by looping over APPEND BLANK, yet none of the original field values were written back from the collection object "oFld".

I'm stumped?

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Rick Strahl
  Harvey Mushman
  Jan 3, 2020 @ 11:08pm

Does the ? oFld.Field_Name value show inside the FOR EACH? You should also write out the value of the field after the GATHER and see if it made it at that point.

Other than the values not actually being in the collection objects, I can't see a reason why this shouldn't work.

FWIW, you can use CursorToCollection() and CollectionToCursor() to pretty much do this without manually writing the conversion code.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Harvey Mushman
  Rick Strahl
  Jan 4, 2020 @ 07:01am

If you run my code, (just point at any dbf file) and see if the "tFileStru" table is filled in, I could rule out it is something to do with my environment.

I know about CursorToCollection() and CollectionToCursor but I'm puzzled by why this code does not work.

After additional testing and adding a question mark after the GATHER on the oFld.Field_Name property, the generated table showed Field_Name present. But none of the other fields existed. Additional testing, made oFld.Field_Type=oFld.Field_Type and it now was written into the table as well.

Just for the hell of it, I added an AMEMBERS(laFlds,oFld) before the APPEND BLANK. The return value from AMEMBERS is equal to zero. Yet in the Debugger, I see all the properties of oFld. Then just to try and understand better, I moved the AMEMBERS to after oFld.Field_Type=oFld.Field_Type. Guess what, AMEMBERS returned a property count of one!

Seems like the collection has a scope issue with SCATTER or the Collection.ADD() since AMEMBERS and GATHER both don't see the values until after an operation like x=x is preformed.

Can this be an undocumented feature of VFP ?

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Harvey Mushman
  Harvey Mushman
  Jan 4, 2020 @ 07:09am

Interesting... FOR EACH causes the problem!

The following works:

  
CLEAR 
lcBasePath='c:\data\'
 
oFileStructureCollection=CREATEOBJECT('Collection')
USE lcBasePath + 'users' 
COPY STRUCTURE EXTENDED TO tFileStru
USE ('tFileStru') EXCLUSIVE
SELECT('tFileStru')
 
SCAN
 SCATTER NAME oXFld memo
 oFileStructureCollection.Add(oXFld)
 * ? 'add: ' + oXFld.Field_Name
ENDSCAN
ZAP
FOR i = 1 TO oFileStructureCollection.Count
 oFld=oFileStructureCollection.Item(i)
 * ? 'before: '+ oFld.Field_Name
 * lnMembers=AMEMBERS(laFlds,oFld)
 * ? 'before: '+ oFld.Field_Name
 * ? 'before: '+ oFld.Field_type
 APPEND BLANK
 GATHER NAME oFld
 * ? 'after: '+ oFld.Field_Name
 * ? 'after: '+ oFld.Field_type
ENDFOR 

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Tore Bleken
  Harvey Mushman
  Jan 4, 2020 @ 08:04am

If you add FoxObject to the For Each expression, it might work. IOW

FOR EACH oFld IN oFileStructureCollection FoxObject
Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Harvey Mushman
  Tore Bleken
  Jan 4, 2020 @ 08:45am

WOW - That works!

FOR EACH oFld IN oFileStructureCollection FoxObject

Un-FU... real!!

Thanks

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Tore Bleken
  Harvey Mushman
  Jan 4, 2020 @ 10:27am

Good to know, and you're welcome.

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Rick Strahl
  Harvey Mushman
  Jan 5, 2020 @ 12:01pm

Yeah you should always use FOXOBJECT when using FOR EACH except when using COM objects.

This is one of those FoxPro late stage langugae brain farts (like XMLTOCURSOR and XMLADAPTER/SQLADAPTER crazy syntax conventions) that make no sense, but at least the workaround is easy. If I recall FOR EACH uses COM objects, and FOXOBJECT forces FoxPro objects. Besides being more reliable it's MUCH faster.

FWIW, I prefer to use array style syntax with collections precisely because of that and also because I can swap with wwCollection and wwNameValueCollection which don't work with FOR EACH as that's a special concept designed only to work against FoxPro collections or COM collections. Just another FoxPro language afterthought.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Gather NAME oFileStructureCollection
  Harvey Mushman
  Rick Strahl
  Jan 6, 2020 @ 08:49am

Thanks... I was so puzzled by this and although there are several work-a-rounds, I keep trying to figure it out knowing there was an answer!

© 1996-2020