excelvbaimportfilesystemobjecttxt

Import txt files with UTF-8 special characters to xlsx


I have txt files that are automatically exported to me from another system (I cannot change this system). When I try to convert these txt files to excel with the following code (I created a subfolder xlsx manually):

Sub all()

   Dim sourcepath As String
   Dim sDir As String
   Dim newpath As String
    
    sourcepath = "C:\Users\PC\Desktop\Test\"
    newpath = sourcepath & "xlsx\"
    
    'make sure subfolder xlsx was created before

    sDir = Dir$(sourcepath & "*.txt", vbNormal)
    Do Until Len(sDir) = 0
        Workbooks.Open (sourcepath & sDir)
        With ActiveWorkbook
            .SaveAs Filename:=Replace(Left(.FullName, InStrRev(.FullName, ".")), sourcepath, newpath) & "xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
            .Close
        End With
        
        sDir = Dir$
    Loop
End Sub

it does work, however certain special characters, like ä,ö and Ü and so, are not properly displayed. I.e. when I open the xlsx files later on, I can see that these have been replaced by something like ä and so. I could use a work around and now start to replace these afterwards, however I would like to improve my txt to xlsx code. According to this post or this one it should be possible using ADODB.Stream. However, I don't know how to implement this into my code (loop) to get it working here in my case? If there is another approach instead of ADOB.Stream I am also fine with that. It is not necessary for me to use ADOB.Stream.


Solution

  • Have you tried coercing the code page, using the Origin parameter? I don't know if you need a particular one, but the UTF-8 constant might be a starting point. I personally like this page as a reference source: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers

    So the solution might turn out to be as simple as this - it worked in my dummy tests:

    Option Explicit
    Private Const CP_UTF8 As Long = 65001
    
    Public Sub RunMe()
        Dim sDir As String, sourcePath As String, fileName As String
        Dim fso As Object
        
        sourcePath = "C:\anyoldpath\"
        
        Set fso = CreateObject("Scripting.FileSystemObject")
        sDir = Dir(sourcePath & "*.txt", vbNormal)
        Do While Len(sDir) > 0
            fileName = sourcePath & "xlsx\" & fso.GetBaseName(sDir) & ".xlsx"
            Application.Workbooks.OpenText sourcePath & sDir, CP_UTF8
            ActiveWorkbook.SaveAs fileName, xlOpenXMLWorkbook
            ActiveWorkbook.Close False
            sDir = Dir()
        Loop
    End Sub