"FOR EACH"-statement i Natural

In VB the “FOR EACH”-statement iterates thru a collection of objects.

Does anybody know how to mimic that behaviour in Natural?

Regards Michael

FOR EACH ist generally just a shortcut to the explicit usage of the Count property and the Item method. In Natural you can use Count and Item to iterate through a collection:

1 #coll handle of object
1 #item handle of object
1 #c (i4)
1 #i (i4)

#c := #coll.Count
for #i := 1 to #c
send ‘Item’ to #coll with #i return #item
end-for

Kind regards, +o:-]

Sure - but what if them “item” method does NOT take an integer, but a specific value like e.g filename (which is the case for the “ifiles”-object)?

Normally a ‘correctly’ implemented Item method should support both, a numeric index and an alphanumeric key. But in the case that for a given collection only the alphanumeric key is supported, this is really bad luck :frowning: Since Natural does not have a direct counterpart to the FOR EACH construct, I see no direct way to to use that collection with Natural means alone.
Kind regards, +o:-]

This is something I have been trying to find a solution to for quite a while, Natural can access file system objects and get right down to the file collection, get the count of how many there are, but not parse the collection. My current work-around is DOS DIR command and reading the filenames from a workfile.

With all of the dynamic and X-Array options now available all we would need is a routine to return a list of names (and type? to distinguish between dir and file), then other information could be obtained directly by using other objects.

(I think) it would be a fairly simple routine to write in C or VB, but creating it as an MS dll would be the tough part for me since I don’t have access to the compilers anymore. :frowning:

For this purpose I have a small wrapper component (see attached) that takes a collection of Automation objects and provides the necessary iteration methods that can be called from Natural. Register it (regsvr32 GeneralCollection.dll) and use it in the following way:


define data
local
1 #coll handle of object
1 #filesystem handle of object
1 #folder handle of object
1 #files handle of object
1 #file handle of object
1 #i (i4)
1 #cnt(i4)
1 #path (a) dynamic
end-define
*
create object #coll of "Natural.GeneralCollection"
*
create object #filesystem
of class 'Scripting.FileSystemObject'
*
send "GetFolder" to #filesystem
with "e:\TestFolder" return #folder
*
#files := #folder.Files
#cnt := #files.Count
*
send "Attach" to #coll with #files (ad=o) /* sic (!) */
send "Next" to #coll return #file
repeat while #file ne null-handle
  #path := #file.Path
  send "Next" to #coll return #file
  write #path (al=60)
end-repeat
*
send "Reset" to #coll
send "Next" to #coll return #file
repeat while #file ne null-handle
  #path := #file.Path
  send "Next" to #coll return #file
  write #path (al=60)
end-repeat
*
end

I hope this helps. Good luck, +o:-]
GeneralCollection.zip (45.5 KB)

BenedictXVII, I gotta say, you’re wonderfull!! Did you really just whip that up this morning?

Add providing the source is also great!! I had to take a peek at it before giving it a try, I can tell I’ve been in this Natural-only environment for too long because the pointer ref/de-ref made me shudder :slight_smile:

I can only hope that your routine (or something similar) makes it into one of the future releases of Natural

Hope you don’t mind but I’m also adding an example of itterating through a collection of subfolders, exactly the same as going through the files collection but with a different object. I know quite a few other people that would also be interested in your routine, since you posted it with source I’ll assume it is OK to point them here.

Big thanks!
Chad.

define data 
local 
1 #coll handle of object 
1 #filesystem handle of object 
1 #folder handle of object
1 #folders handle of object
1 #SubFolder handle of object
1 #i (i4) 
1 #cnt(i4) 
1 #path (a) dynamic 
end-define 
* 
** *  Requires GeneralCollection.dll to parse the collections  * **
** * It needs to be registered with cmd regsvr32 GeneralCollection.dll * **
create object #coll of "Natural.GeneralCollection" 
*
create object #filesystem of class 'Scripting.FileSystemObject' 
*
send "GetFolder" to #filesystem with "C:\BBB" return #folder
send "SubFolders" To #Folder Return #Folders
*
Send "Attach" to #Coll With #Folders (AD=O)
Send "Next" To #Coll Return #SubFolder
repeat while #SubFolder ne null-handle 
  #path := #SubFolder.Path
  send "Next" to #coll return #SubFolder
  Print #path 
  Add 1 To #i
end-repeat 
Print 'Total SubFolders displayed' #i
*
end 

Works like a charm… thanx :slight_smile: