>>NicoM Posté(e) le 13 janvier Posté(e) le 13 janvier Bonjour, Cela fait un moment que je n'ai pas posé de question sur ce forum, mais je suis bloqué sur un problème et j'aimerais obtenir des conseils. Je cherche à insérer un bloc comportant plusieurs attributs dans AutoCAD, en affectant leurs valeurs directement depuis une feuille Excel. Actuellement, j'ai une version fonctionnelle qui affecte les propriétés au dernier bloc inséré, et les attributs récupèrent et compilent ces propriétés. Cependant, le temps d'exécution est assez long, et j'aimerais optimiser ce processus (voir code ci-dessous). Mon objectif serait de sauter l'étape intermédiaire des propriétés et d'intégrer directement les attributs dans le bloc. Il me semblait qu'avec Entmake, Attdef et Attrib, c'était plus rapide et relativement simple, mais je n'arrive pas à comprendre leur fonctionnement. En parcourant le code Edit_bloc3.5 de (gile), j'ai l'impression d'être encore plus perdu qu'au départ. Auriez-vous des suggestions pour optimiser le temps d'exécution et simplifier ce processus ? Merci d'avance pour votre aide ! ;; BOUCLE POUR LES POTEAUX (setq index 0) (while (< index nb-row) ;; Récupération de la liste courante (setq lst (nth index data-list)) ;; Liste des variables à définir (setq var1 '(ID A B phi H D C Nb N1 N1_larg N1_long S1 L1 fL1 fL2 N2 S2 E2 L2 fX2 fY2 N31 N312 S31 E31 L31 fY31 N32 N322 S32 E32 L32 fX32 V_béton P_tot Ratio pos_X pos_Y visi_sch)) ;; Liste des indices correspondants dans lst (setq ind1 '(6 7 8 9 10 11 12 15 16 17 18 19 20 21 22 24 25 26 27 28 29 32 33 34 35 36 37 40 41 42 43 44 45 50 51 52 61 62 63)) ;; Association des variables aux valeurs récupérées (mapcar '(lambda (var index) (set var (vlax-variant-value (nth index lst)))) var1 ind1) ;; Conversion explicite des coordonnées en réel (setq pos_X (if (numberp pos_X) pos_X (atof pos_X))) (setq pos_Y (if (numberp pos_Y) pos_Y (atof pos_Y))) ; insertion du poteau (setq insertion-point (list pos_X pos_Y 0)) (command "_-insert" "# ptx 2 rangs - Barre droite" insertion-point 1 1 0) (setq ent (entlast)) ; attribution des propriétés (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "ID") ID) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "A") A) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "B") B) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "phi") phi) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "H") H) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "D") D) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "C") C) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "Nb") Nb) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N1") N1) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "S1") S1) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "L1") L1) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fL1") fL1) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fL2") fL2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N2") N2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "S2") S2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "E2") E2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "L2") L2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fX2") fX2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fY2") fY2) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N31") N31) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N312") N312) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "S31") S31) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "E31") E31) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "L31") L31) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fY31") fY31) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N32") N32) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N322") N322) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "S32") S32) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "E32") E32) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "L32") L32) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "fX32") fX32) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "N312") N312) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "V_béton") V_béton) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "P_tot") P_tot) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "Ratio") Ratio) ; insertion du schéma (setq insertion-point (list (+ 454 pos_X) (- pos_Y 17) 0)) (command "_insert" "# Schéma ptx Y2" insertion-point 1 1 0) (setq ent (entlast)) ;; Liste des variables à définir (setq variables3 '(N1_larg N1_long visi_sch)) ;; Liste des indices correspondants dans lst (setq propriétés3 '("X" "Y" "Visibilité1")) ;; Association des variables aux valeurs récupérées (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "Y") N1_larg) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "X") N1_long) (setpropertyvalue ent (strcat "AcDbDynBlockProperty" "Visibilité1") visi_sch) ;; Incrémentation de l'index pour passer à l'itération suivante (setq index (1+ index))) Projeteur Béton Armé sur Revit et AutoCAD 2023 Une connaissance acquise ne devient vivante que si on l’a repensée par soi-même.
>>NicoM Posté(e) le 14 janvier Auteur Posté(e) le 14 janvier Grace à ce sujet, https://cadxp.com/topic/54262-lire-la-valeur-dun-attribut-de-bloc/ j'ai enfin réussi à trouver par ou passer pour accéder aux attributs du bloc. Ce n'est encore ni optimisé, ni adapté a mon cas, mais ça fonctionne : (defun modify-attributes (blk) (if (and blk (eq (cdr (assoc 0 (entget blk))) "INSERT")) ; Vérifie que c'est un bloc (progn ;; Vérifie si le bloc contient des attributs (if (assoc 66 (entget blk)) (progn (setq textattrib (entnext blk)) ; Première entité suivante ;; Parcourt les attributs du bloc (while (= (cdr (assoc 0 (entget textattrib))) "ATTRIB") (setq attrib-data (entget textattrib)) ; Récupère les données DXF de l'attribut ;; Si l'attribut a pour tag "ID", on modifie sa valeur (if (= (cdr (assoc 2 attrib-data)) "ID") (progn (setq new-attrib (subst (cons 1 "P66") (assoc 1 attrib-data) attrib-data)) ; Changer la valeur de l'attribut "ID" (entmod new-attrib) ; Appliquer la modification ) ) ;; Si l'attribut a pour tag "AXB", on modifie sa valeur (if (= (cdr (assoc 2 attrib-data)) "AXB") (progn (setq new-attrib (subst (cons 1 "20x50") (assoc 1 attrib-data) attrib-data)) ; Changer la valeur de l'attribut "AXB" (entmod new-attrib) ; Appliquer la modification ) ) (setq textattrib (entnext textattrib)) ; Prochaine entité ) ) ) ) (princ "\nL'entité sélectionnée n'est pas un bloc ou n'a pas d'attributs.") ) (princ) ) (defun c:ModifyAttribs () (setq blk (car (entsel "\nSélectionnez un bloc : "))) ; Sélection du bloc (if blk (progn (modify-attributes blk) (princ "\nAttributs modifiés.") ) (princ "\nAucun bloc sélectionné.") ) (princ) ) Projeteur Béton Armé sur Revit et AutoCAD 2023 Une connaissance acquise ne devient vivante que si on l’a repensée par soi-même.
(gile) Posté(e) mercredi à 14:52 Posté(e) mercredi à 14:52 Le 13/01/2025 à 13:58, >>NicoM a dit : Auriez-vous des suggestions pour optimiser le temps d'exécution et simplifier ce processus ? Pour optimiser le temps d'exécution, tu peux remplacer les appels à 'command' par des 'entmake[x]'. Pour simplifier le processus, tu pourrais utiliser une lite d'association au lieu de définir une quarantaine de variables (LISP est très bien équipé pour traiter les listes. Un exemple avec les fonctions gc:InsertBlockReference et gc:SetDynPropValue extraites de la bibliothèque Blocks en bas de cette page. (while (< index nb-row) ;; Récupération de la liste courante (setq lst (nth index data-list)) ;; Liste d'association des noms de propriété dynamique aux valeurs récupérées (setq pairs (mapcar '(lambda (var index) (cons (vl-symbol-name var) (vlax-variant-value (nth index lst)))) '(ID A B phi H D C Nb N1 N1_larg N1_long S1 L1 fL1 fL2 N2 S2 E2 L2 fX2 fY2 N31 N312 S31 E31 L31 fY31 N32 N322 S32 E32 L32 fX32 V_béton P_tot Ratio pos_X pos_Y visi_sch) '(6 7 8 9 10 11 12 15 16 17 18 19 20 21 22 24 25 26 27 28 29 32 33 34 35 36 37 40 41 42 43 44 45 50 51 52 61 62 63) ) ) ;; Conversion explicite des coordonnées en réel (setq pos_X (if (numberp pos_X) pos_X (atof pos_X))) (setq pos_Y (if (numberp pos_Y) pos_Y (atof pos_Y))) ;; insertion du poteau (setq insertion-point (list pos_X pos_Y 0)) (if (setq ent (gc:InsertBlockReference "# ptx 2 rangs - Barre droite" insertion-point 0. 1.)) (foreach pair (reverse (cdddr (reverse pairs))) (gc:SetDynPropValue ent (strcat "AcDbDynBlockProperty" (car pair)) (cdr pair)) ) ) ;; insertion du schéma (setq insertion-point (list (+ 454 pos_X) (- pos_Y 17) 0)) (if (setq ent (gc:InsertBlockReference "# Schéma ptx Y2" insertion-point 0. 1.)) ;; Association des variables aux valeurs récupérées (progn (setq pairs (reverse pairs)) (foreach pair (list (car pairs) (cadr pairs) (caddr pairs)) (gc:SetDynPropValue ent (strcat "AcDbDynBlockProperty" (car pair)) (cdr pair)) ) ) ) ;; Incrémentation de l'index pour passer à l'itération suivante (setq index (1+ index)) ) 1 Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
>>NicoM Posté(e) jeudi à 10:33 Auteur Posté(e) jeudi à 10:33 Merci ! C'est exactement ce qu'il me fallait ! J'avais bien cherché sur la page en question, mais je n'avais pas trouvé le "block". Je suis admiratif de tout le travail qui a été fait, c'est impressionnant ! J'ai testé en corrigeant certaines choses et ça fonctionne en l'état. Je vais néanmoins faire une autre version en passant par "gc:SetAttributeValue" au lieu de "gc:SetDynPropValue" et je la partagerais ici. Petite question bonus, maintenant lors de l'exécution de la commande, mon espace Autocad se fige jusqu'à la fin de l'exécution. N'y a t-il pas moyen de visualiser l'insertion des blocs en temps réel, ou au moins avoir une petite idée de l'avancement via la console ? Projeteur Béton Armé sur Revit et AutoCAD 2023 Une connaissance acquise ne devient vivante que si on l’a repensée par soi-même.
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