I am trying to access a series of nested collections and getting a runtime error 5 when I do so... the nested collection is a series of folders and files assembled using the FileSystemObject.
I cannot seem to place a screenshot here but from the VB6 debugger I have a watch set on a variable called FSFolder which is defined as an object, and FSFolder has collections in it for the Drives, Subfolders and Files, and under subFolders there is another subFolder and File collection nested inside it.
When I attempt to get a count of the subfolders at the top level, there is no problem; lFolderIndex = FSfolder.subfolders.count and it returns the correct information (37 folders), however if I attempt to do lDirCount = FSfolder.SubFolders(lFolderIndex).Files.Count I get runtime error 5 Invalid procedure call or argument!
Even if I replace the lFolderIndex with a specific collection item number it gives me the same error. In the watch window I have expanded FSfolder and I see the nested collection subfolders and if I expand subfolders I see the Files collection and can look at each item. Why cant I access the elements programmatically? What am I doing wrong?
check the value of lFolderIndex... is it 37 when the error happens? If so, that's the problem... there may be 37 folders, but the colleciton goes from 0 to count-1... or 0 to 36...
See if this change works for you:
lFolderIndex = FSfolder.subfolders.count -1
check the value of lFolderIndex... is it 37 when the error happens? If so, that's the problem... there may be 37 folders, but the colleciton goes from 0 to count-1... or 0 to 36...
See if this change works for you:
lFolderIndex = FSfolder.subfolders.count -1
-tg
Based on the error message returned you would think that, however looking at the items in the collection, they are 1 based and the highest # (37 in this case) is valid and has information in it that I am after (e.g. the filename and size and other info).
Based on the error message returned you would think that, however looking at the items in the collection, they are 1 based and the highest # (37 in this case) is valid and has information in it that I am after (e.g. the filename and size and other info).
I figured out how to get the screenshot posted; The example here shows element (item) 1, but it does go to 37... just didnt want to make the screenshot too large.
What I am trying to do is work backward through the collections. The For/Next loop does not allow that so I need get the total and step -1 through the list.
It may say item 37.... but that's NOT the index number... it says the count is 37... that means the indexes run from 0 to 36.
Just try the change I suggested (by adding -1 to the end of the .Count) and see if it works. If it doesn't say so...
For/Next does allow backwards step... it's a For Each that doesn't - yes I'm being specific... there's a reason... I can just see posts following trying to prove that part wrong. Annnnyways... try the .Count -1 ... at this point it isn't going to hurt... at best, it's going to work. that also means your For/NExt needs to go down to 0 .... OOOOrrrrr....
Work it like this:
Code:
lFolderIndex = FSfolder.subfolders.count
For someCount as Integer = lFolderIndex to 1 Step -1
lDirCount = FSfolder.SubFolders(someCount -1).Files.Count
Next
Your call... you can either do the math once, when you get the count in the first place... or you can do it on each iteration of the loop.... either way, the collection goes from 0 to count-1
It may say item 37.... but that's NOT the index number... it says the count is 37... that means the indexes run from 0 to 36.
Just try the change I suggested (by adding -1 to the end of the .Count) and see if it works. If it doesn't say so...
For/Next does allow backwards step... it's a For Each that doesn't - yes I'm being specific... there's a reason... I can just see posts following trying to prove that part wrong. Annnnyways... try the .Count -1 ... at this point it isn't going to hurt... at best, it's going to work. that also means your For/NExt needs to go down to 0 .... OOOOrrrrr....
Work it like this:
Code:
lFolderIndex = FSfolder.subfolders.count
For someCount as Integer = lFolderIndex to 1 Step -1
lDirCount = FSfolder.SubFolders(someCount -1).Files.Count
Next
Your call... you can either do the math once, when you get the count in the first place... or you can do it on each iteration of the loop.... either way, the collection goes from 0 to count-1
-tg
You are right about my original post, I typed the For/Next loop wrong... I meant to type For/Each loop as not allowing backward iteration... You are also right about everyone trying to counter it
At any rate, I understand where you are coming from and I do understand how to iterate through an array or collection, so it is not foreign to me.. I tried as you suggested for just for the sake of trying it but there is no difference... If I set the index to 0, or 37, or 5, or 10, it doesn't matter... I still get same error...
The first level works... I can call lFolderIndex = FSfolder.subfolders.count and get the correct number, but if I attempt to access any of the subitems that is when I get the error;
If you look at my screenshot, the following line should return "00000001";
stempstr = FSFolder.subFolders(1).name but I get the runtime error 5.
huh... ok... can you post the actual code... doesn't necessarily need to be everything... but the important bits of it... where you're getting the collection, the count, then your loop... clearly there's something amiss.
huh... ok... can you post the actual code... doesn't necessarily need to be everything... but the important bits of it... where you're getting the collection, the count, then your loop... clearly there's something amiss.
-tg
Its prettty simple what I am doing.
I have;
dim FS as FileSystemObject (and of course a reference to it)
dim FSFolder as object
dim sTempstr as String
sTempstr = "Whatever path I want to pass it"
set FSFolder = fs.GetFolder(sTempstr) ' A method of the base FSO
This returns all of the sTempstr folder plus any files contained in it, and its subfolders and files, plus their sub-folders and files underneath that.
Once you have that, try to access any of the info from FSFolder.subfolders(index).files.count or path, or name or any of the fields.... you'll see them in the watch window.
I guess I am doing something wrong... I dont see it!
Last edited by GaryBouchard; Feb 7th, 2011 at 03:58 PM.
Reason: Fully qualified
yes, yes, I know that much, that's why I wanted to see ACTUALL code... not a mock up approximation of what you're doing...
OH... woah... "as OBJECT" ???? Oh.... that is your issue... you should be using the actual type... okay.. hang on... Ahh... oh carp... I'm just now noticing this is VB6.. I was going to suggest using the DirectroyInfo object instead, but that's .NET....
OK... I'm going to have to work from memory and put on my wayback hat... I'll get back to it this evening unless someone else beats me to it...
SubFolders is a collection, not an array. The keys to the collection are folder name strings, not indexes. The Watch window indexes them because it doesn't know what else to do, but they're not really indexed. You can iterate over the collection with the For Each syntax. You're getting an invalid argument error because you're passing an invalid argument--a number that's not a key to an element of the collection.
For instance, if sTempstr points to a folder with a subfolder named "MyFolder", the following calls succeed:
Code:
MsgBox FSFolder.SubFolders("MyFolder").Files.Count
For Each SFolder in FSFolder.SubFolders
MsgBox SFolder.Files.Count
Next
(Saving you the trouble of remembering how stupid VB6 was, techgnome .)
The time you enjoy wasting is not wasted time. Bertrand Russell