VBA Excel从GetFolder.Files返回的文件集合中获取第一个文件名

时间:2013-10-22 13:59:23

标签: excel-vba collections vba excel

我试图获取目录的第一个文件。我不在乎"首先"在这种情况下没有明确的定义,如果我每次打电话给我的子,我都不会关心。

我尝试使用:

Dim FSO As Object
Dim SourceFolder As Object

Dim FileItem As Object

Set FSO = CreateObject("Scripting.FileSystemObject")
Set SourceFolder = FSO.GetFolder(SourceFolderName)

Set FileItem = SourceFolder.Files.Item(0)

但这会返回编译器错误("无效的过程调用或参数") 你能告诉我如何做这个工作吗?

谢谢, 李

5 个答案:

答案 0 :(得分:3)

您可以使用内置的Dir函数下面是示例代码,它返回Test文件夹中找到的第一个文件名。

Sub test()

    Dim strFile As String
    strFile = Dir("D:Test\", vbNormal)

End Sub

答案 1 :(得分:2)

我认为SourceFolder.Files只接受字符串作为键,就像您在Scripting.Folders中所说的那样。我认为Santosh的答案是要走的路,但是这里是对代码的一个重大修改,它返回文件夹中的“第一个”文件:

Sub test()

Dim FSO As Object
Dim SourceFolder As Object
Dim FileItem As Object
Dim FileItemToUse As Object
Dim SourceFolderName As String
Dim i As Long

SourceFolderName = "C:\Users\dglancy\Documents\temp"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set SourceFolder = FSO.GetFolder(SourceFolderName)

For Each FileItem In SourceFolder.Files
    If i = 0 Then
        Set FileItemToUse = FileItem
        Exit For
    End If
Next FileItem

Debug.Print FileItemToUse.Name
End Sub

答案 2 :(得分:1)

VBA确实存在一个限制(我认为是一个错误或设计缺陷),其中文件系统对象的Files集合不能通过item-index编号访问,只能通过每个项目的文件路径字符串值来访问。这里发布的原始问题是关于只访问Files集合中的第一个项目,但它涉及一个常见问题,有两个合理的解决方法:创建和使用File对象元集合或File对象数组来提供索引访问Files集合。这是一个演示例程:

Sub DemoIndexedFileAccess()
    '
    'Demonstrates use of both a File object meta-collection and a File object array to provide indexed access
    'to a Folder object's Files collection.
    '
    'Note that, in both examples, the File objects being accessed refer to the same File objects as those in
    'the Folder object's Files collection.  (i.e. if one of the physical files gets renamed after the creation
    'of the Folder object's Files collection, all three sets of File objects will refer to the same, renamed
    'file.)
    '
    'IMPORTANT: This technique requires a reference to "Microsoft Scripting Runtime" be set.
    '
    '**********************************************************************************************************

    'File-selector dialog contsants for msoFileDialogFilePicker and msoFileDialogOpen:

    Const fsdCancel As Integer = 0       'File dialog Cancel button
    Const fsdAction As Integer = -1      'File dialog Action button, and its aliases...
    Const fsdOpen   As Integer = fsdAction
    Const fsdSaveAs As Integer = fsdAction
    Const fsdOK     As Integer = fsdAction

    Dim FD          As FileDialog
    Dim File        As Scripting.File
    Dim FileArr()   As Scripting.File
    Dim FileColl    As New Collection
    Dim Folder      As Scripting.Folder
    Dim FSO         As Scripting.FileSystemObject
    Dim Idx         As Integer

    'Get a folder specification from which files are to be processed

    Set FD = Application.FileDialog(msoFileDialogFolderPicker)  'Create the FolderPicker dialog object
    With FD
        .Title = "Select Folder Of Files To Be Processed"
        .InitialFileName = CurDir

        If .Show <> fsdOK Then Exit Sub
    End With

    'Use the folder specification to create a Folder object.

    Set FSO = New Scripting.FileSystemObject
    Set Folder = FSO.GetFolder(FD.SelectedItems(1))

    'A Folder object's Files collection can't be accessed by item-index number (only by each item's file-path
    'string value), so either...

    '1. Create a generic "meta-collection" that replicates the Files collection's File objects, which allows
    '   access by collection-item index:

        For Each File In Folder.Files
            FileColl.Add File
        Next File

        '"Process" the files in (collection) index order

        For Idx = 1 To FileColl.Count
            Debug.Print "Meta-Collection: " & FileColl(Idx).Name
        Next Idx

    '2. Or, create an array of File objects that refer to the Files collection's File objects, which allows
    '   access by array index:

        ReDim FileArr(1 To Folder.Files.Count)

        Idx = 1
        For Each File In Folder.Files
            Set FileArr(Idx) = File
            Idx = Idx + 1
        Next File

        '"Process" the files in (array) index order

        For Idx = LBound(FileArr) To UBound(FileArr)
            Debug.Print "File Object Array: " & FileArr(Idx).Name
        Next Idx
End Sub

答案 3 :(得分:0)

我用这种方式解决问题:

Private Function GetFirstFile(StrDrive as String) As String

    'Var Declarations
        Dim Fso As Object, Drive As Object, F As File

    'Create a reference to File System Object and Drive
        Set Fso = New Scripting.FileSystemObject
        Set Drive = Fso.GetDrive(StrDrive)
        If Not Drive Is Nothing Then
            'Scan files in RootFolder.files property of then drive object
            For Each F In Drive.RootFolder.Files
                Exit For
            Next
            'if there are any file, return the first an get then name
            If Not F Is Nothing Then FirstFile = F.Name: Set F = Nothing
            Set Drive = Nothing
        End If
        Set Fso = Nothing

End Function

不要忘记在项目中添加对Microsoft Scripting Runtime的引用 它对我有用......我希望这能帮到你们。

答案 4 :(得分:0)

为什么不只使用一种功能来遍历文件夹中的文件,直到获得所需的文件?假设您正在使用上面其他文章中详细介绍的fso,只需传递文件夹和所需文件的索引,它可能是#1或该文件夹中的任何其他文件。

Function GetFile(oFolder As Folder, Index As Long) As File
Dim Count As Long
Dim oFile As File
  Count = 0
  For Each oFile In oFolder.Files
    Count = Count + 1
    If Count = Index Then
      Set GetFile = oFile
      Exit Function
    End If
  Next oFile
End Function