使用变量文件名在 VBA 中获取文件标签

使用变量文件名在 VBA 中获取文件标签

我在 Excel 中使用 VBA 循环遍历一系列文件并决定导入哪些文件。我想使用文件标签之类的东西来决定导入哪些文件,这样我就不需要打开每个文件了。我尝试使用该GetDetailsOf方法来获取它们,但每当我尝试使用变量作为文件名时都会失败。

此代码使用常量作为文件名,可以正常工作:

Sub TestTags()
  Dim strPath As String
  Dim strFile As String

  strPath = "C:\Users\XXXX\Documents\Safe Space\MacroTest\"
  strFile = Dir(strPath & "*.xls*")
  Do While strFile <> ""
      Debug.Print GetTags()
      strFile = Dir()
  Loop
End Sub

Function GetTags()
  Const csFile As String = "MyTestFile.xlsx"

  With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
      GetTags = .GetDetailsOf(.Items.Item(csFile), 18)
  End With
End Function

但是,当我尝试用调用子例程传递的变量替换常量时,出现错误。以下是失败的代码:

Sub TestTags()
    Dim strPath As String
    Dim strFile As String

    strPath = "C:\Users\XXXX\Documents\Safe Space\MacroTest\"
    strFile = Dir(strPath & "*.xls*")
    Do While strFile <> ""
        Debug.Print GetTags(strFile)
        strFile = Dir()
    Loop
End Sub

Function GetTags(ByVal strFile As String)
    Const csFile As String = "MyTestFile.xlsx"
    Dim i As Integer

    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.Items.Item(strFile), 18)
    End With
End Function

我唯一改变的是.GetDetailsOf方法中的参数,从常量切换到变量。每次运行时,它都会在该行停止并显示“错误 445:对象不支持此操作”

我究竟做错了什么?

答案1

编辑:

好的。仍然无法弄清楚为什么案例 2 不起作用,但我发现获取对应的FolderItem对象的“正确”方式strFile(按要求.GetDetailsOf())是使用该.ParseName()方法:

Function GetTags(ByVal strFile As String)
    Const csFile As String = "MyTestFile.xlsx"
    Dim i As Integer

    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.ParseName(strFile)), 18)
    End With
End Function

我无法解释为什么它不起作用,但我确实有三种解决方法。


1)调用时使用CStr(strFile)而不是:strFile.GetDetailsOf()

Function GetTags(ByVal strFile As String)
    Const csFile As String = "MyTestFile.xlsx"
    Dim i As Integer

    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.Items.Item(CStr(strFile)), 18)
    End With
End Function

或者

2)将的参数类型更改strFileVariant

Function GetTags(ByVal strFile As Variant)
    Const csFile As String = "MyTestFile.xlsx"
    Dim i As Integer

    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.Items.Item("" & strFile), 18)
    End With
End Function

或者

strFile3)调用时连接一个空字符串.GetDetailsOf()

Function GetTags(ByVal strFile As Variant)
    Const csFile As String = "MyTestFile.xlsx"
    Dim i As Integer

    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.Items.Item("" & strFile), 18)
    End With
End Function

答案2

以下是我在 Excel 2010 中可以使用的方法:

Dim fdata as String
Dim ffolder as String
Dim filename as String
Dim foldobj As Object
Dim fshell As Object
Dim fullpath As String

Set fshell = CreateObject("shell.application") 
ffolder = "M:\AVMEDIA\FOLDER01"
filename = "video.mp4"
fullpath = ffolder & "\" & filename
Set foldobj = fshell.Namespace(ffolder & "\")
fdata = foldobj.GetDetailsOf(foldobj.ParseName(filename), 18)

评论

  1. 创建文件夹对象时,结尾的反斜杠必不可少。MS 文档似乎不正确。
  2. 我们解析以获取数据的对象的详细信息是文件名,而不是完整路径。这是根据 MS 文档的。
  3. 什么数据被存储在哪个文件标签中,整个过程是难以言喻的可怕,特别是当您有多个文件类型时。

答案3

Dir() 函数不返回完整路径,它只返回文件名和扩展名。因此,当您尝试访问标签时,如果您获得 Dir() 的结果,则只会传递文件名和扩展名。相反,请按如下所示添加路径。我更改了 GetTags 中传递的变量的名称,以避免混淆。

Sub TestTags()
    Dim strPath As String
    Dim strFile As String

    strPath = "C:\Users\XXXX\Documents\Safe Space\MacroTest\"
    strFile = Dir(strPath & "*.xls*")
    Do While strFile <> ""
        Debug.Print GetTags(strPath & strFile)
        strFile = Dir()
    Loop
End Sub

Function GetTags(ByVal strFullPath As String)
    With CreateObject("Shell.Application").Namespace("C:\Users\XXXX\Documents\Safe Space\MacroTest\")
        GetTags = .GetDetailsOf(.Items.Item(strFullPath), 18)
    End With
End Function

答案4

在许多情况下,将 + 0 或 & vbnullstring & "" 添加到要传递的变量会导致自动转换为所需的类型。许多年前,某种语言设计师一定把这个例程放在那里

相关内容