-
Compteur de contenus
1 113 -
Inscription
-
Dernière visite
-
Jours gagnés
42
Type de contenu
Profils
Forums
Calendrier
Blogs
Tout ce qui a été posté par Luna
-
Rotation de N Blocs en fonction d une Valeur d Attribut
Luna a répondu à un(e) sujet de lecrabe dans Routines LISP
Et bien justement j'ai été étonné mais j'avais eu un soucis à la création d'un bloc (la case de l'échelle uniforme s'est cochée toute seule >n<) et j'ai juste fait un (entmod) sur l'insertion du bloc en question et je pouvais tout à fait forcer les valeurs en X, Y, Z de manière indépendante via la liste DXF donc même si depuis la palette des propriétés on ne peut pas, la liste DXF ne l'interdit absolument pas donc tant mieux !! Alors du coup j'ai déjà vu passer les routines ATTIN / ATTOUT mais sans vraiment regarder de plus près...Le principe consiste je présume de récupérer des valeurs depuis un fichier Excel / CSV avec une correspondance du genre (nom attribut . valeur) ? Pour le coup, j'avais en tête d'écrire un programme relativement basique et qui fait confiance à l'utilisateur (parce que c'est difficile de contrôler si la valeur de l'attribut ROTATION est en grade ou en degrés donc la seule solution c'est de supposer que le format des unités est le même entre le format défini dans le dessin et celui renseigné dans l'attribut) qui nécessite de sélectionner un bloc de référence. Depuis une boîte de dialogue qui aura la liste des attributs du blocs, on aura une liste déroulante pour chaque attribut afin de l'affecter à une propriété (et des radio-button pour désactiver les attributs sans relation avec les propriétés), une fois qu'on a bien tout paramétrer, on lance le programme soit sur la pré-sélection, soit une sélection manuelle, soit toutes les occurrences du bloc (dans le même espace) et je filtre pour le faire fonctionner sur blocs standards et dynamiques Comme cela, le programme s'adaptera à n'importe quel nom de bloc, au nombre d'attribut et leur nom ainsi que leur relation avec les propriétés :3 La seule question que je ne maîtrise pas encore c'est si je dois conserver les paramètres définis dans la boîte de dialogue dans le cas où on sélectionne le même bloc pour ne pas avoir à re-paramétrer les liaisons attributs/propriétés mais bon, je verrais cela à la fin ^^ Chat sera sûrement utile je pense au vu des demandes sur le sujet xD Bisous, Luna -
Rotation de N Blocs en fonction d une Valeur d Attribut
Luna a répondu à un(e) sujet de lecrabe dans Routines LISP
Coucou pat, Vouih absolument ! Je n'ai pas vraiment pensé à mettre un gestionnaire d'erreur si un réseau parvient à se glisser dans la sélection lorsque je récupère le nom de la définition de bloc mais bon...un réseau ne possède pas d'attribut donc il se fait éjecter de la sélection illico presto xD Mais comme je n'applique aucun filtre sur le nom du bloc en question, les blocs standards et dynamiques sont pris en comptes (et les réseaux aussi du coup) et après les attributs sont atteignables de la même manière dynamique ou pas. Au final je ne récupère le nom du bloc que pour le message de fin qui liste le nom des blocs ayant été modifiés, c'est de la broderie essentiellement ^^ Mais au vu de la demande sur le passage d'une information contenu dans les attributs d'un bloc pour modifier une propriété du bloc en question, je vais essayer de me pencher sur la question pour générer une BdD un peu jolie et pouvoir faire mumuse avec pour implémenter les valeurs d'attributs dans une propriété des blocs sélectionner en prenant en compte toutes les propriétés modifiables :3 Le concept devrait aller vite mais la gestion des données pour éviter les soucis va être amusante ! Bref cela m'évitera de créer une commande ATT... pour chaque propriété et nom d'attribut de chacun... la généralisation c'est plus efficace ! Bisous, Luna -
Rotation de N Blocs en fonction d une Valeur d Attribut
Luna a répondu à un(e) sujet de lecrabe dans Routines LISP
Vouih décidément je me suis levée du pied gauche ce matin >w< Il manquait une conversion (atof) de la valeur de l'attribut vers une valeur numérique. Si le nom de tes étiquettes correspond bien (j'ai testé cette fois-ci) cela devrait fonctionner. J'ai re-modifié le code ci-dessus. Bisous, Luna -
Rotation de N Blocs en fonction d une Valeur d Attribut
Luna a répondu à un(e) sujet de lecrabe dans Routines LISP
désolée, j'ai été un peu vite en besogne donc le code était incomplet mais il est corrigé :3 -
Rotation de N Blocs en fonction d une Valeur d Attribut
Luna a répondu à un(e) sujet de lecrabe dans Routines LISP
Coucou, Premièrement merci ! Tu as posé ton problème de manière claire et concise avec toutes les infos nécessaires du premier coup, chat fait plaisir :3 Ensuite pour ton problème on peut revoir légèrement le code de ATTROT comme ci-dessous : (defun c:ATTSCL (/ ang-conv remove-double jsel i e name tag rot n lst) ; Supprime les doublons au sein d'une liste spécifiée en argument : ;--- La fonction (Remove-Double) possède 1 argument ;--- lst1 correspond à la liste devant être évaluée pour la suppression des doublons ;--- Renvoie la liste modifiée sans ses doublons (defun Remove-Double (lst1 / lst2) (while (car lst1) (setq Lst2 (cons (car lst1) lst2) Lst1 (vl-remove (car lst1) lst1) ) ) (reverse lst2) ) ; Permet de convertir les unités angulaires : ;--- La fonction (ang-conv) possède 3 arguments ;--- a correspond à l'angle que l'on souhaite convertir ;--- from correspond à l'unité angulaire de départ ; 0 - Degree ; 3 - Radian ; 2 - Grade ;--- to correspond à l'unité angulaire d'arrivée ; 0 - Degree ; 3 - Radian ; 2 - Grade ;--- Renvoie l'angle converti sous format numérique (defun ang-conv (a from to /) (cond ((and (= from 0) (= to 0)) (/ (* a 180.0) 180.0) ) ((and (= from 0) (= to 3)) (/ (* a pi) 180.0) ) ((and (= from 0) (= to 2)) (/ (* a 200.0) 180.0) ) ((and (= from 3) (= to 0)) (/ (* a 180.0) pi) ) ((and (= from 3) (= to 3)) (/ (* a pi) pi) ) ((and (= from 3) (= to 2)) (/ (* a 200.0) pi) ) ((and (= from 2) (= to 0)) (/ (* a 180.0) 200.0) ) ((and (= from 2) (= to 3)) (/ (* a pi) 200.0) ) ((and (= from 2) (= to 2)) (/ (* a 200.0) 200.0) ) ) ) (if (or (setq jsel (ssget '((0 . "INSERT")))) ; si pré-sélection ou sélection manuelle (setq jsel (ssget "_X" '((0 . "INSERT")))) ; si pas de sélection manuelle, alors prise en compte de la totalité des blocs ) (progn (setq n 0 i (sslength jsel) e i ) (setq tag '(("ECHELLE_X" 41) ("ECHELLE_Y" 42) ("TYPE" 50))) (repeat i (setq name (ssname jsel (setq i (1- i)))) (mapcar '(lambda (x / v) (if (and (null (vl-catch-all-error-p (setq v (vl-catch-all-apply 'getpropertyvalue (list name (car x)))))) (if (= (cadr x) 50) (setq v (ang-conv (atof v) (getvar "AUNITS") 3)) (setq v (atof v))) (entmod (subst (cons (cadr x) v) (assoc (cadr x) (entget name)) (entget name))) ) (setq n (1+ n) lst (cons (getpropertyvalue name "BlockTableRecord/Name") lst) ) (ssdel name jsel) ) ) tag ) ) (sssetfirst nil jsel) (foreach name (setq lst (vl-sort (remove-double lst) '<)) (command "_ATTSYNC" "N" name) ) (setq lst (apply 'strcat (mapcar '(lambda (str) (strcat "\n - " str)) lst))) (alert (strcat "\nUn total de " (itoa n) " / " (itoa e) " bloc(s) ont été redéfinis." "\nVoici la liste des blocs ayant les attributs nommés \"" (vl-string-right-trim "\", \"" (apply 'strcat (mapcar '(lambda (x) (strcat x "\", \"")) tag))) "\" : " lst ) ) (prompt (strcat "\nUn total de " (itoa n) " / " (itoa e) " bloc(s) ont été redéfinis." "\nVoici la liste des blocs ayant les attributs nommés \"" (vl-string-right-trim "\", \"" (apply 'strcat (mapcar '(lambda (x) (strcat x "\", \"")) tag))) "\" : " lst ) ) ) (prompt (strcat "\nAucun bloc présent dans ce fichier...")) ) (princ) ) Je ne l'ai pas testé, je te laisse essayer avec tes blocs et revient vers moi en cas de soucis ! Bisous, Luna -
Coucou, Si la commande GATTU est suffisante alors tant mieux :3 Je remarque que j'ai fait 2-3 petits oublis mais bon ^^" Si jamais la commande DATECART t'intéresse tout de même, envoie moi un .dwg avec tes blocs cartouches afin que je puisse l'adapter correctement. Elle a l'avantage de n'avoir aucune sélection souris ou de saisie texte donc facile d'utilisation et rapide ! Comme tu vois, ce n'est pas parce que cela n'existe pas, que c'est impossible ;3 Heureuse d'avoir pu t'aider en tout cas. Bisous, Luna
-
Coucou, Voici ce que je peux te proposer pour la commande GATTE : ;; Actualisation de la commande GATTE (ExpressTools) pour la prise en compte des blocs dynamiques. ;; ;; Auteur(e) : Luna ;; Date : 28/02/2021 ;; Version : v1.0.0 ;; ;; Utilisation de la fonction (GetStringOrEntity) de (gile) postée sur CADxp le 25/03/2020 sur le forum : ;; https://cadxp.com/topic/48837-besoin-dun-entsel-getstring/page__p__292565__hl__getstring__fromsearch__1#entry292565 (defun c:GATTU (/ get-att change-att GetStringOrEntity input jsel i name bloc-list att-list blc att value ent) (prompt "\nInitialisation...") (defun get-att (att-list / att) (prompt (strcat "\nKnown tag names for block :" (apply 'strcat (mapcar '(lambda (a) (strcat " " a)) att-list)))) (while (not (or (and (setq att (GetStringOrEntity nil "\nSelect attribute or type attribute name: ")) (= (type att) 'STR) (member (strcase att) att-list) ) (and att (listp att) (= (cdr (assoc 0 (entget (car att)))) "ATTRIB") (member (strcase (setq att (cdr (assoc 2 (entget (car att)))))) att-list) ) ) ) ) att ) ;; End of (defun get-att) (defun change-att (blc att / value jsel i name input) (prompt (strcat "\nBlock: " (strcase blc) " Attribute tag: " (strcase att))) (setq value (getstring t "\nEnter new text: ")) (if (setq jsel (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat blc ",`*U*"))))) (repeat (setq i (sslength jsel)) (setq name (ssname jsel (setq i (1- i)))) (if (or (wcmatch (getpropertyvalue name "ClassName") "AcDbAssociative*Array") (not (wcmatch (strcase (getpropertyvalue name "BlockTableRecord/Name")) (strcase blc))) ) (setq jsel (ssdel name jsel)) ) ) ) (if (and jsel (> (sslength jsel) 0)) (progn (initget "Yes No") (if (or (null (setq input (getkword (strcat "\nNumber of inserts in drawing = " (itoa (sslength jsel)) " Process all of them? [Yes/No] <Yes>: ")))) (= input "Yes") ) (repeat (progn (prompt "\nPlease wait...") (setq i (sslength jsel))) (setq name (ssname jsel (setq i (1- i)))) (setpropertyvalue name att value) ) (if (setq jsel (ssget (list '(0 . "INSERT") (cons 2 (strcat blc ",`*U*"))))) (repeat (progn (prompt "\nPlease wait...") (setq i (sslength jsel))) (setq name (ssname jsel (setq i (1- i)))) (if (or (wcmatch (getpropertyvalue name "ClassName") "AcDbAssociative*Array") (not (wcmatch (strcase (getpropertyvalue name "BlockTableRecord/Name")) (strcase blc))) ) (setq jsel (ssdel name jsel)) (setpropertyvalue name att value) ) ) ) ) (null (prompt (strcat "\n" (itoa (if jsel (sslength jsel) 0)) " attributes changed."))) ) ) ) ;;End of (defun change-att) ;--- LISP de (gile) publié sur CADxp.com le 25/03/2020 17:56 ; Permet de récupérer une chaîne de caractères ou une liste similaire à (nentsel) pour une entité : ;--- La fonction (Get-string-or-entity) possède 2 arguments ;--- cr si non nil, accepte les espaces dans la chaîne comme (getstring) ;--- msg correspond au message d'invite à afficher sur la ligne de commande ;--- Renvoie la chaîne de caractères, une liste de la forme (<entityname> . (x y z)) (similaire à (nentsel)) ou nil (defun GetStringOrEntity (cr msg / break result gr pt ent str) (prompt msg) (while (and (not break) (setq gr (grread nil 12 2)) ) (cond ((= 3 (car gr)) ;; Clic gauche (setq ent (nentselp (cadr gr)) result (cond ((null ent) nil) ((= (length ent) 2) ent) (T (list (last (last ent)) (cadr gr)))) break T ) ) ((equal gr '(2 13)) ;; Validation par Entrée (setq result str break T ) ) ((and (not cr) (equal gr '(2 32))) ;; Validation par Espace (setq result str break T ) ) ((= 2 (car gr)) ;; Récupération des entrées au clavier (if (= (cadr gr) 8) ;; 8 = retour/effacer (or (and str (/= str "") (setq str (substr str 1 (1- (strlen str)))) (princ (chr 8)) (princ (chr 32)) ) (setq str nil) ) (or (and str (setq str (strcat str (chr (cadr gr)))) ) (setq str (chr (cadr gr))) ) ) (and str (princ (chr (cadr gr))) ) ;; affichage sur la ligne de commande ) ) ) result ) ;; End of (defun GetStringOrEntity) (initget "Block name") (if (setq input (nentsel "\nSelect block or attribute [block name]: ")) (progn (cond ((and (= input "Block") (while (not (and (setq blc (getstring t "\nEnter block name: ")) (setq bloc-list (tblsearch "BLOCK" blc)))) (null (prompt "\nInvalid block name.")) ) (setq ent (cdr (assoc -2 bloc-list))) (while ent (if (= (cdr (assoc 0 (entget ent))) "ATTDEF") (setq att-list (cons (strcase (cdr (assoc 2 (entget ent)))) att-list)) ) (null (setq ent (entnext ent))) ) (if att-list (progn (setq att (get-att att-list)) (change-att blc att) ) (null (prompt "\nThe block selected has no attributes!")) ) ) ) ((and (listp input) (= (cdr (assoc 0 (entget (setq name (car input))))) "ATTRIB") (setq att (cdr (assoc 2 (entget name)))) (setq name (cdr (assoc 330 (entget name)))) (setq blc (getpropertyvalue name "BlockTableRecord/Name")) (change-att blc att) ) ) ((and (listp input) (setq name (car input)) (setq bloc-list (assoc 331 (entget (cdr (assoc 330 (entget name)))))) (setq name (cdr bloc-list)) (setq blc (getpropertyvalue name "BlockTableRecord/Name")) (setq att-list (mapcar 'vla-get-tagstring (vlax-invoke (vlax-ename->vla-object name) 'getattributes))) (setq att (get-att att-list)) (change-att blc att) ) ) ) ) ) (princ) ) J'ai remarqué du coup qu'il y avait la possibilité de sélectionner manuellement les blocs devant être mis à jour si on ne désire pas modifier toutes les occurrences. Cependant la sélection d'objet sur plusieurs présentations différentes n'est pas possible donc je modifierais tout de même ma commande DATECART pour l'adapter à tes besoins mais en attendant je pense que la commande Global ATTribute Update (GATTU) fonctionne correctement et de la même manière que la commande initiale GATTE. Il aurait probablement été plus simple de modifier la commande originelle si elle était en open source mais je ne l'ai pas trouvée donc j'ai fait au mieux en espérant ne pas avoir oublié une fonctionnalité... ^^" Testé un petit peu sur AutoCAD 2018 sans encombres, donc je te laisse regarder de ton côté si cela fonctionne :3 (si tu as besoin d'aide pour charger la commande, je peux mettre en PJ le fichier .lsp et tu n'auras qu'à suivre les instructions de (gile) pour charger le fichier depuis AutoCAD via ce post) Bisous, Luna
-
Concernant ton soucis de date, je le comprend parfaitement étant donné que j'ai précisément était contrainte à créer une commande pour modifier la date de mes cartouches. Sauf que généralement en phase EXE ou DOE, on affiche la date d'impression et on aimerait bien que la date ne change pas sur les présentations n'ayant pas été modifiées entre-temps donc très souvent la date est différentes sur l'ensemble des cartouches. Dans ce cas précis, GATTE ne va pas réellement t'aider car si je comprends bien son fonctionnement, il modifie la totalité des occurrences trouvées dans le dessins or tu souhaiterais pouvoir en modifier certaines et d'autres non. Cependant l'avantage des cartouches c'est qu'ils sont généralement liés à la présentation (un seul cartouche par présentation) donc j'avais effectué le filtre sur les onglets de présentations pour sélectionner les cartouches comme je le souhaitais :3 En revanche il faudra que tu me transmettes tes blocs afin que je puisse la modifier correctement :3 Je vais donc faire deux commandes distinctes en me basant sur ma commande DATECART ci-dessous : ; Permet de modifier la date d'un ou plusieurs cartouche(s) sélectionnés via une BdD des différentes présentation du dessin et en spécifiant la date souhaitée (avec prise en compte de réponse rapide) : (defun C:DATECART (/ layout date) (if (setq layout (ListBox "DATECART : Sélection des présentations" "Veuillez choisir les présentations devant changer de date :" (layoutlist) (getvar "CTAB") 2)) (progn (if (= "" (setq date (getstring (strcat "\nVeuillez définir la date souhaitée (ENTER pour \"" (substr (get-date) 1 10) "\") :")))) (setq date nil) ) (set-date layout date) ) (exit) ) ) ; Permet de récupérer la date et l'heure au moment de l'exécution sous la forme "XX/XX/XXXX - XX:XX:XX" : ; La fonction (get-date) ne possède aucun argument ;--- Renvoie la date et l'heure sous la forme "JJ/MM/AAAA - HH:MM:SS" (defun Get-Date (/ Date Jour Heure) (setq Date (rtos (getvar "CDATE") 2 6) Jour (strcat (substr Date 7 2) "/" (substr Date 5 2) "/" (substr Date 1 4)) Heure (strcat (substr Date 10 2) ":" (substr Date 12 2) ":" (substr Date 14 2)) Date (strcat Jour " - " Heure) ) ) ; Permet de mettre à jour l'attribut "DATE" des cartouches UBS sur les présentations spécifiées et d'après la date spécifiée : ; La fonction (Set-Date) possède 2 arguments ;--- laylist correspond à la liste des présentations devant être prises en compte pour la redéfinition de la date des cartouches (issue d'une fenêtre de sélection des présentations) ;--- value correspond à la date que l'on souhaite spécifier pour la nouvelle valeur, si value ne possède pas de format typé "date" ou nil, la fonction définira la date comme étant la date actuelle ;--- Renvoie nil. (defun Set-Date (laylist value / jsel i name lst) (cond ((not (listp laylist)) (setq laylist (list laylist))) ) (if (and value (= (strlen (vl-princ-to-string value)) 10) (wcmatch (vl-princ-to-string value) "##.##.####") ) (setq value (vl-princ-to-string value)) (setq value (substr (get-date) 1 10)) ) (if (setq jsel (ssget "_X" (list '(0 . "INSERT") '(2 . "`*U*") (cons 410 (apply 'strcat (mapcar '(lambda (l) (strcat l ",")) laylist)))))) (progn (repeat (setq i (sslength jsel)) (setq name (ssname jsel (setq i (1- i)))) (if (and (not (wcmatch (getpropertyvalue name "ClassName") "AcDbAssociative*Array")) (wcmatch (getpropertyvalue name "BlockRecord/Name") "Cartouche*") (assoc "DATE" (get-att-list name)) (null (setpropertyvalue name "DATE" value)) ) (setq lst (cons (cdr (assoc 410 (entget name))) lst)) (ssdel name jsel) ) ) (prompt (strcat "\nModification de la date (\"" value "\") de " (itoa (sslength jsel)) " cartouche(s)." "\nListe des présentations : \"" (vl-string-right-trim (apply 'strcat (mapcar '(lambda (l) (strcat l "\", \"")) (vl-sort lst '<))) "\", \"") "\"." ) ) ) ) (sssetfirst nil nil) (princ) ) ;--- LISP de bonusCAD publié sur CADXP.com le 11/01/2016 11:34 ;--- Version modifiée de la fonction (ListBox), possède 5 arguments ;--- title correspond à l'entête de la boîte de dialogue ;--- msg correspond au message affiché au dessus de la liste ;--- lst correspond à la liste à afficher ;--- value correspond à la valeur définie par défaut ;--- flag correspond au type de liste souhaitée ; flag = 0 -> liste déroulante (choix unique) ; flag = 1 -> liste avec barre de défilement (choix unique) ; flag = 2 -> liste avec barre de défilement (choix multiple) ; Renvoie la liste des calques ayant été sélectionnés (defun ListBox (title msg lst value flag / tmp file DCL_ID choice) (setq tmp (vl-filename-mktemp "tmp.dcl") file (open tmp "w") ) (write-line (strcat "ListBox:dialog{width=" (itoa (+ (apply 'max (mapcar 'strlen (mapcar 'vl-princ-to-string lst))) 5)) ";label=\"" title "\";") file ) (if (and msg (/= msg "")) (write-line (strcat ":text{label=\"" msg "\";}") file) ) (write-line (cond ((= 0 flag) "spacer;:popup_list{key=\"lst\";") ((= 1 flag) "spacer;:list_box{height=15;key=\"lst\";") (t "spacer;:list_box{height=15;key=\"lst\";multiple_select=true;") ) file ) (write-line "}spacer;ok_cancel;}" file) (close file) (setq DCL_ID (load_dialog tmp)) (if (not (new_dialog "ListBox" DCL_ID)) (exit) ) (start_list "lst") (mapcar 'add_list lst) (end_list) (set_tile "lst" (if (member value lst) (itoa (vl-position value lst)) (itoa 0))) (action_tile "accept" "(or (= (get_tile \"lst\") \"\") (if (= 2 flag) (progn (foreach n (str2lst (get_tile \"lst\") \" \") (setq choice (cons (nth (atoi n) lst) choice)) ) (setq choice (reverse choice)) ) (setq choice (nth (atoi (get_tile \"lst\")) lst)) ) ) (done_dialog)" ) (start_dialog) (unload_dialog DCL_ID) (vl-file-delete tmp) choice ) ;--- LISP de bonusCAD publié sur CADXP.com le 11/01/2016 11:34 ;--- Nécessaire au bon fonctionnement de la fonction (ListBox) ci-dessus (defun str2lst (str sep / pos) (if (setq pos (vl-string-search sep str)) (cons (substr str 1 pos) (str2lst (substr str (+ (strlen sep) pos 1)) sep) ) (list str) ) ) Bisous, Luna
-
Coucou, Je ne connaissais pas du tout la commande GATTE (à vrai dire j'utilise très peu les ExpressTools) mais au vu de ce qu'elle propose, l'exercice de la remplacer n'est vraiment pas bien compliqué je pense pour intégrer les blocs dynamiques dans la sélection. Dans ce cas, je peux te proposer de généraliser ta demande afin de "copier" le fonctionnement de cette commande et de pouvoir modifier la date ou plus encore au besoin. Le principe est simple puisque les attributs et effectivename sont collectables assez facilement. Je pourrais te proposer un premier jet demain afin de voir si cela correspond bien à ta demande si tu veux :3 Bisous, Luna
-
Coucou, En lisp, il faut faire un tri post-sélection en vérifiant l'effectivename du bloc dynamique. Donc si par exemple les blocs dynamique que tu utilises ont pour nom "Présentation" par exemple, on ferait ceci : (defun c:blocselect (/ jsel i name) (if (setq jsel (ssget "_X" '((0 . "INSERT") (2 . "`*U*")))) (progn (repeat (setq i (sslength jsel)) (setq name (ssname jsel (setq i (1- i))) (if (or (wcmatch (getpropertyvalue name "ClassName") "AcDbAssociative*Array") (not (wcmatch (getpropertyvalue name "BlockRecord/Name") "Présentation")) ) (ssdel jsel name) ) ) (sssetfirst nil jsel) ) ) (princ) ) Le petit risque des sélections de blocs dynamiques c'est la potentielle présence de réseaux qui sont des blocs dynamiques anonymes et qui génère donc des erreurs lors de la recherches de l'effectivename... Après si tu souhaite modifier la valeur d'un attribut tu peux simplement utiliser (setpropertyvalue name "ATT-name" value) avec ATT-name le nom de l'étiquette de ton attribut. Si tu as une demandes particulière, je peux t'écrire un code pour répondre à ta demande mais pour se faire j'aurais besoin d'infos supplémentaires comme le nom des blocs et des étiquettes et la manière dont tu souhaites modifier les blocs. Bisous, Luna
-
Coucou, La somme est effectuée au moment de l'export avec les valeurs numériques et donc exactes (aucun arrondis) donc il ne fait pas la somme des arrondis mais l'arrondi de la somme :3 si on veut faire une somme d'arrondis, je ne vois pas vraiment d'autre alternative que de succéder 3 conversions au lieu d'une seule : (rtos (atof (rtos number 2 1)) 2 1) Donc dans ton cas on aurait à la place de (rtos (apply '+ (mapcar 'cadr y)) 2 2) on doit faire (rtos (apply '+ (mapcar '(lambda (s) (atof (rtos (cadr s) 2 1))) y)) 2 1) Donc cela peut se comprendre dans le cas d'un nombre très important de pièces pour un même appartement car on a n*0.1 m² de différence (n le nombre de pièces) mais de là à poser problème... Autrement il faut remplacer comme ci-dessus. Mais n'est-ce pas d'ailleurs une erreur de faire la somme des arrondis et non l'arrondi de la somme ? Car perso' je considère cela comme une erreur car en prenant 200 pièces de 1.05m² chacune on aura une surface réelle à 210.0m² si je fais l'arrondi de la somme et 220.0m² si je fais la somme des arrondis, donc on se retrouve avec 10m² inexistant à payer, ou inversement avec 10m² supplémentaires gratuitement ! 0o0 Donc je n'arrives pas bien à saisir la pertinence de la démarche...mais bon..
-
J'avoue ne pas bien comprendre la demande pour le coup... l'arrondi c'est juste une question de décimale donc qu'elle différence existe-t-il entre la colonne "Surface arrondie" et "Surface" mise à part le nombre de décimales après la virgule ? Et du coup quel est l'intérêt d'avoir une colonne avec 1 décimales et une autre avec 2 ? L'export est strictement identique, on ne fait qu'écrire deux fois la même chose donc il est plus simple de modifier cela directement sur Excel, nan ? Bisous, Luna
-
Coucou, Hydro8 Il s'agit du second 2 à chaque (rtos), par exemple pour celui-ci (rtos (apply '+ (mapcar 'cadr y)) 2 2) on peut isoler les 3 arguments comme suit : (rtos (apply '+ (mapcar 'cadr y)) ;; le nombre réel que l'on souhaite convertir sous format texte 2 ;; l'écriture que l'on souhaite appliquer lors de la conversion (ici le 2 correspond à l'écriture décimale) 2 ;; la précision (donc ici on oblige à écrire le nombre avec 2 décimales après la virgule) ) La surface est située au (cadr y) ou (cadr r) tandis que le périmètre est situé au (caddr y) ou (caddr r) ou si tu préfères les virgules servent de séparateurs pour le fichier .csv donc tu as : Nom , Surface , Périmètre Donc si tu repères les virgules, la surfaces correspond aux (rtos) situés entre les deux virgules :3 Il est possible de supprimer la précision (pour ne pas la forcer) afin que seule la précision indiquée dans le format du dessin (cf. variable système LUPREC, ou Format > Contrôle des unités... > Longueur "Précision") soit prise en compte. Les arrondis se font automatiquement lors de la conversion du nombre en texte en fonction de la précision indiquée. Par exemple : (rtos 2 2 2) renvoie "2.00" (rtos 2.01536484529 2 3) renvoie "2.015" (rtos 2.6131861 2 0) renvoie "3" (rtos 2.1536 2) renvoie "2.1536" Pour simplifier la modification du code, il est possible de remplacer cette valeur 2 à chaque occurrence par une seule variable et de définir cette nouvelle variable en dur en début de programme (pour n'avoir à la modifier qu'à un seul endroit). GEGEMATIC Vouih, je les avais également vu passer lorsque j'avais eut un soucis avec la fonction (vl-sort) et (gile) l'avait évoqué également mais je n'ai pas vraiment eut le temps d'étudier le programme (et surtout la moitié du programme utilise des fonctions que je ne connais pas donc la lecture est d'autant plus complexe et longue) mais je me rend bien compte qu'il va bien falloir que je passe par là si je veux continuer à progresser :3 (et accessoirement aussi parce que je refuse d'utiliser un programme sans savoir pourquoi et comment chat marche >w<) Donc merci beaucoup pour m'avoir partagé cela et vraiment désolée si tu ne peux pas t'attribuer tout le mérite, promis je montrerais plus d’enthousiasme sur tes partages de fonctions à l'avenir <3 Bisous, Luna
-
Coucou, Petite remarque : dans ton .dwg tu sembles exclure des poteaux des surfaces en faisant un décroché de ton contour et ainsi tu as plusieurs fois le même sommet dans ta polyligne (à l'aller et au retour). Cette configuration génère bien souvent des erreurs pour les sélections d'objets sous forme de fenêtres ou de captures. La fonction (ssget) est alors incapable de déterminer une emprise et se résulte par la sélection d'aucun objet. Ainsi tu as tes terrasses (ou jardins) qui sont exportés en surface mais sans aucun nom associé à la surface. Donc rien de grave étant donné que la surface est tout de même exportée mais les noms, eux, ne pourront pas être exportés. Il existe la solution au pire de ne séparer les sommets d'aller des sommets du retour par un espace d'1mm voire moins pour ne pas perturber AutoCAD :3 Bon du coup j'ai ajouté la fabuleuse fonction proposée par GEGEMATIC (et je sens que je vais y passer des heures pour la décortiquer de mon côté, merci Gégé !) au fichier de SurfArea que je te transmet ci-joint. J'ai ajouté l'impression des résultats dans l'historique de commande afin de contrôler directement dans AutoCAD les valeurs associées au besoin (temps d'exécution identique). J'ai testé sur ton .dwg et aucun problème apparent (mise à part l'exclusion des poteaux qui empêche l'export du nom des pièces), dis-moi si cette version te convient bien :3 Bisous, Luna SurfArea v1.1.0 26-02-2021 (Luna).lsp
-
Coucou GEGEMATIC, non je ne connaissais absolument pas et cela à l'air vraiment intéressant pour le coup ! Je m'étais déjà penchée sur l'écriture du formatage mais par manque de documentation sur le sujet (et de temps surtout) j'ai laissé cela de côté... Cela paraît être une excellente solution pour convertir les textes formatés avant l'exécution de la commande SURFAREA pour éviter tout problème avec la version originale et si je comprends bien, ta version permet d'extraire le texte réel sans modifier l'objet "MTEXT" ? Autrement il est toujours possible de placer une Marque avec la commande ANNULER, lancer la commande STRIPMTEXT pour purger les textes, lancer SURFAREA et Retourner à la marque une fois le fichier .csv édité :3 J'utilise beaucoup cette fonctionnalité, chat dépanne bien souvent (et économise des crampes aux doigts ^^) Merci Gégé !
-
Le soucis vient du fait que SI le programme supprime le formatage (si formatage il y a plus exactement), alors il faut s'arrêter à "}\\P" et non "\\P" uniquement. Bref la gestion des formatages en MTEXT peut s'avérer délicat en fonction du dessin (et du dessinateur/dessinatrice !) donc je ferais une modification à partir de ton .dwg, mais sera du coup coincé dans un fonctionnement basé sur vos pratiques. Donc si vous changez vos pratiques (même ponctuellement) le programme ne sera plus fonctionnel.
-
C'est un peu trop incertain pour être honnête...il suffit d'une différence pour que cela ne fonctionne pas.. Est-ce une obligation que le texte soit en gras ? De plus la taille de la police est forcée, y a-t-il une raison ? Selon le formatage il est possible de démarrer au ";" mais cela ne fonctionne que dans certains cas particuliers, ce qui n'est pas le tien. On peut éventuellement ajouter (setq str (vl-string-left-trim "{\fTahoma|b1|i0|c0|p34;\H3x;7f1\fTahoma|b0|i0|c0|p34;" str)) et ajouter le "}" pour la recherche du "\\P" au besoin. Bisous, Luna
-
Le dossier est vide ^^"
-
En effet petite erreur de ma part ^^" cette fois-ci j'ai testé et chat marche ! Code mis à jour sur le post#14
-
J'ai ajouté la découpe au premier "\P", je n'ai pas testé mais cela devrait fonctionner. Si le texte n'a pas de retour à la ligne, il prendra tout, sinon il ne prendra que la première ligne. Bisous, Luna
-
Le filtre du calque sur le texte est actuellement défini sur "*" à la ligne ((and (setq obj (ssget "_CP" pt-list '((0 . "MTEXT,TEXT") (8 . "*")))), le code DXF 8 correspond au filtre que l'on souhaite appliquer à la propriété de calque. Donc si par exemple tous tes textes sont présents sur un calque nommé "ROOM_TXT" alors tu remplaces le "*" par "ROOM_TXT" et si tu as plusieurs calques avec une base identique tu peux utiliser le wildcard "*" comme pour le filtre des polylignes. Vouih c'est parfaitement faisable, si par exemple la séparation des informations est faite avec un retour à la ligne au sein du MTEXT, alors il suffit de repérer le wildcard "\P" spécifiant un retour à la ligne (et donc de ne prendre que les informations qui le précède. Un exemple de MTEXT ayant plusieurs lignes avec un retour à la ligne (ENTER) entre chaque : Commande: (explore-dxf (car (entsel)) 0 nil) Choix de l'objet: Explore DXF in progress from "MTEXT" (<Nom d'entité: 2ca3af5bdc0>) : | (-1 . <Nom d'entité: 2ca3af5bdc0>) | (0 . "MTEXT") | (330 . <Nom d'entité: 2c9e0dcd9f0>) | (5 . "4BBBA4") | (100 . "AcDbEntity") | (67 . 0) | (410 . "Model") | (8 . "0") | (48 . 0.5) | (100 . "AcDbMText") | (10 1.9019e+06 3.16255e+06 0.0) | (40 . 1.5) | (41 . 23.518) | (46 . 0.0) | (71 . 1) | (72 . 5) | (1 . "Ligne 1\PLigne 2\PLigne 3") | (7 . "UBS-Style de texte") | (210 0.0 0.0 1.0) | (11 0.999544 0.0301896 0.0) | (42 . 7.23606) | (43 . 6.99866) | (50 . 0.0) | (73 . 1) | (44 . 1.0) | End of exploration... Après le plus gros risque des MTEXT par rapport aux TEXT simple, c'est la mise en forme spécifique au sein du MTEXT. Par exemple si le texte est d'une couleur forcée, d'une police forcée, en gras, italique, etc on commence de suite à rentrer dans les tréfond de l'AutoLISP pour faire le tri xD Voici un exemple avec la première ligne forcée en couleur rouge, la seconde ligne en gras et la troisième ligne avec une taille de police plus grande : Explore DXF in progress from "MTEXT" (<Nom d'entité: 2ca3af5bdc0>) : | (-1 . <Nom d'entité: 2ca3af5bdc0>) | (0 . "MTEXT") | (330 . <Nom d'entité: 2c9e0dcd9f0>) | (5 . "4BBBA4") | (100 . "AcDbEntity") | (67 . 0) | (410 . "Model") | (8 . "0") | (48 . 0.5) | (100 . "AcDbMText") | (10 1.9019e+06 3.16255e+06 0.0) | (40 . 1.5) | (41 . 23.518) | (46 . 0.0) | (71 . 1) | (72 . 5) | (1 . "{\\C1;Ligne 1}\\P{\\fVerdana|b1|i0|c0|p34;Ligne 2}\\P{\\H1.33333x;Ligne 3}") | (7 . "UBS-Style de texte") | (210 0.0 0.0 1.0) | (11 0.999544 0.0301896 0.0) | (42 . 9.61986) | (43 . 7.68737) | (50 . 0.0) | (73 . 1) | (44 . 1.0) | End of exploration... Donc si votre utilisation du MTEXT est simple (uniquement des retours à ligne avec la première ligne correspondant au nom de la pièce), je peux mettre un arrêt sur le "\P" au besoin. Bisous, Luna
-
oups pardon ! c'est corrigé ! :3
-
Coucou, Je n'ai pas fait ainsi, en .csv on n'a pas la main sur la mise en page du fichier .xls mais pour les rangées qui porte le nom du calque "SURFACE_APPARTEMENT001" par exemple, tu as le total des pièces qui le compose au-dessous que se soit pour la surface ou le périmètre (cela économise une colonne ^^) Si je l'avais affiché dans l'historique de commande j'aurais pu faire un peu de mise en page pour faire ressortir ces valeurs voilà tout. Mais du coup tu as déjà cela dans ton fichier d'export. Absolument, je ne l'ai pas fait car cela est spécifique mais je peux tricher légèrement :3 J'ai modifier le code au post#14 pour prendre en compte cela en ajoutant la ligne (if (vl-string-search "_" layer) (setq layer (substr layer (+ 2 (vl-string-position (ascii "_") layer))))) sur le (mapcar layer). Cela devrait normalement découper le nom des calques à partir du caractère "_", peut importe ce qu'il y a avant ce caractère. Bisous, Luna
-
Coucou, Je peux éventuellement te proposer ceci : ;; Dans le but d'une généralisation du programme, la sélection des calques/polylignes peut se faire selon 3 différents modes : ;; ;; ;; ;; Le programme ouvre en premier lieu une boîte de dialogue pour la sélection multiple des calques. En suivant ce mode, ;; ;; l'ensemble des polylignes présentes sur ce(s) calque(s) seront prise en compte pour l'exportation des données. Si cette ;; ;; méthode ne convient pas à l'utilisateur, il suffit de valider à vide (pas de calque sélectionné) ou d'annuler la BdL. ;; ;; ;; ;; Si aucun calque n'a été sélectionné via la BdL, le programme demande alors de sélectionner manuellement des polylignes, ;; ;; qui sont filtrées par défaut pour des calques suivant la dénomination "SURFACES_APPART*". Il est également possible de ;; ;; ne sélectionner aucune polyligne afin de sélectionner automatiquement la totalité des polylignes présentes dans les ;; ;; calques suivant la dénomination "SURFACE_APPART*". ;; ;; ;; ;; Si la dénomination des calques ne convient pas, il est possible de modifier la valeur par défaut en modifiant le filtre ;; ;; (ssget) de la forme (8 . "SURFACES_APPART*") et donc de remplacer "SURFACES_APPART*" par la dénomination souhaitée. ;; ;; Ceci est également possible pour le filtre des "TEXT" et "MTEXT" (8 . "*") pour afiner la recherche et la rapidité. ;; ;; ;; ;; Concernant la création du fichier .csv, celui-ci utilise le dossier du fichier .dwg par défaut ainsi que le nom du fichier ;; ;; .dwg comme nom par défaut, il est donc possible d'éxécuter la commande rapidement en effectuant une succession de 3 ;; ;; validations à vide, ce qui permettra d'exporter l'ensemble des surfaces des polylignes de chaque pièce pour l'ensemble des ;; ;; calques nommés "SURFACES_APPART*". ;; ;; ;; ;; Une modification est en cours pour permettre la détection d'îlots au sein d'une pièce et en déduire leur aire à l'aire de ;; ;; la pièce principale pour permettre un export plus juste. ;; ;; ;; ;;--- Auteur(e) : Luna ;; ;;--- Date : 25/02/2021 ;; ;;--- Version : 1.0.0 ;; (defun c:SURFAREA (/ ListBox str2lst unit-prompt Remove-Double jsel i name obj n ent layer-list area perim pt-list layer txt str lst file) ;--- LISP de bonusCAD publié sur CADXP.com le 11/01/2016 11:34 ;--- Version modifiée de la fonction (ListBox), possède 5 arguments ;--- title correspond à l'entête de la boîte de dialogue ;--- msg correspond au message affiché au dessus de la liste ;--- lst correspond à la liste à afficher ;--- value correspond à la valeur définie par défaut ;--- flag correspond au type de liste souhaitée ; flag = 0 -> liste déroulante (choix unique) ; flag = 1 -> liste avec barre de défilement (choix unique) ; flag = 2 -> liste avec barre de défilement (choix multiple) ; Renvoie la liste des calques ayant été sélectionnés (defun ListBox (title msg lst value flag / tmp file DCL_ID choice) (setq tmp (vl-filename-mktemp "tmp.dcl") file (open tmp "w") ) (write-line (strcat "ListBox:dialog{width=" (itoa (+ (apply 'max (mapcar 'strlen (mapcar 'vl-princ-to-string lst))) 5)) ";label=\"" title "\";") file ) (if (and msg (/= msg "")) (write-line (strcat ":text{label=\"" msg "\";}") file) ) (write-line (cond ((= 0 flag) "spacer;:popup_list{key=\"lst\";") ((= 1 flag) "spacer;:list_box{height=15;key=\"lst\";") (t "spacer;:list_box{height=15;key=\"lst\";multiple_select=true;") ) file ) (write-line "}spacer;ok_cancel;}" file) (close file) (setq DCL_ID (load_dialog tmp)) (if (not (new_dialog "ListBox" DCL_ID)) (exit) ) (start_list "lst") (mapcar 'add_list lst) (end_list) (if (member value lst) (set_tile "lst" (itoa (vl-position value lst)))) (action_tile "accept" "(or (= (get_tile \"lst\") \"\") (if (= 2 flag) (progn (foreach n (str2lst (get_tile \"lst\") \" \") (setq choice (cons (nth (atoi n) lst) choice)) ) (setq choice (reverse choice)) ) (setq choice (nth (atoi (get_tile \"lst\")) lst)) ) ) (done_dialog)" ) (start_dialog) (unload_dialog DCL_ID) (vl-file-delete tmp) choice ) ;--- LISP de bonusCAD publié sur CADXP.com le 11/01/2016 11:34 ;--- Nécessaire au bon fonctionnement de la fonction (ListBox) ci-dessus (defun str2lst (str sep / pos) (if (setq pos (vl-string-search sep str)) (cons (substr str 1 pos) (str2lst (substr str (+ (strlen sep) pos 1)) sep) ) (list str) ) ) ; Permet d'afficher l'unité de mesure selon la valeur de la variable système "INSUNITS" ou "AUNITS" : ; Création le 21/09/2020 v1.0.0 (defun unit-prompt (flag / u) (cond ((= flag 0) (setq u (getvar "INSUNITS")) ) ((= flag 1) (setq u (getvar "AUNITS")) ) ) (cond ((and (= flag 0) (= u 0)) "" ) ((and (= flag 0) (= u 1)) "in" ) ((and (= flag 0) (= u 2)) "ft" ) ((and (= flag 0) (= u 3)) "mi" ) ((and (= flag 0) (= u 4)) "mm" ) ((and (= flag 0) (= u 5)) "cm" ) ((and (= flag 0) (= u 6)) "m" ) ((and (= flag 0) (= u 7)) "km" ) ((and (= flag 0) (= u 8)) "µin" ) ((and (= flag 0) (= u 9)) "Mi" ) ((and (= flag 0) (= u 10)) "yd" ) ((and (= flag 0) (= u 11)) "Å" ) ((and (= flag 0) (= u 12)) "nm" ) ((and (= flag 0) (= u 13)) "µm" ) ((and (= flag 0) (= u 14)) "dm" ) ((and (= flag 0) (= u 15)) "dam" ) ((and (= flag 0) (= u 16)) "hm" ) ((and (= flag 0) (= u 17)) "Gm" ) ((and (= flag 1) (= u 0)) "°" ) ((and (= flag 1) (= u 1)) "\"" ) ((and (= flag 1) (= u 2)) "gon" ) ((and (= flag 1) (= u 3)) "rad" ) ) ) ; Supprime les doublons au sein d'une liste spécifiée en argument : ;--- La fonction (Remove-Double) possède 1 argument ;--- lst1 correspond à la liste devant être évaluée pour la suppression des doublons ;--- Renvoie la liste modifiée sans ses doublons (defun Remove-Double (lst1 / lst2) (while (car lst1) (setq Lst2 (cons (car lst1) lst2) Lst1 (vl-remove (car lst1) lst1) ) ) (reverse lst2) ) ; []=================================================[] DEBUT DE LA COMMANDE SURFAREA []=================================================[] ; (if (or (and (setq layer-list (ListBox "Choix des calques : " "Veuillez choisir le(s) calque(s) des polylignes contenant les surfaces à étudier :" (progn (setq name (cdr (assoc 2 (tblnext "LAYER" t)))) (while (/= name nil) (if (not (wcmatch name "*|*")) (setq layer-list (cons name layer-list)) ) (setq name (cdr (assoc 2 (tblnext "LAYER")))) ) (vl-sort layer-list '<) ) nil 2 ) ) (setq jsel (ssget "_X" (list '(0 . "LWPOLYLINE") (cons 8 (apply 'strcat (mapcar '(lambda (layer) (strcat layer ",")) layer-list)))))) ) (setq jsel (ssget '((0 . "LWPOLYLINE") (8 . "SURFACES_APPART*")))) (setq jsel (ssget "_X" '((0 . "LWPOLYLINE") (8 . "SURFACES_APPART*")))) ) (progn (repeat (setq i (sslength jsel)) (setq name (ssname jsel (setq i (1- i))) area (vlax-curve-getarea name) perim (vlax-curve-getDistAtParam name (vlax-curve-getEndParam name)) pt-list (mapcar 'cdr (vl-remove-if-not '(lambda (e) (= (car e) 10)) (entget name))) layer (cdr (assoc 8 (entget name))) txt nil ) ;; (if (or ;; (and layer-list ;; (setq obj (ssget "_WP" (setq pt-list (mapcar '(lambda (pt) (trans pt 0 1)) pt-list)) (list '(0 . "LWPOLYLINE") (cons 8 (apply 'strcat (mapcar '(lambda (layer) (strcat layer ",")) layer-list)))))) ;; ) ;; (setq obj (ssget "_WP" pt-list '((0 . "LWPOLYLINE") (8 . "SURFACES_APPART*")))) ;; ) ;; (repeat (setq n (sslength obj)) ;; (setq ent (ssname obj (setq n (1- n))) ;; area (- area (vlax-curve-getArea ent)) ;; jsel (ssdel ent jsel) ;; i (1- i) ;; ) ;; ) ;; ) (cond ((and (setq obj (ssget "_CP" pt-list '((0 . "MTEXT,TEXT") (8 . "*")))) (= 1 (sslength obj)) ) (setq txt (substr (setq str (cdr (assoc 1 (entget (ssname obj 0))))) 1 (vl-string-search "\\P" str))) ) ((and obj (< 1 (sslength obj)) ) (repeat (setq n (sslength obj)) (setq ent (ssname obj (setq n (1- n))) txt (cons (substr (setq str (cdr (assoc 1 (entget ent)))) 1 (vl-string-search "\\P" str)) txt) ) ) (setq txt (vl-string-right-trim " | " (apply 'strcat (vl-sort (mapcar '(lambda (x) (strcat x " | ")) txt) '<)))) ) (t (setq txt "-") ) ) (setq lst (cons (cons layer (list txt area perim)) lst)) ) (if (and (setq layer-list (vl-sort (remove-double (mapcar 'car lst)) '<) file (getfiled "Enregistrement du fichier .csv" (strcat (getvar 'DWGPREFIX) (vl-filename-base (getvar 'DWGNAME)) ".csv") "csv" 45 ) file (open file "w") ) (write-line (strcat "Dénomination,Surface (" (unit-prompt 0) "²),Périmètre (" (unit-prompt 0) ")") file ) (mapcar '(lambda (layer / y txt) (setq y (vl-sort (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) layer)) lst)) '(lambda (e1 e2) (< (car e1) (car e2))))) (if (vl-string-search "_" layer) (setq layer (substr layer (+ 2 (vl-string-position (ascii "_") layer))))) (write-line (strcat layer "," (rtos (apply '+ (mapcar 'cadr y)) 2 2) "," (rtos (apply '+ (mapcar 'caddr y)) 2 2)) file ) (mapcar '(lambda (r) (write-line (strcat (car r) "," (rtos (cadr r) 2 2) "," (rtos (caddr r) 2 2)) file ) ) y ) ) layer-list ) (not (close file)) ) (prompt (strcat "\nLe fichier .csv a été créé avec succès pour l'export des calques :" (apply 'strcat (mapcar '(lambda (layer) (strcat "\n - " layer)) layer-list)) ) ) (prompt "\nUne erreur est survenue lors de la création du fichier .csv !") ) ) ) (princ) ) Cela fait un peu usine à gaz, je l'avoue mais c'est rapide à l'exécution ! :3 J'ai essaye d'intégrer un système de détection d'îlots interne aux pièces maîtresses pour en déduire leur aire et ainsi permettre l'ajout d'obstacle au sein d'une pièce sans fausser les données mais cela demande une manipulation de liste un peu plus violente et donc l'ajout d'une seconde boucle pour supprimer à partir de la première. En attendant j'ai fait en sorte que le programme puisse fonctionner pour un peu pour tout le monde donc tu as 3 modes de sélection possibles (expliqué dans les commentaires du programme) qui se comporte comme des niveaux de lectures. Si le premier niveau est ignoré alors il passe au second sinon il lance le programme. Donc ces niveaux consiste à : 1er Niveau -> Sélectionner la totalité des polylignes en sélectionnant les calques que l'on veut prendre en compte pour l'export 2nd Niveau -> Sélectionner manuellement les polylignes que l'on souhaite avec un filtre appliqué lors de la sélection sur le nom du calque "SURFACES_APPART*" 3ème Niveau -> Sélectionner la totalité des polylignes sur l'ensemble des calques ayant pour dénomination "SURFACES_APPART*" Ainsi les deux premiers niveaux ont besoin d'une validation/décision de l'utilisateur et le dernier se fait automatiquement. Il est possible d'ignorer les deux premiers en validant à vide donc facile et rapide. Pour le filtre appliqué sur les textes, je ne connais pas le nom du calque que tu utilises donc actuellement le filtre est appliqué pour prendre tous les calques donc il te faudra ajouter le nom du calque des textes pour ne sélectionner que le nom des pièces. En ensuite tu auras une BdL pour enregistrer ton fichier .csv qui aura le répertoire de ton dessin par défaut et le nom de ton .dwg par défaut donc ici aussi tu peux faire une légère modif' sur le nom et hop validé ! :3 Si tu as des remarques ou améliorations, n'hésites pas ! Bisous, Luna
-
Coucou, Contrairement à lecrabe, je ne possède pas de bibliothèque de 3001 routines donc je ne peux pas te proposer quelque chose de tout fait à modifier légèrement mais je peux en écrire une au besoin. Pour cela j'ai besoin d'un peu plus de précision :3 Pour commencer, si je comprends bien tu as besoin d'un rendu comme suit : Avec le nom "Appartement ##" correspondant au final au nom du calque des polylignes (est-il préférable pour toi de sélectionner une polyligne de chaque calque, ou bien le(s) calque(s) dans une liste de calques ?) et le nom "Pièce ##" correspondant au texte présent dans les objets "MTEXT" ou "TEXT" du dessin. Ces fameux textes ont un unique calque, non lié au calque d'appartement si je comprend bien mais sont situés dans l'emprise de la polyligne pour chaque pièce ? Comment sont fabriqués ces textes ? Il possède le nom de la pièce, la surface de la pièce, une autre info ? Est-il possible qu'un appartement possède deux pièces distinctes possédant la même dénomination ? Si oui, faut-il regrouper les deux surfaces en une seule ou bien les conserver séparées ? Concernant les infos, tu as besoin uniquement de la surface ou bien le périmètre est utile ? L'historique de commande est-il suffisant ou bien il te faut un fichier d'extraction (.txt, .csv, ... ?) ? Je me suis déjà penchée sur des problématiques similaires avec gestions de listes/sous-listes triées Bisous, Luna
