Traiter un fichier ASCII

Résolu
Ludovic1988 Messages postés 18 Statut Membre -  
Ludovic1988 Messages postés 18 Statut Membre -
Bonjour,

Mon but est d'extraire d'un fichier dxf (fichier de type ASCII) une série d'information facilement identifiable.

Etant donné le nombre important de ligne (plus de 125 000 pour un petit fichier), il n'est pas concevable de le traiter via excel. C'est là que se situe mon problème.

Quelqu'un saurait-il me donner une piste pour y arriver?

Voici un peu plus de détails concernant le ficher et les informations recherchées:

Le fichier dxf est un fichier de DAO.

Il se compose de plusieurs sections : Classes, Tables, Block, Entities et Objets.

A chaque fois que l'on insère un block dans le dessin, on retrouve une référence à ce block dans le section Entities. Dans mon cas, les blocks ont des attributs (variables attachées au block). C'est dans la section Entities, sous la référence du block que je les retrouve.

Mon but est d'extraire, sous forme de tableau, le nom du block, le nom des attributs et leurs valeurs.

10 réponses

  1. Yoda
     
    Salut,

    J'ai eu le temps de peaufiner le programme
    Tu trouveras ci-dessous le code VBA de la macro.
    Mode d'emploi:
    Après le bloc de définition des variables (Dim), il y a trois variables à renseigner:
    '*****************************************************************
    'initialiser les 3 variables ci-dessous***************************
    '*****************************************************************
    'nom_fich_inp = nom complet du fichier DXF
    nom_fich_inp = "C:\Documents and Settings\X\Mes documents\Fichier.dxf"

    'nom_fich_out= nom complet ddu fichier TXT ou CSV à créer
    nom_fich_out = "C:\Documents and Settings\X\Mes documents\Fichier.txt"

    'nom_bloc=nom du bloc à traiter
    'mettre * pour tous
    nom_bloc = "*"
    '*****************************************************************
    '****************************************************************

    Changes les nom des fichiers, et éventuellement le nom du bloc à traiter.

    Lances le programme. Un message t'avertit quand c'est fini.
    Le fichier généré est un fichier texte du type CSV, facilement exploitable avec Excel.
    Chaque ligne contient tout ce qui est intéressant de connaitre dans un bloc.
    Une fois importé dans une feuille Excel, tu pourras filtrer, supprimer des colonnes, trier, ...etc

    Copie/Colle cette macro dans un module.
    Fais un essai et rends-moi compte.

    Sub import_dxf()

    Dim lig1 As String, lig2 As String
    Dim nom_fich_inp As String, nom_fich_out As String
    Dim nom_bloc As String
    Dim bloc As String, calque As String, att_c As String, att_n As String, att_v As String
    Dim coordX As String, ccordY As String, coordZ As String
    Dim nb_att As Integer, extrac As String
    Dim l_c As Long 'compteur de lignes pour debogage

    '*****************************************************************
    'initialiser les 3 variables ci-dessous***************************
    '*****************************************************************
    'nom_fich_inp = nom complet du fichier DXF
    nom_fich_inp = "C:\Documents and Settings\X\Mes documents\Fichier.dxf"

    'nom_fich_out= nom complet ddu fichier TXT ou CSV à créer
    nom_fich_out = "C:\Documents and Settings\fmoretti\Mes documents\Attributs.txt"

    'nom_bloc=nom du bloc à traiter
    'mettre * pour tous
    nom_bloc = "*"
    '*****************************************************************
    '*****************************************************************

    '**********************************
    'Debut du programme d'extraction***
    '**********************************

    Close
    Open nom_fich_inp For Input As #1
    Open nom_fich_out For Output As #2

    'recherche de la section "ENTITIES"
    lig1 = ""
    lig2 = ""
    l_c = 0
    While Not (lig2 = "ENTITIES")
    Line Input #1, lig1
    Line Input #1, lig2
    l_c = l_c + 2
    lig2 = UCase(Trim(lig2))
    Wend

    Do
    If lig2 = "INSERT" Then ' c'est un bloc
    calque = "": bloc = "": coordX = "": coordY = "": coordZ = "": nb_att = 0
    lig1 = "999"
    'MsgBox l_c
    While val(lig1) > 0

    Select Case val(lig1)

    Case 8 'nom du calque
    calque = lig2

    Case 2 'nom du bloc
    bloc = lig2

    Case 10
    coordX = lig2

    Case 20
    coordY = lig2

    Case 30
    coordZ = lig2

    Case 66
    nb_att = val(lig2)

    End Select

    'lire 2 lignes
    Line Input #1, lig1
    Line Input #1, lig2
    l_c = l_c + 2
    Wend 'si lig1=0 sortie de boucle

    If (Trim(UCase(nom_bloc)) = Trim(UCase(bloc))) Or Trim(UCase(nom_bloc)) = "*" Then

    'traitement
    extract = "" 'initialisation

    'choisir les données à transferer
    extract = extract & Chr(34) & calque & Chr(34) & "," 'calque du bloc
    extract = extract & Chr(34) & bloc & Chr(34) & "," 'nom du bloc
    extract = extract & coordX & "," 'X du point d'insertion
    extract = extract & coordY & "," 'Y du point d'insertion
    extract = extract & coordZ & "," 'Z du point d'insertion

    If nb_att > 0 Then

    Do
    If lig2 = "ATTRIB" Then 'c'est un attribut
    'MsgBox l_c

    Do
    Select Case val(lig1)

    Case 8 'nom du calque
    att_c = lig2

    Case 2 'nom attribut
    att_n = lig2

    Case 1 'valeur attribut
    att_v = lig2

    End Select
    'lire 2 lignes
    Line Input #1, lig1
    Line Input #1, lig2
    l_c = l_c + 2
    Loop Until val(lig1) = 0 'fin des attributs

    'choisir les données à transferer
    extract = extract & Chr(34) & att_c & Chr(34) & "," 'calque attribut
    extract = extract & Chr(34) & att_n & Chr(34) & "," 'nom attribut
    extract = extract & Chr(34) & att_v & Chr(34) & "," 'valeur attribut

    End If

    Loop Until UCase(Trim(lig2)) = "SEQEND"

    Else
    'MsgBox "Bloc " & bloc & " n'a pas d'attributs"
    'Close
    'End
    End If 'If nb_att > 0

    Print #2, extract

    End If 'If nom_bloc = bloc

    End If 'If lig2 = "INSERT"

    If lig2 <> "INSERT" Then
    'lire 2 lignes
    Line Input #1, lig1
    Line Input #1, lig2
    lig2 = UCase(Trim(lig2))
    l_c = l_c + 2
    End If
    Loop While Not EOF(1)
    Close
    MsgBox "FINI"
    End Sub
    1
    1. Ludovic1988 Messages postés 18 Statut Membre
       
      Ca fonctionne super bien!!! ;)

      J'ai encore une petite question, en espérant ne pas trop abuser de ton temps. Il y a-t-il des différences dans la manière de coder entre le VBA et le VB? Cette question car j'ai essayé de faire fonctionner ce code dans Microsoft Visual Studio mais il y a une série de fonction qu'il ne connaît pas et qu'il faut du coups modifier.
      0
    2. Yoda
       
      Je suis heureux que ça marche.

      Le VBA se rapproche d'avantage du VB6 que du VB.NET.
      Si tu compiles ce programme avec VB6, pas de problème parce qu'il n'y a aucune référence aux objets Excel.

      Sous VB.NET (Visual Basic Express 2010 par exemple), il y a quelques fonctions ou instructions à modifier. La syntaxe est légèrement différente.

      Mais pour compiler ce programme, quel que soit le langage, il faudrait le rendre un peu plus convivial: création d'une fenêtre (UserForm) avec quelques contrôles comme une TextBox pour la saisie du nom de fichier DXF, une autre pour le fichier TXT, un bouton EXECUTER, un bouton ANNULER, ...etc.

      En effet, dans un programme exe, les éléments variables comme les noms de fichiers doivent être saisis au moment de l'exécution, et pas en dur dans le code comme dans un langage interprété comme VBA.

      Si tu mets en place ce genre d'interface, je t'aidera à adapter le code.
      En attendant, toute application capable d'executer du VBA fera l'affaire, aussi bien Excel que Word ou Autocad ou ....

      A+.
      0
    3. Ludovic1988 Messages postés 18 Statut Membre
       
      Ok je vais essayer de me familiariser avec VB.net. Je reviendrai vers toi dès que je bloque de trop. Merci encore pour ton aide.
      0
  2. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Bonjour,

    si excel 2003 et anterieur, 125000 lignes pas possible mais excel2007-2013 si

    autrement pouvez-vous mettre un de ces fichiers a dispo sur https://www.cjoint.com/
    0
  3. Ludovic1988 Messages postés 18 Statut Membre
     
    Voici le fichier : https://www.cjoint.com/?DKtojXMLnyb

    Excel peut traiter un maximum de 1 000 000 de lignes par feuille. Or il est probable qu'un fichier dxf dépasse le million de ligne.
    0
  4. f894009 Messages postés 17417 Date d'inscription   Statut Membre Dernière intervention   1 717
     
    Re,
    pas tres parlant.

    une référence à ce block dans le section Entities donnez un exemple, car pas trouve de nom de block
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. Ludovic1988 Messages postés 18 Statut Membre
     
    Voici un exemple extrait du fichier précédent: https://www.cjoint.com/?DKtqcexYwxn

    Les informations a extraire sont suivies de ????????????????????????????? pour les faire ressortir.

    0
    SECTION
    2
    ENTITIES-> signifie que l'on se trouve dans la section Entities

    0
    INSERT -> signifie qu'un block est inséré dans le dessin

    La suite du code est la description des attributs du block.

    Chaque attribut est décrit de la manière suivante:

    0
    ATTRIB
    ....
    1
    Valeur de l'attribut
    ....
    2
    Nom de l'attribut
    .....

    Cette nomenclature se répète autant de fois qu'il y a d'attribut.

    J'espère que c'est déjà plus claire.

    Merci!
    0
  7. Yoda
     
    Bonjour,

    Si ton Autocad n'est pas une version LT, il existe des petits programmes en Lisp qui font exactement ce que tu cherches.

    Est-ce que tu sais comment charger et exécuter un Lisp?
    0
  8. Ludovic1988 Messages postés 18 Statut Membre
     
    Je ne connais pas le lisp. Du moins je n'ai jamais codé en lisp.

    Par contre, le système que j'essaye de mettre en place ne peut fonctionner qu'à partir d'un fichier dxf généré par tout programme de DAO de base (Autocad, Mensura, Covadis,...). Je dois donc faire appel à un système qui n'à aucun lien avec ces programmes. Ceci afin de limiter les manipulations du dessinateur et assurer une universalité.
    0
    1. Yoda
       
      Désolé du retard,

      Je pense pouvoir t'aider en écrivant un petit programme Basic (ou VBA ou VB6), à moins que tu ne sois capable de le faire toi-même.
      Voici le principe
      - lire le fichier ligne par ligne
      - ignorer jusqu'à ENTITIES
      - ensuite lire les lignes par paires
      - si ligne1="0" et ligne2="INSERT" c'est un bloc

      si c'est le cas continuer à lire les lignes 2 par 2
      la première ligne est un entier appelé code de groupe
      la seconde est la valeur associée
      voici les plus interessants
      8
      'nom du calque'
      2
      'nom du bloc'
      10
      'coord. X insertion
      20
      'coord. Y
      30
      'coord Z
      66
      'si >0 nombre d'attributs

      si des attributs existent
      0
      ATTRIB ; debut attributs
      2
      'nom attribut'
      1
      'valeur attribut
      0
      SEQEND ; Fin attributs

      et comme ça jusqu'à la fin du fichier

      A+
      0
    2. Ludovic1988 Messages postés 18 Statut Membre
       
      En VBA, je me débrouille assez bien. Mais je ne pense pas qu'il soit possible de traiter le ficher ASCII ligne par ligne sans passer par l'importation du fichier en question dans une feuille du classeur. Est-ce que je me trompe? Si c'est possible alors mon problème est résolu.

      En ce qui concerne le petit programme basic, je n'ai aucune connaissance dans des langages autres que VBA du coups je ne sais pas vraiment par quoi commencer. Mais je suis très intéressé d'apprendre si quelqu'un me donne quelques pistes.

      Merci encore pour vos conseils ;)
      0
    3. Yoda
       
      Salut,

      Un fichier dxf est fichier texte, donc on ne peux le lire que séquentiellement ligne par ligne.
      Importer directement un dxf dans une feuille excel, c'est possible (si le fichier n'est pas trop grand), mais c'est pas très exploitable. Il est plus intéressant de lire le fichier avec un petit programme en VBA et ne stocker dans la feuille excel que le resultat de l'extraction.

      Tu as cité Mensura et Covadis, Ces deux logiciels fonctionnent sous Autocad. Donc un programme Lisp ferait l'affaire.

      Je regarde dans ma bibliothèque si je peux adapter le Lisp en VBA.
      Est ce que les blocs avec attributs sont connus d'avance (nom du bloc, nom des attributs), comme par exemple bloc 1POINT, attributs MAT (matricule) et ALT (altitude)?


      A+
      0
    4. Yoda
       
      Salut,

      J'ai réussi à adapter le Lisp d'extraction des attributs en VBA.
      Dis moi si tu es toujours intéressé.

      A+
      0
    5. Ludovic1988 Messages postés 18 Statut Membre
       
      Excuse moi pour le retard,

      Oui je suis toujours intéressé! Et pou répondre à ton avant dernier message, oui les nom des blocs et les noms des attributs sont connus d'avance.
      0
  9. Ludovic1988 Messages postés 18 Statut Membre
     
    Super un tout grand merci pour ton temps!!! Je regards ca et je te tiens au courant.
    0
  10. Ludovic1988 Messages postés 18 Statut Membre
     
    Voici le programme finalisé (https://www.cjoint.com/?DLbpbXMl0hK

    Si vous avez des remarques à me faire sur ma manière de programmer, surtout, n'hésitez pas ;)
    0
    1. Yoda
       
      Bonjour,

      Je suis intéressé, mais le lien ne marche pas :-(

      A+
      0
    2. Ludovic1988 Messages postés 18 Statut Membre
       
      En effet, voici un nouveau : https://www.cjoint.com/?DLbpxgQlWLR
      0
      1. Yoda > Ludovic1988 Messages postés 18 Statut Membre
         
        Je l'ai !

        Je n'ai pas vb.Net là ou je me trouve actuellement, je regarderai ce soir à la maison, promis.

        A+
        0
  11. Yoda
     
    Bonjour,

    J'ai galéré un peu pour ouvrir le projet, j'avais des erreurs au chargement des dialogues.
    Finalement j'ai réussi et voici mes remarques.

    Sur l'ergonomie.
    Visiblement ce n'est pas fini, alors difficile de donner une appréciation.
    L'utilisation des menus déroulants et des boutons qui font double emploi me dérange un peu.
    Le menu File, en l'occurrence ne sert à rien.
    Le menu Tools n'a qu'une seule commande Settings, donc pas très utile.
    Les textes des boutons ne sont pas assez explicites, on ne voit pas à quoi ils servent au premier coup d'oeil.
    Par exemple, au dessus du champ texte de Select File, je mettrai mettrai un Label "Select Input File (DXF)", je laisserai le champ texte visible mais non modifiable manuellement.
    Par contre la barre de progression, je la ferai apparaitre seulement à l'exécution.

    Pour la première feuille Settings, je n'ai pas compris toutes les options possibles.
    En effet, le programme ne fait qu'extraire des Blocs et leurs attributs, mais peut-être que ce programme va évoluer?
    La couleur du texte des boutons (blanc sur blanc) n'est pas assez contrastée.

    Pour la seconde feuille Extract Settings.
    Dans le premier encadré Bloc Informations, il faudrait supprimer l'option Nombre d'attributs, parce que dans le dxf, ce nombre ne peut avoir que deux valeurs, zéro pour "sans attributs", non nul pour "attributs suivent".

    Pour le deuxième encadré Attribut Informations, il ne devrait y avoir que des choix portant sur des informations communes à tous les blocs comme Nom du calque, Nom de l'Attribut, Valeur de l'Attribut...
    Comme c'est fait là, le programme listera uniquement les attributs portant un Label précis, donc uniquement applicable à un type de dessin.
    Si on ne veut s'intéresser qu'à un Bloc bien précis, il faudrait donner le nom du bloc à extraire avant tout, puis éventuellement lister les attributs et faire une sélection parmi eux. Dans l'état actuel, ce programme n'est pas conçu pour ça.

    En ce qui concerne l'écriture du code, je dirai que à partir du moment où on ne travaille pas en équipe, à chacun son style pourvu que ça marche.

    Cordialement
    0
    1. Ludovic1988 Messages postés 18 Statut Membre
       
      Ok merci pour ces remarques. Le programme devrait en effet évoluer. Ce n'est qu'une première étape. Tes remarques me seront donc très utiles pour le développer.
      0