XL 2021 Fichiers Txt en UTF8 ou ANSI

Marc Vanlindt

XLDnaute Nouveau
Bonjour à toutes et à tous.
Lorsque j'importe un fichier .txt dans une TextBox, ce fichier peut être encodé soit en ANSI, soit en UTF8 (sans BOM).
L'affichage dans une TextBox est toujours ANSI.
Comment déterminer l'encodage du fichier .txt afin de savoir si je dois le convertir ou non ?
Merci d'avance pour vos réponses ! (ChatGPT n'y parvient pas)
Marc
 
Solution
Bonjour,

Il y a quelques temps j'avais rencontré le même problème que toi et j'avais pondu un bout de code, qui ne vaut que ce qu'il vaut... mais qui fonctionnait avec les fichiers que j'utilisais.

Je t'ai construit un classeur-exemple avec les macros de l'époque, et ça a l'air de fonctionner avec tes trois fichiers qui sont bien détectés au format indiqué par leurs noms.
A toi de voir si tu peux en tirer quelque chose ou pas. ;)

Marc Vanlindt

XLDnaute Nouveau
Bonjour,

Bonjour et merci pour le lien.
J'ai testé le code proposé en lui soumettant un fichier txt encodé en utf8 mais il m'a répondu qu'il était encodé en ANSI.
Ne fonctionne donc pas et je ne vois pas comment l'adapter.
 

patricktoulon

XLDnaute Barbatruc
Bonjour
il faut switcher avec open for input et adobd.stream
une petite fonction facon patricktoulon
VB:
Sub test3()
'on lit un fichier ANSI
    Dim texto$, Fichier$
    Fichier = "C:\Users\polux\Desktop\Mémo 0.txt"
    Open_For_Read_Force_Udf_8 Fichier, texto
    UserForm1.textbox1.value= texto
End Sub

Function Open_For_Read_Force_Udf_8(ByVal Fichier$, texto$)
    Dim lachaine As String, x: x = FreeFile
    'lecture binnaire
    Open Fichier For Binary Access Read As #x: lachaine = String(LOF(x), " "): Get #x, , lachaine: Close #x
    If Not lachaine Like "*[Ã|é|è|ç|â|€|«|»|û|ê|…|/ø|ø|À|É|È|Ã|Ö|]*" Then    'si la chaine ne contient pas de carateres sbizarre
        texto = lachaine    ' alors texto = lachaine
    Else    ' sinon on stream le fichier avec ADOBD.Stream

        With CreateObject("ADODB.Stream")
            .Charset = "utf-8": .Open: .LoadFromFile (Fichier): texto = .ReadText()
        End With
    End If
End Function
et voila :)
 

Marc Vanlindt

XLDnaute Nouveau
Bonjour
il faut switcher avec open for input et adobd.stream
une petite fonction facon patricktoulon
VB:
Sub test3()
'on lit un fichier ANSI
    Dim texto$, Fichier$
    Fichier = "C:\Users\polux\Desktop\Mémo 0.txt"
    Open_For_Read_Force_Udf_8 Fichier, texto
    UserForm1.textbox1.value= texto
End Sub

Function Open_For_Read_Force_Udf_8(ByVal Fichier$, texto$)
    Dim lachaine As String, x: x = FreeFile
    'lecture binnaire
    Open Fichier For Binary Access Read As #x: lachaine = String(LOF(x), " "): Get #x, , lachaine: Close #x
    If Not lachaine Like "*[Ã|é|è|ç|â|€|«|»|û|ê|…|/ø|ø|À|É|È|Ã|Ö|]*" Then    'si la chaine ne contient pas de carateres sbizarre
        texto = lachaine    ' alors texto = lachaine
    Else    ' sinon on stream le fichier avec ADOBD.Stream

        With CreateObject("ADODB.Stream")
            .Charset = "utf-8": .Open: .LoadFromFile (Fichier): texto = .ReadText()
        End With
    End If
