Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VBA Excel从GetFolder.files返回的文件集合中获取第一个文件名_Excel_Collections_Vba - Fatal编程技术网

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

VBA Excel从GetFolder.files返回的文件集合中获取第一个文件名,excel,collections,vba,Excel,Collections,Vba,我正在尝试获取目录的第一个文件。我不在乎“first”在本例中没有很好的定义,我也不在乎每次调用sub时是否会得到不同的文件 我尝试使用: Dim FSO As Object Dim SourceFolder As Object Dim FileItem As Object Set FSO = CreateObject("Scripting.FileSystemObject") Set SourceFolder = FSO.GetFolder(SourceFolderName) Set F

我正在尝试获取目录的第一个文件。我不在乎“first”在本例中没有很好的定义,我也不在乎每次调用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)
但这将返回一个编译器错误(“无效的过程调用或参数”) 你能告诉我怎么做吗

谢谢,
Li

您可以使用bulit in
Dir
功能

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

Sub test()

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

End Sub

在我看来,它类似于
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

的确,VBA有一个限制(我认为这是一个bug或设计缺陷),文件系统对象的文件集合不能通过项索引号访问,只能通过每个项的文件路径字符串值访问。这里发布的原始问题是关于仅访问文件集合中的第一项,但它涉及到一个一般问题,对此有两个合理的解决方法:创建和使用文件对象元集合或文件对象数组来提供对文件集合的索引访问。下面是一个演示例程:

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
子DemoIndexedFileAccess()
'
'演示如何使用文件对象元集合和文件对象数组来提供索引访问
'到文件夹对象的文件集合。
'
'请注意,在这两个示例中,正在访问的文件对象所指的文件对象与中的文件对象相同
'文件夹对象的文件集合。(即,如果其中一个物理文件在创建后被重命名
'文件夹对象的“文件”集合中,所有三组文件对象都将引用相同的重命名文件
'文件。)
'
重要提示:此技术需要设置对“Microsoft脚本运行时”的引用。
'
'**********************************************************************************************************
'msoFileDialogFilePicker和msoFileDialogOpen的文件选择器对话框contsants:
Const fsdCancel As Integer=0“文件对话框取消”按钮
Const fsdAction As Integer=-1'文件对话框操作按钮及其别名。。。
常量fsdOpen为整数=fsdAction
常量fsdSaveAs为整数=fsdAction
常量fsdOK为整数=fsdAction
将FD设置为文件对话框
将文件设置为脚本.File
Dim FileArr()作为脚本.File
Dim FileColl作为新集合
将文件夹设置为脚本。文件夹
将FSO设置为Scripting.FileSystemObject
将Idx设置为整数
'获取要从中处理文件的文件夹规范
设置FD=Application.FileDialog(msoFileDialogFolderPicker)'创建FolderPicker对话框对象
有FD
.Title=“选择要处理的文件的文件夹”
.InitialFileName=CurDir
如果。显示fsdOK,则退出Sub
以
'使用文件夹规范创建文件夹对象。
Set FSO=New Scripting.FileSystemObject
Set Folder=FSO.GetFolder(FD.SelectedItems(1))
'文件夹对象的文件集合无法通过项目索引号(仅通过每个项目的文件路径)访问
'字符串值),因此。。。
'1.创建一个通用的“元集合”,用于复制文件集合的文件对象,这允许
'按集合项索引访问:
对于文件夹.Files中的每个文件
添加文件
下一个文件
'按(集合)索引顺序“处理”文件
对于Idx=1到FileColl.Count
Debug.Print“Meta-Collection:&FileColl(Idx).Name
下一个Idx
'2.或者,创建引用文件集合的文件对象的文件对象数组,该数组允许
'按数组索引访问:
ReDim FileArr(1到Folder.Files.Count)
Idx=1
对于文件夹.Files中的每个文件
设置FileArr(Idx)=文件
Idx=Idx+1
下一个文件
'按(数组)索引顺序“处理”文件
对于Idx=LBound(FileArr)到UBound(FileArr)
Debug.Print“文件对象数组:”&FileArr(Idx).Name
下一个Idx
端接头

我用以下方法解决问题:

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脚本运行时的引用
它对我有用。。。我希望这对你们有帮助

为什么不使用函数遍历文件夹中的文件,直到找到所需的文件?假设您正在使用上面其他文章中详述的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

你试过第1项了吗?我认为在一个集合中,第一个索引是1,而不是10@Octavio:是的,我收到了相同的错误
GetFolder
方法接受一个字符串,其中as
SourceFolder
被定义为object。@Santosh请参阅上面的代码,GetFolder获取“sourceFolderName”,这是一个字符串。。。对不起,我忘了添加它的声明。我调试后发现错误出现在最后一个代码行上!我忽略了变量名。