【问题标题】:How to handle filenames with unicode characters in VBA using Dir?如何使用 Dir 在 VBA 中处理带有 unicode 字符的文件名?
【发布时间】:2016-06-12 11:41:40
【问题描述】:

我正在使用 Dir 根据条件选择文件列表,然后将它们存储在字符串数组中。然后我遍历数组并处理文件。

如何处理带有 unicode 字符的文件名?

我尝试做StrConv,但没有帮助。

vfile = Dir(vCurrDir & vCrit, vbNormal) 'vCrit is something like *test*

然后我会尝试像这样访问文件的属性:

vfilename = vCurrDir & "\" & vfile
Set objFSO = CreateObject("Scripting.FileSystemObject")
vDateMod = objFSO.GetFile(vfilename).datelastmodified

在最后一行,我收到一条错误消息,指出找不到文件。这只发生在带有 unicode 字符的文件名上。

这里有另一个帖子:Working with Unicode file names in VBA (using Dir, FileSystemObject, etc.),但它没有t solve the problem withDir`。

我的例子: VBA(观看)c:\my-test-file.pdf Unicode: c:\my-test-file.pdf

(您在这里看不到区别,但如果您复制名称并将它们粘贴到 Notepad++ 中,您会看到破折号是两个文件的不同字符,VBA 正在将 unicode 破折号字符转换为 Windows 区域设置破折号)

或链接问题中的示例: 3_Polish.txt(Unicode 格式)与 3_Polish.txt(VBA 格式)

【问题讨论】:

  • 您是否尝试在您的vfilename 上添加手表?显示什么?
  • 是的,当然,VBA 正在将文件名转换为 Windows 语言环境:(您在此处看不到它,但两个文件名之间的破折号不同,如果您将粘贴复制到 Notepad++,您会看到我平均值)VBA(手表)c:\my-test-file.pdf Unicode: c:\my-test-file.pdf
  • 您是否尝试过使用fso.GetFolder(path)

标签: vba excel unicode


【解决方案1】:

我遇到了类似的问题。使用 FileSystemObject 爬取文件的子目录太慢了。出于我的需要,我编写了一个批处理文件的创建和运行代码,其中包括使用Dir 命令并将输出通过管道传输到一个文件中。然后在批处理文件完成后,我的代码解析了输出文件。奇怪的是,unicode 字符很好,然后突然就不行了。 (我从来没有试图弄清楚为什么。我猜是因为我们将文件移动到了不同的地方,我开始使用客户端而不是服务器来进行处理,或者 Win10 升级du jour,但没有一个这些都在我的控制范围内。)

我解决它的方法是将批处理文件的创建从包含dir 命令改为执行call cmd /u /c dir "dirpath" > c:\Temp\DirOutput.txt 的DOS 命令,然后读取文件。

  • cmd /u 是关键部分。这会强制通过管道传输到文件的输出为 Unicode
  • call 因为它在批处理文件中,并且call 暂停批处理文件执行,直到命令完成。简单的dir 不需要,但我发现cmd 需要它。 (也许有更好的方法,但这是我第一次偶然发现的方法。)
  • cmd/c 标志告诉cmd 将该行的其余部分视为要执行的命令,然后终止。
  • dir 当然也可以有标志。我使用了 /s 标志,因为我需要 及以下 dirpath 内的所有文件
  • > 告诉 dir 将结果输出到文本文件。

【讨论】:

    【解决方案2】:

    其实问题在于使用Dir创建文件列表,我建议更广泛地使用FileSystemObject,即:FolderFile对象的属性。

    下面的过程打印D:\@D_Trash\文件夹中所有txt文件的属性NameDateLastModifiedPath

    Sub Files_with_Unicode_Chars()
    Dim oFso As Object      'Scripting.FileSystemObject
    Dim oFdr As Object      'Scripting.Folder
    Dim oFle As Object      'Scripting.File
    Dim vCurrDir As String, vCrit As String
    
        Set oFso = CreateObject("Scripting.FileSystemObject")
    
        vCurrDir = "D:\@D_Trash\"   'Update as needed!
        vCrit = ".txt"              'Update as needed!
    
        Set oFdr = oFso.GetFolder(vCurrDir)
        For Each oFle In oFdr.Files
            With oFle
                Select Case Mid(.Name, InStrRev(.Name, "."))
                Case vCrit
                    Rem Perform actions as needed
                    Rem This sample shows the use some of the File object properties
                    Debug.Print Now; vbTab; "["; .Name; "]"; Tab(71); .DateLastModified; Tab(101); .Path
        End Select: End With: Next
    
        End Sub
    

    【讨论】:

      【解决方案3】:

      尝试使用 BuildPath https://msdn.microsoft.com/en-us/library/office/gg251615.aspx 代替

      vfilename = vCurrDir & "\" & vfile
      

      【讨论】:

        猜你喜欢
        • 2016-02-14
        • 1970-01-01
        • 1970-01-01
        • 2013-11-08
        • 1970-01-01
        • 1970-01-01
        • 2012-01-07
        • 2021-10-24
        相关资源
        最近更新 更多