Invité YouuNess Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Bonjour Voila, j'ai un petit besoin qui sera, je l'espère, un bon défis pour les programmeurs sous Autocad Je dispose de plusieurs milliers de dessin autocad (archives de plusieurs années de travaux topographiques) classés pas dossiers numéroté et je souhaite avoir un idée d'ensemble sur leurs emplacement respectifs Je cherche donc une macro (vba de préférence) qui puisse scanner les répertoires (et sous-répertoire) de se renseigner sur le contenu des fichiers DWG et d'y récupérer les coordonnées du point centralUn ficher texte sera généré qui comportera un tableau dans lequel se trouvera le nom du dossier, les différents fichiers DWG (s'il en existe plusieurs); les coordonnées du centre de chaque dessin J'espère que je me suis bien expliqué et que la tache aura intéressé le plus de monde
bryce Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Bonjour, Qu'est-ce que tu appelles exactement le point central du dessin ? :casstet: Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant
Invité YouuNess Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 En fait j'ai juste besoin de savoir la situation approximative du dessinSi tu veux, je propose de faire le zoom à l'étendu et d'extraire les coordonnées du point central de l'écran... ce n'est qu'une proposition mais les coordonnées de n"importe quel objet du dessin me suffiront dans la plupart des cas
rebcao Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Bonsoir, Comme la variable système VIEWCTR en coordonnées LAMBERT depuis le SCG ? Et la variable système VIEWSIZE pourrait donner une idée de l'étendue ? Christian Formateur, Consultant Expert AutoCAD, REVIT MEP, INVENTOR, télécharger , des Outils AutoCAD...cad123 @ wanadoo.fr (enlever les espaces de part et d'autre de @)
Invité YouuNess Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 @ Christian Bon début! :) Est-ce qu'il est nécessaire d'ouvrir le dessin pour pourvoir utiliser ces deux variables?je rappelle qu'il s'agit de plusieurs milliers de fichiers :casstet:
bryce Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Dans la mesure où les dessins n'ont pas forcément été enregistrés en zoom étendu et dans le SCG, ça me paraît indispensable d'ouvrir chaque dessin et d'effectuer ces opérations avant de récupérer la valeur des variables mentionnées par rebcao. C'est faisable en script + lisp, mais ça moulinerait probablement quelques heures... Peut-être qu'en VB ou autre langage il serait possible d'effectuer ces tâche un peu plus rapidement dans une instance AutoCAD "invisible", mais je ne m'y connais pas assez dans ces langages pour l'affirmer. Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant
(gile) Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Salut, Il est possible d'utiliser l'ActiveX ObectDBX en Visual LISP ou VBA ou la méthode Database.ReadDwgFile en .NET pour accéder à la base de donnée d'un dessin fermé, mais ces méthodes ne permettent pas d'accéder à l'éditeur d'AutoCAD donc de lancer des commandes ou d'interroger des variables système. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bryce Posté(e) le 20 février 2011 Posté(e) le 20 février 2011 Merci de l'info (gile) :) Donc a priori pas le choix, il faut ouvrir chaque dessin... Je pense que si j'étais dans ton cas je passerais par un simple script, qui exécuterait pour chaque dessin à traiter les actions suivantes :- ouvrir le dessin- zoom étendu- passer dans le SCG- lancer un petit lisp qui aurait pour mission de lire un certains nombre de variables (dwgprefix, dwgname, viewctr, viewsize et/ou extmin - extmax, ...) et d'aller les écrire dans un fichier texte donné- fermer le dessin. Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant
(gile) Posté(e) le 21 février 2011 Posté(e) le 21 février 2011 Re, Il est possible de faire quelque chose sans utiliser les variables système. Je donne une procédure envisageable en VBA (puisque cela semble être le souhait malgré le choix du forum). - Créer un fichier texte ouvert en écriture.- Créer une instance d'ObjectDBX.AxDbDocument.- Ouvrir chaque fichier avec cette instance.- Parcourir l'espace objet du dessin.- Affecter les valeurs des points MinPoint et MaxPoint de l'emprise de la première entité (méthode GetBoundingBox) à deux variables.- Pour chaque entité suivante exécuter GetBoundingBox et modifier les valeurs des deux variables si les coordonnées retournées par GetBoundingBox sont inférieures ou supérieures à celles des variables.- Quand tout l'espace objet aura été scanné, les valeurs des variables seront égales à celles des variables système EXTMIN et EXTMAX, faire la moyenne de ces deux point et l'écrire dans le fichier texte.- Quand tous les DWG auront été traités, supprimer l'instance d'ObjectDBX et libérer les ressources. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Invité YouuNess Posté(e) le 21 février 2011 Posté(e) le 21 février 2011 Merci les gars pour toutes vos suggestionsJ'aurai préféré une solution toute prête mais bon, je vois qu'il faut mettre la main dans la pâte :D Je vais donc essayer de faire un peu de programmation lisp ou vba (que je maitrise mieux) peu importe si ça devra tourner toute la nuit, l'essentiel est d'avoir un résultat correctJ'espère que j'aurai un peu de temps d'ici là je vous mettrai au courant si ça marche
(gile) Posté(e) le 22 février 2011 Posté(e) le 22 février 2011 Je te propose un LISP qui devrait faire ce que tu veux. Attention, même si ça devrait être beaucoup plus rapide qu'avec un script, le traitement risque de prendre un peu de temps si tu as beaucoup de fichiers. Mode d'emploi :- charger les routines dans un dessin vierge (seuls les fichier fermés seront traités)- lancer la commande ARCHIVE- spécifier le nom du fichier .csv de sortie (lisible avec Excel ou OpenOffice ou le bloc-note).- choisir le répertoire racine des répertoires à traiter. Le nom de chaque fichier en cours de traitement s'affiche sur la ligne commande. Essaye d'abord avec un dossier qui ne contient pas trop de fichiers et sous dossiers. ;; DirBox (Patrick_35) ;; retourne le chemin complet du dossier spécifé ;; ;; Arguments ;; Message : le méssage à afficher dans la boite de dialogue ;; Chemin : le chemin du répertoire source ;; Drapeau : la somme des codes binaires suivants ;; ;; Valeur du Drapeau ;; 0 = Valeur par défaut ;; 1 = BIF_RETURNONLYFSDIRS = Seulement les fichiers système ;; 2 = BIF_DONTGOBELOWDOMAIN = Interdit d'explorer en dehors du domaine ;; 4 = BIF_STATUSTEXT = Inclure un secteur de statut. La fonction de rappel de service peut placer le texte de statut en envoyant des messages à la zone de dialogue. Ce drapeau n'est pas soutenu quand BIF_NEWDIALOGSTYLE est indiqué. ;; 8 = BIF_RETURNFSANCESTORS = Seulement les sous Dossiers ;; 16 = BIF_EDITBOX = Inclure une commande d'édition dans la zone de dialogue ;; 32 = BIF_VALIDATE = Verifie si l'utilisateur dactylographie un nom inadmissible dans la boîte d'édition ;; 512 = BIF_NONEWFOLDERBUTTON = Ne pas inclure le bouton Créer un nouveau dossier ;; 4096 = BIF_BROWSEFORCOMPUTER = Autorise à parcourir le réseau ;; 8192 = BIF_BROWSEFORPRINTER = Seulement le choix d'une imprimante ;; 16384 = BIF_BROWSEINCLUDEFILES = Montre tout ;; = BIF_BROWSEINCLUDEURLS = Montrer les raccourcis, Les drapeaux BIF_USENEWUI et de BIF_BROWSEINCLUDEFILES doivent également être placés ;; = BIF_NEWDIALOGSTYLE = Employer la nouvelle interface utilisateur ;; = BIF_NOTRANSLATETARGETS = Quand l'article choisi est un raccourci, renvoyer le PIDL du raccourci lui-même plutôt que sa cible. ;; = BIF_SHAREABLE = Peut montrer les ressources en commun sur les systèmes à distance. Le drapeau de BIF_NEWDIALOGSTYLE doit également être placé. ;; = BIF_UAHINT = Une fois combiné avec BIF_NEWDIALOGSTYLE, ajoute un conseil d'utilisation à la zone de dialogue au lieu de la boîte d'édition. BIF_EDITBOX dépasse ce drapeau. ;; = BIF_USENEWUI = Employer la nouvelle interface utilisateur, y compris une boîte d'édition (defun DirBox (Message Chemin Drapeau / rep sh) (setq sh (vlax-create-object "Shell.Application")) (if (setq rep (vlax-invoke sh 'browseforfolder 0 Message Drapeau Chemin) ) (setq rep (vlax-get-property (vlax-get-property rep 'self) 'path)) (setq rep nil) ) (vlax-release-object sh) rep ) ;; gc:GetDrawingExtents ;; Affecte aux symboles les points inférieur gauche et supérieur droit de l'étendue du dessin ;; ;; Arguments ;; doc : le document à traiter (vla-object) ;; _outputExtMinSym : un symbole quoté auquel sera affecté la valeur du point inférieur gauche ;; _outputExtMaxSym : un symbole quoté auquel sera affecté la valeur du point supérieur droit (defun gc:GetDrawingExtents (doc _outputExtMinSym _outputExtMaxSym / tmpMinPt tmpMaxPt) (vlax-for o (vla-get-ModelSpace doc) (or (vl-catch-all-error-p (vl-catch-all-apply 'vla-GetBoundingBox (list o 'tmpMinPt 'tmpMaxPt))) (if (eval _outputExtMinSym) (progn (set _outputExtMinSym (mapcar 'min (eval _outputExtMinSym) (vlax-safearray->list tmpMinPt)) ) (set _outputExtMaxSym (mapcar 'max (eval _outputExtMaxSym) (vlax-safearray->list tmpMaxPt)) ) ) (progn (set _outputExtMinSym (vlax-safearray->list tmpMinPt)) (set _outputExtMaxSym (vlax-safearray->list tmpMaxPt)) ) ) ) ) ) ;; gc:Getfiles ;; Retourne la liste du (ou des) fichier(s) spécifié(s) dans le dossier (ou disque) et ses sous dossiers ;; ;; Arguments ;; dir : le chemin complet de répertoire racine pour la recherche ;; pat : un modèle pour le type de fichier (accepte les caractères génériques) (defun gc:GetFiles (dir pat) (apply 'append (cons (if (vl-directory-files dir pat) (mapcar (function (lambda (x) (strcat dir "\\" x))) (vl-directory-files dir pat) ) ) (mapcar (function (lambda (x) (gc:GetFiles (strcat dir "\\" x) pat))) (vl-remove ".." (vl-remove "." (vl-directory-files dir nil -1)) ) ) ) ) ) ;; gc:GetAxDbDoc ;; Accéder à un dessin fermé ;; Retourne un objet IAxDbDocument si le document est trouve ;; nil si le document n'a pu être trouvé ou s'il est ouvert ;; ;; Argument : ;; Le chemin complet du fichier (defun gc:GetAxDbDoc (filename / axdbdoc release) (setq axdbdoc (vlax-create-object (if ( "ObjectDBX.AxDbDocument" (strcat "ObjectDBX.AxDbDocument." (itoa release)) ) ) ) (if (vl-catch-all-apply 'vla-open (list axdbdoc filename) ) (not (vlax-release-object axdbdoc)) axdbdoc ) ) ;; gc:lst2str ;; Concatène une liste et un séparateur en une chaine ;; ;; Arguments ;; lst : la liste à transformer en chaine ;; sep : le séparateur (defun gc:lst2str (lst sep) (if (cdr lst) (strcat (vl-princ-to-string (car lst)) sep (gc:lst2str (cdr lst) sep) ) (vl-princ-to-string (car lst)) ) ) ;; ARCHIVE ;; Inscrit dans un fichier CSV les coordonnées du centre de l'étendue ;; du dessin pour chaque dessin du répertoire et des sous-répertoires (defun c:ARCHIVE (/ *error* filename dirname len sep file doc minpt maxpt) (vl-load-com) (defun *error* (msg) (and msg (or (= msg "Fonction annulée") (princ (strcat "Erreur: " msg)) ) ) (and file (close file)) (vl-catch-all-apply 'vlax-release-object (list doc)) (princ) ) (if (and (setq filename (getfiled "Spécifiez le ficher d'extraction" (getvar 'dwgprefix) "csv" 1)) (setq dirname (DirBox "Spécifier le dossier à traiter" "" 512)) ) (progn (setq len (1+ (strlen dirname)) sep (vl-registry-read "HKEY_CURRENT_USER\\Control Panel\\International" "sList") file (open filename "w") ) (write-line (strcat dirname sep "X" sep "Y" sep "Z") file) (foreach f (gc:GetFiles dirname "*.dwg") (print f) (if (setq doc (gc:GetAxDbDoc f)) (progn (setq minpt nil maxpt nil ) (gc:GetDrawingExtents doc 'minpt 'maxpt) (write-line (strcat (strcat "." (substr f len)) sep (gc:lst2str (mapcar (function (lambda (x1 x2) (/ (+ x1 x2) 2))) minpt maxpt) sep) ) file ) (vlax-release-object doc) ) ) ) ) ) (*error* nil) ) Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bryce Posté(e) le 22 février 2011 Posté(e) le 22 février 2011 Super intéressant ! :o De mon côté j'ai testé "à l'ancienne" avec un script qui effectue sur chaque dessin les opérations suivantes : _tilemode 1 _ucs _w _zoom _e (setq chemin (getvar "dwgprefix")) (setq fichier (getvar "dwgname")) (setq centre (getvar "viewctr")) (setq basgauche (getvar "extmin")) (setq hautdroite (getvar "extmax")) (setq fichiercsv (open "c:/temp/test.csv" "a")) (write-line (strcat chemin fichier ";" (rtos (car centre) 2 2) ";" (rtos (cadr centre) 2 2) ";" (rtos (car basgauche) 2 2) ";" (rtos (cadr basgauche) 2 2) ";" (rtos (car hautdroite) 2 2) ";" (rtos (cadr hautdroite) 2 2)) fichiercsv) (close fichiercsv) _close _y J'ai testé les 2 méthodes sur 7 fichiers (pas assez, mais bon...) assez gros (19.2Mo au total) pour voir s'il y a une différence de rapidité significative, et après plusieurs essais je conclue que ton lisp est un poil plus rapide : 28-30s, contre 30-32s pour le script. :) Edit: quand j'active les smileys, le message ne s'affiche pas correctement... [Edité le 22/2/2011 par bryce] Brice, formateur AutoCAD - Inventor - SolidWorks - ZWCad - DraftSight - SketchUp indépendant
(gile) Posté(e) le 22 février 2011 Posté(e) le 22 février 2011 Le LISP devrait faire la différence sur un nombre plus important de fichiers. Le script est plus rapide pour récupérer les données mais c'est l'ouverture de chaque fichier qui prendra du temps. Avec ObjectDBX, on n'ouvre pas les fichiers dans AutoCAD, mais il faut parcourir tout l'espace objet pour récupérer l'emprise de chaque entité (et dans ce cas c'est plus le nombre d'entités que le "poids" du fichier qui intervient). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Invité YouuNess Posté(e) le 23 février 2011 Posté(e) le 23 février 2011 @ (gile) Merci beaucoup c'est plus que je n'espérai!Cela fait longtemps que je voulez apprendre le LISP, avec votre routine je m'y forceraiIl a fallu tout de même changer son nom car la commande "archive" existe déjà chez moiJe l'ai testé sur un petit répertoire et ça marche à merveille... j'attends la nuit pour la lancer sur le gros volume car je ne sais pas combien de temps ça va prendre et s'il est possible de l'arrêter en cours de route D'ici là (et avec votre permission) je me permet de l'étudier et d'y effectuer quelques améliorations (de forme et non de fond) :D
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant