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.
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
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
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.
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 ....
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é.
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
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.
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)?
Les voici:
Nom du bloc: IDENTITY_V20
Nom des attributs du bloc: Entity_Number; Common/Private_area?; Exclusive_use?_(Y/N); Lot_number; Name; Headroom; Ground(1)/Above(2)/Below(3)_ground?; Level; Area_type; S.E.M.; S.I.M.;
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.
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.
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.
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+.