IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

VBA, conversion UTF 8 et caractères accentués [XL-2013]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Juriste
    Inscrit en
    Mars 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Juriste
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2004
    Messages : 49
    Par défaut VBA, conversion UTF 8 et caractères accentués
    Bonjour à toutes et tous,

    Je dois sauvegarder via macro excel une plage de cellules dans un fichier csv encodé en UTF 8 sans bom (en vue d'alimenter une table MySQL)

    Après de nombreuses recherches, j'ai accouché péniblement du code suivant très largement pompé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Sub saveUTF8csv()
      Dim oAdoS As Object
     
     
      Set oAdoS = CreateObject("ADODB.Stream")
     
     oAdoS.Charset = "UTF-8"
     oAdoS.Mode = 3
     oAdoS.Type = 2
     oAdoS.Open
     
     
     celultime = Cells.Find("*", , , , , xlPrevious).Row ' dernière ligne non vide
     
    lRow = 1
     lCol = 1
     iii = 1
     For iii = 1 To celultime
       oAdoS.WriteText (Sheets("export").Cells(lRow, lCol).Text)
      lCol = lCol + 1
      For i = 1 To 26 'de la première à la dernière colonne
       oAdoS.WriteText (";" & Sheets("export").Cells(lRow, lCol).Text)
       lCol = lCol + 1
      Next
      oAdoS.WriteText (vbCrLf)
      lCol = 1
      lRow = lRow + 1
    Next
     
     oAdoS.SaveToFile ActiveWorkbook.Path & "\" & "temp_utf8.csv", 2 'nom du fichier temporaire
     oAdoS.Close
     
    'sans BOM
    oAdoS.Open
    oAdoS.Type = 1 ' binaire
    oAdoS.LoadFromFile ActiveWorkbook.Path & "\" & "temp_utf8.csv"  'nom du fichier temporaire
    oAdoS.Position = 3 ' shunte les 3 octets
     
    Dim oAdoS2 As Object
    Set oAdoS2 = CreateObject("ADODB.Stream")
    oAdoS2.Open
    oAdoS2.Type = 1 ' binaire
    oAdoS.CopyTo oAdoS2
    oAdoS2.SaveToFile ActiveWorkbook.Path & "\" & SupprimerAccents(nom) & Fix(distance) & ".csv", 2
    oAdoS.Close
     Set oAdoS = Nothing
     oAdoS2.Close
     'Set oAdoS2 = Nothing
    Kill ActiveWorkbook.Path & "\" & "temp_utf8.csv" 'suppression du fichier temporaire
    filname = SupprimerAccents(coursev) & Fix(distance) & ".csv"
    MsgBox ("Exportation réussie dans le répertoire courant : " & filname)
     
    End Sub
    Je parviens donc à exporter cette plage dans un fichier csv qui si j'en crois Notepad++ est bien encodé en UTF8 sans BOM.

    Or, en fait les caractères accentués (é,à, ï...) présents dans la table n'ont absolument été convertis.
    N'ai-je rien compris à l'encodage UTF 8 ? ou, où-je fais-je erreur dans le code ?
    Merci d'avance à celles et ceux qui prendront le temps de se pencher sur mon problème
    n.

  2. #2
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    Bosoir

    un exemple avec une autre méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Option Base 1
    Sub test1()
    fichier = ThisWorkbook.Path & "\" & ThisWorkbook.Name & ".CSV"
    Set plage = ActiveSheet.Range("A4:B8")
    XLrange_to_CsV fichier, plage
    End Sub
     
    Function XLrange_to_CsV(fichier, plage)
    Dim tablo, texte As String
    tablo = plage.Value
    colcount = plage.Columns.Count
    For i = 1 To UBound(tablo)
    For col = 1 To colcount: texte = texte & tablo(i, col) & IIf(col < colcount, ";", ""): Next
    texte = texte & vbCrLf
    Next
    Open fichier For Output As #1: Print #1, texte: Close #1
    MsgBox "plage :" & plage.Address & vbCrLf & " a été enregistrée en csv dans : " & vbCrLf & fichier
    End Function
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  3. #3
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut
    Bonjour !

    Citation Envoyé par nullos Voir le message
    Après de nombreuses recherches, j'ai accouché péniblement du code suivant très largement pompé
    Pourtant juste en consultant la documentation sur MSDN, même pas besoin de pomper comme un Shadok !


    Citation Envoyé par nullos Voir le message
    si j'en crois Notepad++ est bien encodé en UTF8 sans BOM.
    Oui il faut le croire !     Le fichier est donc bon et le code à peu près …     Circulez, y a rien à voir !


    Citation Envoyé par nullos Voir le message
    Or, en fait les caractères accentués (é,à, ï...) présents dans la table n'ont absolument été convertis.
    Comment l'as-tu vérifié ?‼
    Car Notepad++ comme le Bloc-notes décodant bien l'encodage utf-8, c'est normal que les caractères y soient bien affichés !
    Par contre en pensant juste depuis l'Explorateur Windows à double-cliquer sur le fichier csv ainsi généré …

    Le fichier étant bien encodé en uft-8 sans BOM, le problème est peut-être alors du côté de l'importation SQL …


       Décapitation de ton code tant côté Excel comme côté Stream :

    • Ligne n°13 : pas de précision de classeur ni de feuille de calculs, donc c'est la feuille active …
       Par contre lignes n°19 & 22 une feuille est bien précisée (du classeur actif car il est omis) !
       Heureusement que la feuille export est déjà active pour la ligne n°13 ! …
       Juste en déclarant une variable de type Worksheet si le classeur n'est pas celui contenant le code,
       sinon il suffit d'utiliser directement le CodeName de la feuille comme dans l'exemple plus bas …

    • Si la documentation avait été consultée concernant la méthode WriteText, il n'y aurait pas eu besoin de la ligne n°25 !

    • Lignes n°15 à 28 : via le B-A-BA d'Excel ce bloc peut être simplifié en seulement 3 lignes de code en une unique boucle …

    • La ligne n°48 est en commentaire alors qu'elle ne doit pas l'être afin de libérer la mémoire utilisée par l'objet !


    Voici une démonstration du même traitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Sub Demo()
            Dim otsie As Object, Rg As Range, BILL$
            Set otsie = CreateObject("ADODB.Stream")
                otsie.Type = 1
                otsie.Open
                BILL = ThisWorkbook.Path & "\tmp"
        With CreateObject("ADODB.Stream")
                .Charset = "utf-8"
                .Open
            For Each Rg In Feuil1.Cells(1).CurrentRegion.Rows
                .WriteText Join$(Application.Index(Rg.Resize(2).Value, 1), ";"), 1
            Next
                .SaveToFile BILL, 2
                .Close
                .Type = 1
                .Open
                .LoadFromFile BILL
                .Position = 3
                .CopyTo otsie
                .Close
        End With
                Kill BILL
                otsie.SaveToFile ThisWorkbook.Path & "\Test utf-8 no BOM .csv", 2
                otsie.Close
            Set otsie = Nothing
    End Sub
    Cadeau bonus : 2 lignes de code références cinématographiques à trouver !

    _________________________________________________________________________________________________________

    Merci de cliquer sur pour chaque message ayant aidé puis sur pour clore cette discussion …

    _________________________________________________________________________________________________________
    Je suis Paris, Berlin, Nice, Bruxelles, Charlie, …

  4. #4
    Membre averti
    Homme Profil pro
    Juriste
    Inscrit en
    Mars 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Juriste
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2004
    Messages : 49
    Par défaut
    Bonjour et merci à vous deux.

    Je mesure le chemin que j'ai encore à faire
    J'apprends tout seul dans mon coin à regarder des bouts de code alors nécessairement ce que je fais c'est pas propre du tout. La doc msdn j'essaie mais généralement je comprends pas grand chose.

    Bon effectivement les caractères accentués sont bien convertis (é pour "é" par exemple), donc mon sujet était inutile, j'aurai du croire Notepad++ et ne pas croire le webmaster qui mettait en doute que mon fichier était ok pour sa base
    C'est bête avec un encodage utf8 sans bom, wordpad ou même excel auraient suffit à me convaincre..

    Marc-L, merci particulièrement pour la décapitation

    ligne 13 et ... : ok, je note

    ligne 25 : j'ai pompé honteusement cette partie de code, j'ai juste adapté le code à ma plage de données donc spa ma faute

    Lignes n°15 à 28 : ben j'ai pas les bases désolé, l'avantage c'est que je comprends à peu près le processus contrairement avec ta boucle
    autre souci c'est que sont sauvegardés les valeurs des cellules or j'ai besoin de récupérer le contenu affiché

    exemple:
    00null;xx;yy;;4;4;00:33:01;00:04:08;SEM;4;M;;96;NULL;2,14;NULL;14/01/1970;a;b;c;Bretagne;d;8,000;1970-01-148b;0;187;1970-01-14
    est avec ton code

    00null;xx;yy;;4;4;2,29282407407407E-02;2,86603009259259E-03;SEM;4;M;;96;NULL;2,14;NULL;14/01/1970;a;b;c;Bretagne;d;8;1970-01-148b;0;187;1970-01-14

    Ligne 48 : n'aurait pas dû être en commentaire, c'est encore un loupé de ma part


    Merci encore, je vais essayer de comprendre les codes fournis et m'inspirer du dernier pour simplifier et tenter de rendre un peu plus propre mon code

  5. #5
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    • Je retire mon commentaire de la ligne n°25 car dans le contexte de ton code elle est nécessaire
       même si l'on peut s'en passer comme dans le code ci-dessous …

    • Mon code précédent est plus rapide pour le cas d'un grand nombre de lignes à traiter,
       écrivant en une seule instruction une ligne de la plage,
       mais effectivement il ne convient pas dans ton contexte de colonnes horaire …
       L'astuce serait d'affecter les valeurs de la plage à une variable tableau
       puis de retraiter les colonnes horaire dans cette variable via la fonction Format.

       Sinon via une deuxième boucle, ce code remplaçant les lignes n°10 à 12 du code précédent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            For Each Rg In Feuil1.[A1].CurrentRegion.Rows
                For C = 1 To Rg.Cells.Count - 1
                    .WriteText Rg.Cells(C).Text & ";"
                Next
                    .WriteText Rg.Cells(C).Text, 1
            Next
    La variable C étant déclarée en Long en tête de procédure …

  6. #6
    Membre averti
    Homme Profil pro
    Juriste
    Inscrit en
    Mars 2004
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Juriste
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2004
    Messages : 49
    Par défaut
    Merci infiniment !

    Testé et approuvé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    Sub saveUTF8csv()
      Dim oAdoS As Object, C As Long, Rg As Range, BILL$, filname As String
     
        Set oAdoS = CreateObject("ADODB.Stream")
        oAdoS.Type = 1
        oAdoS.Open
        BILL = ThisWorkbook.Path & "\tmp"
        filname = SupprimerAccents(coursev) & Fix(distance) & ".csv"
     
        With CreateObject("ADODB.Stream")
     
        .Charset = "UTF-8"
        .Open
     
     For Each Rg In Feuil1.[A1].CurrentRegion.Rows
                For C = 1 To Rg.Cells.Count - 1
                    .WriteText Rg.Cells(C).Text & ";"
                Next
                    .WriteText Rg.Cells(C).Text, 1
            Next
     
                .SaveToFile BILL, 2
                .Close
                .Type = 1
                .Open
                .LoadFromFile BILL
                .Position = 3
                .CopyTo oAdoS
                .Close
     
        End With
     
        Kill BILL
        oAdoS.SaveToFile ActiveWorkbook.Path & "\" & SupprimerAccents(coursev) & Fix(distance) & ".csv", 2
     
        MsgBox "Sauvegarde de '" & filname & "' réussie dans le répertoire courant"
     
    End Sub

  7. #7
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut



    Pour la variable objet il manque l'instruction Close mais surtout - et encore - sa libération !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/06/2011, 17h54
  2. Réponses: 11
    Dernier message: 05/03/2011, 12h20
  3. VBA : conversion fichier texte en UTF-8
    Par philou8 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/12/2009, 18h50
  4. Conversion UTF => ISO et caractères "exotiques"
    Par tomlev dans le forum Langage
    Réponses: 7
    Dernier message: 24/03/2009, 09h39
  5. Conversion des caractères accentués
    Par chrisbill dans le forum Dreamweaver
    Réponses: 2
    Dernier message: 05/02/2009, 14h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo