3

If there is only one file in a folder, can I pick it up without knowing its name or iterating through the files in the folder?

(The code is VBS, but it could be anything, the FSO is the interesting part here.)

This didn't work for me:

dim fso
set fso = CreateObject("Scripting.FileSystemObject")
dim myFolder
Set myFolder = fso.getFolder("E:\test")
Dim myfiles
Set myfiles = myFolder.Files

WScript.Echo myfiles.Item(0).Path

Neither did WScript.Echo myfiles(0).Path work. (Index 0,1 tested, both fail.)

Using a for each to get just one file seems a bit of an overkill. Also, am I not supposed to be able to somehow iterate with a simple For loop, not a For Each? So there must be indexes... I just can't seem to find them.

Braiam
  • 1
  • 11
  • 47
  • 78
vacip
  • 5,246
  • 2
  • 26
  • 54

3 Answers3

7

No, you can't pick the file without knowing its name or iterating over the files in the folder, at least not with a FileSystemObject instance. As documented the Item property of the Files collection requires the name of an item, not its index:

Item Property (Files)

Gets the specified item for in a Files object

Syntax

object.Item(key)[ = newitem]

Arguments

object
Required. The name of a File object.

spec
Required. The name of the item.

Not every collection allows access by index.

If you're looking for a magic trick you could do something like this:

dir = "C:\your\folder"

Set sh = CreateObject("WScript.Shell")
Set ex = sh.Exec("cmd /c dir /b """ & dir & """")
While ex.Status = 0 : WScript.Sleep 100 : Wend

filename = Split(ex.StdOut.ReadAll, vbNewLine)(0)

Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(fso.JoinPath(dir, filename))

However, that approach is neither very elegant nor very robust, and I fail to see its advantage over something like

dir = "C:\your\folder"
Set fso = CreateObject("Scripting.FileSystemObject")
For Each item In fso.GetFolder(dir).Files
  Set f = item
Next
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Wow. So I can't even use a simple For loop, only For Each. Thanks. I'll leave this open for a while, maybe someone has a magic trick. – vacip Jan 01 '16 at 23:14
3

It's possible by using Shell objects, just like you thought.

dim shellApp
set shellApp = CreateObject("Shell.Application")
dim myFolder
Set myFolder = shellApp.NameSpace("E:\test")
Dim myfiles
Set myfiles = myFolder.Items 'also contains subfolders

WScript.Echo myfiles.Item(0).Path

'and for loop
Dim i
For i = 0 To myfiles.Count - 1
    WScript.Echo myfiles.Item(i).Path
Next
Kul-Tigin
  • 16,728
  • 1
  • 35
  • 64
0

If you're absolutely sure that there's only one file in the folder, a single line of code should do it for you:

Set MyFile = FSO.GetFile("E:\test\" & Dir("E:\test\"))

...at least it works for me in Excel VBA.

Noam Hacker
  • 4,671
  • 7
  • 34
  • 55
  • Very good idea! Unfortunately, the `Dir` command doesn't work like this in VBS. Thanks for the idea though, nice. :) – vacip Feb 16 '16 at 21:08