Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Excel > Macros et VBA Excel
Macros et VBA Excel Vos questions relatives aux macros Excel, à l'utilisation de VBA et à l'automatisation de vos classeurs Excel.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/01/2012, 14h50   #1
Invité de passage
 
Inscription : janvier 2012
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 5
Points : 2
Points : 2
Par défaut Lire un fichier texte dont l'encoding n'est pas connu

Bonjour à tous.
J'ai une macro EXCEL qui doit ouvrir un fichier CSV dont l'encoding n'est pas connu :
- il peut être soit en UTF8 (avec le marqueur BOM qui va bien au début), ou bien être en ascii standard (sans ce fameux marqueur).
- de plus, les sauts de lignes peuvent être différents : soit \n, soit \r\n.

Je dois lire le fichier ligne à ligne, sans perdre les caractères accentués qui le compose.

Bref, il me faudrait une fonctionnalité de lecture de fichier "universelle".

Pour l'instant, je detecte le type du fichier en lisant les 3 premiers octets, et en fonction de cela j'utilise soit ADODB.Stream soit FileSystemObject, mais je souhaite avoir une méthode un peu plus élégante.

Avez-vous une idée ?
jemore22 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/01/2012, 18h26   #2
Expert Confirmé Sénior
 
Avatar de Qwazerty
 
Homme Stéphane
La très haute tension :D
Inscription : avril 2002
Messages : 2 446
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Âge : 32
Localisation : France

Informations professionnelles :
Activité : La très haute tension :D
Secteur : Service public

Informations forums :
Inscription : avril 2002
Messages : 2 446
Points : 4 620
Points : 4 620
Envoyer un message via MSN à Qwazerty
Salut

Propose nous le code déjà réalisé et si possible un exemple des différentes structures que tu souhaites lire.

++
Qwaz
__________________

MagicQwaz := Harry Potter la baguette en moins
Le monde dans lequel on vit
HammerFest
Ma page perso DVP - Dernier Tutoriel : VBA & Internet Explorer
Qwazerty est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 14h24   #3
Invité de passage
 
Inscription : janvier 2012
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 5
Points : 2
Points : 2
Bonjour.

La structure du fichier n'est pas connu (c'est un fichier texte CSV, séparateur ";" , mais peu importe en fait).

Voici le code en question (a placer dans un nouveau module - il faut activer la référence "Microsoft scripting Runtime" )
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
 
Public Type MyFileObject
    objStream As Object
    encoding As Integer
    encodingAsStr As String
 
End Type
 
Public Const myFileEncodingASCII = 1
Public Const myFileEncodingUTF8 = 2
 
Public Function MyFileOpen(ByVal filename As String) As MyFileObject
    ' detect if file is ascii or utf
    Dim bom(3) As Byte
    Dim intFileNum As Byte
    intFileNum = FreeFile
    Open filename For Binary Access Read As intFileNum
    Dim i As Integer
    i = 1
    ' read 3st byte containing the BOM
    Do While Not EOF(intFileNum)
        Get intFileNum, , bom(i)
        i = i + 1
        If i > 3 Then Exit Do
    Loop
    Close intFileNum
 
    Dim t As MyFileObject
 
    ' detect BOM of the file
    If bom(1) = &HEF And bom(2) = &HBB And bom(3) = &HBF Then
        t.encoding = myFileEncodingUTF8
        t.encodingAsStr = "utf-8"
 
    Else
        t.encoding = myFileEncodingASCII
        t.encodingAsStr = "ascii"
    End If
 
    Dim objStream As Object
    If (t.encoding = myFileEncodingASCII) Then
        Dim fso As Scripting.FileSystemObject
        Set fso = New Scripting.FileSystemObject
        Set objStream = fso.OpenTextFile(filename, ForReading, False, TristateFalse)
        Set t.objStream = objStream
    Else
 
        Set objStream = CreateObject("ADODB.Stream")
        objStream.Open
        objStream.Charset = "UTF-8"
        objStream.Type = adTypeText
        objStream.LineSeparator = adLF '' 10 # Linefeed
        objStream.LoadFromFile (filename)
        Set t.objStream = objStream
    End If
 
    MyFileOpen = t
End Function
 
Public Function MyFileIsEOF(fileobj As MyFileObject) As Boolean
 
    If (fileobj.encoding = myFileEncodingASCII) Then
        MyFileIsEOF = fileobj.objStream.AtEndOfStream
    Else
        MyFileIsEOF = fileobj.objStream.EOS
 
    End If
 
End Function
 
Public Function MyFileReadLine(fileobj As MyFileObject) As String
 
    If (fileobj.encoding = myFileEncodingASCII) Then
        MyFileReadLine = fileobj.objStream.ReadLine
    Else
        MyFileReadLine = fileobj.objStream.ReadText(adReadLine)
    End If
End Function
 
Public Function MyFileClose(fileobj As MyFileObject)
    If (fileobj.encoding = myFileEncodingASCII) Then
        MyFileReadLine = fileobj.objStream.Close
    Else
        MyFileReadLine = fileobj.objStream.Close
    End If
 
End Function
Un exemple d'utilisation :
Code :
1
2
3
4
5
6
7
8
9
 
 
Dim objStream As MyFileObject
objStream = MyFileOpen("c:\temp\fichier.csv")
Do Until MyFileIsEOF(objStream)
line = MyFileReadLine(objStream)
' do some stuff..
Loop
MyFileClose(objStream)
Je souhaiterais simplifier ce code, pour utiliser un seul objet capable de s'adapter au format du fichier lu.
jemore22 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/01/2012, 14h39   #4
Membre Expert
 
Avatar de ZebreLoup
 
Homme Sebastien L
Ingénieur Financier
Inscription : mars 2010
Messages : 880
Détails du profil
Informations personnelles :
Nom : Homme Sebastien L
Âge : 33
Localisation : France, Val de Marne (Île de France)

Informations professionnelles :
Activité : Ingénieur Financier
Secteur : Finance

Informations forums :
Inscription : mars 2010
Messages : 880
Points : 1 867
Points : 1 867
Et en mettant juste iso-8859-1 dans le CharSet quand tu es en ASCII, mais en gardant un Stream ADODB, ce serait plus simple non ?
__________________
« Compter en octal, c’est comme compter en décimal, si on n’utilise pas ses pouces » - Tom Lehrer
« Il est assez difficile de trouver une erreur dans son code quand on la cherche. C’est encore bien plus dur quand on est convaincu que le code est juste. » - Steve McConnell
ZebreLoup est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2012, 09h28   #5
Invité de passage
 
Inscription : janvier 2012
Messages : 5
Détails du profil
Informations forums :
Inscription : janvier 2012
Messages : 5
Points : 2
Points : 2
En effet, je n'y avais même pas pensé... Je dois maintenant régler le problème des retours chariots (qui peuvent etre soit CR soit CRLF), mais je suis sur la bonne voie ! Merci pour cet éclair de lucidité !
jemore22 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h54.


 
 
 
 
Partenaires

Hébergement Web