【问题标题】:VBA "object Variable or With block variable not set" with Shell application带有Shell应用程序的VBA“对象变量或未设置块变量”
【发布时间】:2021-06-10 06:27:56
【问题描述】:

我正在尝试从一系列 zip 文件中提取一些数据,并将它们存储在我正在处理的同一张表中。我已经提取了每个 zip 文件的名称并将它们存储在工作表的一列中。我想遍历它们以提取我需要的数据,但是,当我访问 oApp.Namespace(zipName).Items 时,我不断收到“运行时错误 91”的错误。这是我拥有的VBA代码,有人可以帮我吗?谢谢!

Sub GetData()
Dim iRow As Integer 'row counter
Dim iCol As Integer 'column counter
Dim savePath As String 'place to save the extracted files
Dim fileContents As String 'contents of the file
Dim fso As FileSystemObject 'FileSystemObject to work with files
iRow = 1 'start at first row
iCol = 1 'start at frist column
'set the save path to the temp folder
savePath = Environ("TEMP")
'create the filesystem object
Set fso = New FileSystemObject

Do While ActiveSheet.Cells(iRow, iCol).Value <> ""
    fileContents = fso.OpenTextFile(UnzipFile(savePath, ActiveSheet.Cells(iRow, iCol).Value, "Device-1_IR_VR_7-16-2019-2-32-55_PM.pda-iv.txt"), ForReading).ReadAll
    ActiveSheet.Cells(iRow, iCol).Value = fileContents
    iRow = iRow + 1
Loop


'free the memory
Set fso = Nothing
End Sub

Function UnzipFile(savePath As String, zipName As String, fileName As String) As String
Dim oApp As Shell
Dim strFile As String
'get a shell object
Set oApp = CreateObject("Shell.Application")
    'check to see if the zip contains items
    'Debug.Print oApp.Namespace(zipName).Items.Count
  If Not IsNull(oApp.Namespace(zipName).Items) Then
    If oApp.Namespace(zipName).Items.Count > 0 Then
        Dim i As Integer
        'loop through all the items in the zip file
        For i = 0 To oApp.Namespace(zipName).Items.Count - 1
            'check to see if it is the txt file
            If UCase(oApp.Namespace(zipName).Items.Item(i)) = UCase(fileName) Then
                'save the files to the new location
                oApp.Namespace(savePath).CopyHere oApp.Namespace(zipName).Items.Item(i)
                'set the location of the file
                UnzipFile = savePath & "\" & fileName
                'exit the function
                Exit Function
            End If
        Next i
    End If
   End If
'free memory
Set oApp = Nothing

End Function

【问题讨论】:

  • 对 powershell 不太熟悉,但我快速阅读了this Shell.Namespace method 文档,这似乎表明您需要先使用命名空间再次设置oApp,然后检查它是否为空/计数 - 具体来说这两行:set objShell = CreateObject("shell.application") 然后set objFolder = objShell.NameSpace("C:\\")
  • 在使用 shell 命名空间时,您应该使用声明为 Variant 而不是 String 的路径。 stackoverflow.com/questions/31128248/…
  • @TimWilliams 感谢您与我们联系。我对此进行了研究,发现您对我的错误是正确的。现在的问题是我已经在我的工作表中存储了我想要使用的所有 .zip 文件,我需要将它们的名称传递给我的 UnzipFile 函数。但是,我认为没有办法将单元格的值设置为变体类型。你对此有什么想法吗?
  • 在您的解压缩方法中,您可以将变量包装在 CVar() 中

标签: excel vba runtime-error


【解决方案1】:

如果要将变量传递给 Shell,请将它们交换为 Variant:

Sub GetData()
    Dim iRow As Long                'row counter
    Dim iCol As Long                'column counter
    Dim savePath As Variant         'place to save the extracted files
    Dim zipName As Variant
    Dim txtPath As String
    Dim fileContents As String      'contents of the file
    Dim fso As FileSystemObject     'FileSystemObject to work with files
    
    iRow = 1                        'start at first row
    iCol = 1                        'start at first column
    savePath = Environ("TEMP")      'set the save path to the temp folder
    Set fso = New FileSystemObject  'create the filesystem object
    
    Do While ActiveSheet.Cells(iRow, iCol).Value <> ""
        zipName = ActiveSheet.Cells(iRow, iCol).Value
        txtPath = UnzipFile(savePath, zipName, "Device-1_IR_VR_7-16-2019-2-32-55_PM.pda-iv.txt")
        If Len(txtPath) > 0 Then 'if found the file...
            fileContents = fso.OpenTextFile(txtPath, ForReading).ReadAll
            ActiveSheet.Cells(iRow, iCol).Value = fileContents
        End If
        iRow = iRow + 1
    Loop
End Sub

Function UnzipFile(savePath As Variant, zipName As Variant, fileName As String) As String
    Dim oApp As Object, ns As Object, i As Long
    
    Set oApp = CreateObject("Shell.Application")    'get a shell object
    Set ns = oApp.Namespace(zipName)                'get the zip namespace
    If ns.Items.Count > 0 Then
        For i = 0 To ns.Items.Count - 1
            'check to see if it is the txt file
            If UCase(ns.Items.Item(i)) = UCase(fileName) Then
                'save the files to the new location
                oApp.Namespace(savePath).CopyHere ns.Items.Item(i)
                UnzipFile = savePath & "\" & fileName 'return the location of the file
                Exit Function
            End If
        Next i
    End If
End Function

【讨论】:

  • 我听取了您的建议并亲自尝试了不同类型的代码 sn-ps,包括您的代码,但在我的行 If Not IsNull(ns.Items) Then 处再次发生了同样的错误。你认为我应该在主循环中解压缩我的文件吗?谢谢!
  • 我认为您不需要 isnull() 检查 - 一个 zip 存档至少需要其中一个项目。
猜你喜欢
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多