End Function
et voila :)
Bonjour et merci.
J'ai testé et la conversion de UTF8 vers ANSI fonctionne parfaitement. Par contre, si je lis un fichier ANSI il n'est pas correct.
Ce que j'aurais souhaité, c'est lire un fichier txt, peu importe son encodage(UTF8, ANSI, UTF8-BOM, etc.), et avoir en sortie un fichier ANSI.
 

patricktoulon

XLDnaute Barbatruc
une petite fonction qui te donne true ou false si cest du utf-8 avec ou sans BOM
VB:
Sub testq()
    MsgBox Is_UTF8_Encoded("C:\Users\patricktoulon\Desktop\MaccustomUI.xml") 'sans bomm
    MsgBox Is_UTF8_Encoded("C:\Users\patricktoulon\Desktop\exemple.xml") 'avec bomm
    MsgBox Is_UTF8_Encoded("K:\vba excel\A quoi sert la fonction Environ.txt") 'ansi
End Sub

Function Is_UTF8_Encoded(fichier As String) As Boolean
    'patricktoulon 2024
    Dim t As String, res(1 To 3) As Boolean
    Open fichier For Input As #1
    Line Input #1, t
    res(1) = Asc(Mid(t, 1, 1)) = &HEF And Asc(Mid(t, 2, 1)) = &HBB And Asc(Mid(t, 3, 1)) = &HBF 'utf_8 avec BOM
    res(2) = Asc(Mid(t, 1, 1)) = &H3C And Asc(Mid(t, 2, 1)) = &H63 And Asc(Mid(t, 3, 1)) = &H75 'utf-8 asan BOM
    res(3) = Asc(Mid(t, 1, 1)) = &H41 And Asc(Mid(t, 2, 1)) = &H20 And Asc(Mid(t, 3, 1)) = &H71 'utf-8 asan BOM
    Close #1
    If res(1) Or res(2) Then Is_UTF8_Encoded = True
End Function
 

Marc Vanlindt

XLDnaute Nouveau
une petite fonction qui te donne true ou false si cest du utf-8 avec ou sans BOM
VB:
Sub testq()
    MsgBox Is_UTF8_Encoded("C:\Users\patricktoulon\Desktop\MaccustomUI.xml") 'sans bomm
    MsgBox Is_UTF8_Encoded("C:\Users\patricktoulon\Desktop\exemple.xml") 'avec bomm
    MsgBox Is_UTF8_Encoded("K:\vba excel\A quoi sert la fonction Environ.txt") 'ansi
End Sub

Function Is_UTF8_Encoded(fichier As String) As Boolean
    'patricktoulon 2024
    Dim t As String, res(1 To 3) As Boolean
    Open fichier For Input As #1
    Line Input #1, t
    res(1) = Asc(Mid(t, 1, 1)) = &HEF And Asc(Mid(t, 2, 1)) = &HBB And Asc(Mid(t, 3, 1)) = &HBF 'utf_8 avec BOM
    res(2) = Asc(Mid(t, 1, 1)) = &H3C And Asc(Mid(t, 2, 1)) = &H63 And Asc(Mid(t, 3, 1)) = &H75 'utf-8 asan BOM
    res(3) = Asc(Mid(t, 1, 1)) = &H41 And Asc(Mid(t, 2, 1)) = &H20 And Asc(Mid(t, 3, 1)) = &H71 'utf-8 asan BOM
    Close #1
    If res(1) Or res(2) Then Is_UTF8_Encoded = True
End Function
Merci beaucoup, Patrick.
J'ai testé mes fichiers "T1 UTF8.txt", "T2 UTF8-BOM.txt" et "T3 ANSI.txt"
Résultats : FAUX, VRAI, FAUX
J'ai joint mes 3 fichiers tests.
 

Pièces jointes

  • T1 UTF8.txt
    3.2 KB · Affichages: 7
  • T2 UTF8-BOM.txt
    3.2 KB · Affichages: 7
  • T3 ANSI.txt
    3 KB · Affichages: 7

patricktoulon

