早上好/下午/晚上/午夜,
这已成为一个越来越令人沮丧的问题 - 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的一些基本方面......