Traiter un fichier ASCII

Résolu/Fermé
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015 - 19 nov. 2014 à 12:54
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015 - 2 déc. 2014 à 20:44
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.


A voir également:

10 réponses

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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
21 nov. 2014 à 16:00
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
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
21 nov. 2014 à 17:02
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
f894009 Messages postés 17206 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 22 novembre 2024 1 709
19 nov. 2014 à 13:58
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
19 nov. 2014 à 14:06
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
f894009 Messages postés 17206 Date d'inscription dimanche 25 novembre 2007 Statut Membre Dernière intervention 22 novembre 2024 1 709
19 nov. 2014 à 14:31
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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
19 nov. 2014 à 16:03
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
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
19 nov. 2014 à 17:43
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
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
20 nov. 2014 à 11:40
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
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
Salut,

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

A+
0
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
21 nov. 2014 à 08:55
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
21 nov. 2014 à 11:41
Super un tout grand merci pour ton temps!!! Je regards ca et je te tiens au courant.
0
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
1 déc. 2014 à 14:56
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
Bonjour,

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

A+
0
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
1 déc. 2014 à 15:16
En effet, voici un nouveau : https://www.cjoint.com/?DLbpxgQlWLR
0
Yoda > Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
1 déc. 2014 à 15:34
Je l'ai !

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

A+
0
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
Ludovic1988 Messages postés 18 Date d'inscription mercredi 19 novembre 2014 Statut Membre Dernière intervention 21 février 2015
2 déc. 2014 à 20:44
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