Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle filenames with unicode characters in VBA using Dir?

Tags:

excel

unicode

vba

I am selecting a list of files based on a criteria using Dir, and then storing these in an array of strings. I then iterate through the array and process the files.

How can i handle filenames with unicode characters?

I tried to do StrConv but it didn't help.

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

Then later I'll try to access the file's properties like this:

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

at the last line I get an error-message that the File is not found. This only happens for filenames with unicode characters.

There was another post regarding this here: Working with Unicode file names in VBA (using Dir, FileSystemObject, etc.), but it didnt solve the problem withDir`.

My Example: VBA (watch) c:\my-test-file.pdf Unicode: c:\my‐test‐file.pdf

(you cannot see the difference here but if you copy the names and paste them into Notepad++ you'll see that the dashes are different characters for the two files, VBA is converting the unicode dash character into a windows locale dash)

Or the example from the linked question: 3_Połish.txt (in Unicode) vs 3_Polish.txt (in VBA)

like image 973
Atti Avatar asked Feb 29 '16 12:02

Atti


2 Answers

I had a similar issue. Using FileSystemObject to crawl through subdirectories for files was much too slow. For my needs, I coded the creation and running of a batch file that, among other things, used the Dir command and piped the output to a file. Then after the batch file completed, my code parsed the output file. Weirdly, unicode characters were just fine, and then suddenly they weren't. (I never tried to figure out why. I'm guessing it was either because we moved the files to a different place, I started using a client instead of a server to do the processing, or the Win10 upgrade du jour, but none of these were within my control.)

The way I solved it was to change the creation of the batch file from including a dir command to instead execute a DOS command of call cmd /u /c dir "dirpath" > c:\Temp\DirOutput.txt and then read the file.

  • cmd /u is the key part. This forces the output piped to a file to be in Unicode
  • call because it was within a batch file, and call pauses batch file execution until the command is complete. Not needed for a simple dir but I found it needed for cmd. (Maybe there was a better way, but this is the one I stumbled on first.)
  • The /c flag of cmd tells cmd to treat the rest of the line as a command to execute, then terminate.
  • dir can also have flags, of course. I used a /s flag because I needed all files within and below dirpath
  • > to tell dir to output the results to a text file.
like image 177
JSmart523 Avatar answered Oct 23 '22 00:10

JSmart523


Actually, the problem lies in the use of Dir to create the list of files, instead, I suggest a wider use of the FileSystemObject, i.e.: the properties of its Folder and File objects.

The procedure below prints the properties Name, DateLastModified and Path for all txt files in folder D:\@D_Trash\

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
like image 1
EEM Avatar answered Oct 23 '22 01:10

EEM