访问已归档文件夹中的子目录

时间:2015-01-12 14:45:01

标签: vba zip archive

早上好/下午/晚上/午夜,

这已成为一个越来越令人沮丧的问题 - 48小时后,我看了我能找到的每篇文章。我首先要描述问题及其目标,然后是我到目前为止所做的事情。

目的

有一个带有TB级存档(压缩)文件夹的驱动器。在每个压缩文件夹中,文件夹层次结构可以是一层深,可以是几层(子目录)深。在每个压缩档案中都有一个文件,称之为“diamond.xls”。不幸的是,每个存档可能会将其放在不同的子目录中,因此我们必须遍历每个子目录以查找“diamond.xls”。挑战在于编写一个可以浏览压缩文件夹的VBA脚本,搜索任何/所有子目录,找到“diamond.xls”,如果找到,打开并将数据复制到新工作表中。

远远的工作

有很多文章都是关于从压缩文件夹中提取单个文件的。但是,我还没有看到能够通过压缩驱动器中的子目录进行爬网的工具。一位SO撰稿人声称拉链驱动器是扁平的,但是当我通过压缩驱动器的.items()时,它似乎只返回第一级,让我相信这可能是不正确的。这是我目前的代码:

Public Function goThroughZip(ByRef strZipFilename, ByVal strDstDir, ByRef strFilename)
    'Script based on http://stackoverflow.com/questions/19716587/how-to-open-a-file-from-an-archive-in-vba-without-unzipping-the-archive

    Dim intOptions, objShell, objSourceItems, objTarget

    ' Create the required Shell objects
    Set objShell = CreateObject("Shell.Application")

    ' Create a reference to the files and folders in the ZIP file
    On Error Resume Next
    Set objSourceItems = objShell.Namespace(strZipFilename).Items()

    'Browse through Items
    Dim objSourcCol As Collection
    Dim i As Variant
    Dim tempItem As Variant

    For i = 0 To objSourceItems.Count - 1
        tempItem = objSourceItems.Item(i).GetFolder.Items  '<-- more on this below
        Debug.Print (tempItem)
    Next i


    ' Create a reference to the target folder
    'Set objTarget = objShell.Namespace(strDstDir)
    'intOptions = glngcCopyHereDisplayProgressBox
    'Debug.Print ("objTarget " & objTarget)
    ' UnZIP the files
    'objTarget.CopyHere objSource, intOptions

    ' Release the objects
    Set objSource = Nothing
    Set objTarget = Nothing
    Set objShell = Nothing

    goThroughZip = 1
End Function

此代码远未完成。我一直在努力了解如何使用.nameSpace方法和文件夹项方法。

Set objSourceItems = objShell.Namespace(strZipFilename).Items()

返回Folder2类型项的数组,即归档文件夹中的第一级(万岁!)

所以现在根据MS Dev Docs,我应该能够使用方法.item(我作为变体)来检索folderItem对象(并访问该文件夹)。

Dim i as Variant
Dim tempItem as Variant
for i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i)
    Debug.Print(TypeName(tempItem))
Next i

返回一堆字符串......不是FolderITem对象..嗯,好吧,让我们假装它是一个文件夹,看看会发生什么:

Dim i as Variant
Dim tempItem as Variant
for i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i).GetFolder().Items()
    Debug.Print(TypeName(tempItem))
Next i

现在我们要返回FolderItemVerbs。

让我们尝试将循环内的代码修改为:

tempItem = objSourceItems.Item(i).Path()
Debug.Print (tempItem)

返回一堆看起来不错的路径名,即“C; \ archive.zip \ folder1”

如果我们获取该路径名并将其提供给另一个NameSpace,该怎么办:

For i = 0 To objSourceItems.Count - 1
    tempPath = objSourceItems.Item(i).Path()
    tempSourceItems = objShell.Namespace(tempPath).Items()
    Debug.Print (TypeName(tempSourceItems))
Next i

再次,FolderItemVerbs ..不是folderItem。让我们确保这些确实是文件夹:

For i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i).isFolder()
    Debug.Print (tempItem & " : " & objSourceItems.Item(i))
Next i

是的 - 他们是文件夹。

如果我们只是简单地说:

For i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i)
    Debug.Print (tempItem.items())
Next i    

什么都没有......什么也没有。我知道这些文件夹中有子文件夹和文件。发生了什么事?

如何访问这些子文件夹并在每个档案中找到diamond.xls?

非常感谢您的时间和考虑。我的经理很快就要求解决方案 - 你帮了我很多忙!

感激,

扎克


*编辑:奇怪的遵守:

For i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i).Size
    Debug.Print (tempItem)    '<-- Returns Longs that show size
Next i

For i = 0 To objSourceItems.Count - 1
    tempItem = objSourceItems.Item(i)
    Debug.Print (tempItem.size) '<-- Returns nothing
Next i

我想我错过了VBA的一些基本方面......

0 个答案:

没有答案