XLDnaute Barbatruc
re
le T1 UTF8.txt je sais pas ce que c'est mais il est pas en utf-8 même si le truc dit vrai
d'ailleurs tes 2 fichiers quand on les ouvre en binaire sont un peu bizarre
les 3 premiers bytes pour le (sans bom et le ansi )sont les même avec tes fichiers
il y a donc un vrai malaise avec tes fichiers
si c'est de l'import ça m'étonne qu'a moitié
sinon je ne vois pas
en tout cas une chose dont je suis sur à 100% c'est que ton utf8 sans bom n'est pas en utf-8
parti de là je crois qu'il va falloir travailler a l'ancienne avec un textbox dans un userform
et encore je sais même pas comment il va sortir en lecture
 

Marc Vanlindt

XLDnaute Nouveau
re
le T1 UTF8.txt je sais pas ce que c'est mais il est pas en utf-8 même si le truc dit vrai
d'ailleurs tes 2 fichiers quand on les ouvre en binaire sont un peu bizarre
les 3 premiers bytes pour le (sans bom et le ansi )sont les même avec tes fichiers
il y a donc un vrai malaise avec tes fichiers
si c'est de l'import ça m'étonne qu'a moitié
sinon je ne vois pas
en tout cas une chose dont je suis sur à 100% c'est que ton utf8 sans bom n'est pas en utf-8
parti de là je crois qu'il va falloir travailler a l'ancienne avec un textbox dans un userform
et encore je sais même pas comment il va sortir en lecture
C'est étonnant ce que tu dis. J'ai simplement copié du texte d'un article Wikipedia que j'ai collé dans Notebook++.
Et Notebook++ me signale que c'est de l'UTF8 et c'est avec ce programme que j'ai sauvé le texte en deux copies, l'une en ANSI et l'autre en UTF8-BOM...
Comprends pas...
 

TooFatBoy

XLDnaute Barbatruc
Bonjour,

Il y a quelques temps j'avais rencontré le même problème que toi et j'avais pondu un bout de code, qui ne vaut que ce qu'il vaut... mais qui fonctionnait avec les fichiers que j'utilisais.

Je t'ai construit un classeur-exemple avec les macros de l'époque, et ça a l'air de fonctionner avec tes trois fichiers qui sont bien détectés au format indiqué par leurs noms.
A toi de voir si tu peux en tirer quelque chose ou pas. ;)
 

Pièces jointes

  • Lire-fichier-UTF8-ou-ANSI.xlsm
    31.4 KB · Affichages: 7

jurassic pork

XLDnaute Occasionnel
Hello,
pour détecter l'encodage d'un fichier texte sous windows on peut utiliser le module powershell EncodingAnalyzer (licence GPL) qui se trouve dans la galerie powershell.
Voici comment l'utiliser en VBA.
1 - Il faut d'abord importer le module sur sa machine (il se télécharge automatiquement si présent dans la galerie):
[EDIT] Par défaut les scripts PowerShell ne sont pas autorisés. Lancer la commande suivante dans une invite de commande powerShell pour voir les droits actuels :
VB:
Get-ExecutionPolicy
si c'est Restricted on ne pourra pas utiliser le module , lancer alors la commande
Code:
Set-ExecutionPolicy RemoteSigned
ou
Code:
Set-ExecutionPolicy UnRestricted
Pour Installer alors le module :
1 - Pour tous les utilisateurs :
Ouvrir une invite de commande Powershell en étant administrateur et lancer :
Code:
Install-Module -Name EncodingAnalyzer
2 - Que pour l'utiliseur courant :
Ouvrir une invite de commande Powershell et lancer :
Code:
Install-Module -Name EncodingAnalyzer -Scope CurrentUser

