3

我正在尝试获取目录的第一个文件。我不在乎在这种情况下“第一”的定义不明确,我也不在乎每次调用我的 sub 时是否会得到一个不同的文件。

我尝试使用:

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)

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

谢谢,李

4

5 回答 5

4

您可以使用内置Dir函数

下面是返回从 Test 文件夹中找到的第一个文件名称的示例代码。

Sub test()

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

End Sub
于 2013-10-22T14:11:30.297 回答
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
于 2013-10-22T17:11:21.310 回答
1

确实,VBA 有一个限制(我认为是错误或设计缺陷),其中文件系统对象的 Files 集合不能通过项目索引号访问,只能通过每个项目的文件路径字符串值访问。此处发布的原始问题是关于仅访问 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
于 2014-09-23T19:11:34.060 回答
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 的引用它对我有用......我希望这对你们有帮助。

于 2015-02-24T09:27:58.293 回答
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
于 2018-07-02T22:13:00.747 回答