Voici le code VBA pour utiliser la fonction Get-Encoding du module. Ce code utilise la fonction PS_GetOutput qui lance une commande powershell en utilisant la fonction de patricktoulon ShellAndwaitingEndProcess (lancer une commande et attendre qu'elle soit finie). La fonction PS_GetOutput renvoie le résultat de la commande (elle utilise le presse-papier pour récupérer ce résultat).

VB:
Sub DetectFileEncoding()
'Dim bm As New cBenchmark
Dim mesFichiers, Fichiers, Resultat As String, Lignes, Ligne
'bm.TrackByName "Init"
mesFichiers = Array("d:\temp\T1 UTF8.txt", "d:\temp\T2 UTF8-BOM.txt", "d:\temp\T3 ANSI.txt")
For Each Fichier In mesFichiers
    Resultat = PS_GetOutput("Get-Encoding '" & Fichier & "' | ConvertTo-Csv -NoTypeInformation ")
 '   bm.TrackByName "PowerShell Execute"
    Lignes = Split(Resultat, vbCrLf)
    For Each Ligne In Lignes
        Debug.Print Ligne
    Next Ligne
 '   bm.TrackByName "Affiche Résultat"
Next Fichier
End Sub

Public Function PS_GetOutput(ByVal sPSCmd As String) As String
    sPSCmd = "powershell -command " & sPSCmd & " | clip"
    ShellAndwaitingEndProcess sPSCmd
    With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
        .GetFromClipboard
        PS_GetOutput = .GetText(1)
    End With
End Function

Function ShellAndwaitingEndProcess(ByVal CheminComplet As String) As Long
    Dim ProcessHandle As Long
    Dim ProcessId As Long
    ProcessId = Shell(CheminComplet, vbHide)
    ProcessHandle = ExecuteExcel4Macro("CALL(""Kernel32"",""OpenProcess"",""JJJJ"",""" & 2031616 & """,""" & 0 & """,""" & ProcessId & """)")
    ShellAndwaitingEndProcess = ExecuteExcel4Macro("CALL(""Kernel32"",""WaitForSingleObject"",""JJJJJ"",""" & ProcessHandle & """,""" & &HF0000 & """)")
End Function
Les lignes en commentaires dans DetectFileEncoding ont été utilisées pour calculer le temps d'exécution pour traiter 3 fichiers textes. Voici le résultat :
IDnrNameCountSum of ticsPercentageTime sum
0​
Init
1​
78​
0,00%​
7800 ns
1​
PowerShell Execute
3​
22 655 101​
99,85%​
2,27 s
2​
Affiche Résultat
3​
45 397​
0,15%​
4,54 ms
TOTAL
7​
22 700 576​
100,00%​
2,27 s
Total time recorded:2,3 s

Et voici ce qui est retourné (en format csv) :
"BOM","Encoding","Confidence","Path"
"False","UTF-8","100","d:\temp\T1 UTF8.txt"

"BOM","Encoding","Confidence","Path"
"True","UTF-8","100","d:\temp\T2 UTF8-BOM.txt"

"BOM","Encoding","Confidence","Path"
"False","WINDOWS-1252","50","d:\temp\T3 ANSI.txt"

A noter que dans le PowerShell on peut lancer des commandes windows Exemple :
VB:
Resultat = PS_GetOutput("Dir")

Ami calmant, J.P
 
Dernière édition:

Marc Vanlindt

XLDnaute Nouveau
Bonjour,

Il y a quelques temps j'avais rencontré le même problème que toi et j'avais pondu un bout de code, qui ne vaut que ce qu'il vaut... mais qui fonctionnait avec les fichiers que j'utilisais.

Je t'ai construit un classeur-exemple avec les macros de l'époque, et ça a l'air de fonctionner avec tes trois fichiers qui sont bien détectés au format indiqué par leurs noms.
A toi de voir si tu peux en tirer quelque chose ou pas. ;)
Bonjour et merci TooFatBoy ! Ça a l'air de fonctionner parfaitement.
Je vais l'intégrer à mon application. J'ai vraiment bon espoir !
Encore merci.
Marc

 

Discussions similaires

Réponses
18
Affichages
1 K

Statistiques des forums

Discussions
313 769
Messages
2 102 234
Membres
108 181
dernier inscrit
Chr1sD