Modification d'un lsp

lewis185
Advocate
Advocate

Modification d'un lsp

lewis185
Advocate
Advocate

Bonjour,

Après quelques recherches d'un lisp permettant d'extraire les valeurs d'attributs d'un ou plusieurs blocs et pouvant les réinsérer dans un autre dwg, j'ai trouvé ce lisp sous forme de 2 commandes.
J'ai dans l'idée de conserver les deux actions sous forme de 2 commandes afin de pouvoir exécuter d'autres commandes entre les actions.

 

(defun c:att-out ()
(load "attout")
(setq fna "C:\\users\\username\\Desktop\\att.txt")
(setq ss (ssget '((0 . "INSERT") (66 . 1))))
(bns_attout fna ss)
)

(defun c:att-in (/ tmpn)
(load "attout")
(setq #bns_attin_modified 0)
(if (setq tmpn(findfile "C:\\users\\username\\Desktop\\att.txt"))
(bns_attin tmpn nil)
)
)

Mon soucis se situe au niveau du "att-in" :

Reading the input file... Done.
No entity with specified handle "12A7" exists.
No entity with specified handle "11BF" exists.

Si je comprends bien, il ne retrouve pas l'indice handle dans le nouveau dwg, alors que les blocs sont bien présents.
J'aimerais pouvoir forcer le lisp à ne pas s'arrêter sur l'erreur et pouvoir continuer comme un "ATTIN" avec :

3.PNG

 

Avez vous des idées à me donner ?

D'avance merci,

Lewis185

0 J'aime
Répondre
Solutions acceptées (1)
751 Visites
8 Réponses
Replies (8)

_gile
Mentor
Mentor

Salut,

 

Il semble (mais on ne peut en être certain sans voir le code) que les routines bns_attin et bns_attout fonctionne comme les commandes ATTIN et ATTOUT des express tools.

Ces commandes  utilisent, dans un fichier externe, une entrée (une ligne dans le fichier texte) par bloc pour stocker les valeurs d'attribut de ce bloc (attout) ou pour affecter les valeurs d'attributs modifiées dans le fichier à ce même bloc (attin).

Comme différentes entrées peuvent concerner différentes références de la même définition de bloc, c'est le handle de la référence de bloc est utilisé comme identifiant.

Un handle est un identifiant pour toutes les entités AutoCAD. Il est pérenne (conservé après la fermeture du dessin) et unique dans le dessin. Ce qui veux dire que le handle d'une référence de bloc dans un dessin peut ne pas exister dans un autre ou s'il existe correspondre à n'importe quel autre entité de ce dessin.

En résumé, ce type de routine/commande est fait pour fonctionner avec un fichier de données par dessin.

 

Pour passer d'un dessin à un autre, il faudrait qu'il y ait un moyen d'identifier quel bloc du dessin A correspond à quel bloc du dessin B...



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

lewis185
Advocate
Advocate

En effet, je recherche le moyen que le lisp pose la question à l'utilisateur, lui proposant ainsi la même opportunité qu'un attin traditionnel.
Sauf que dans ce cas le lisp en question ne le fait pas, ne trouvant pas les bons handle le lsp s'arrête sans permettre à l'utilisateur d'aller plus loin.

J'aimerais donc modifier le lisp "att-in" pour qu'il pose la question à l'utilisateur, s'il ne retrouve pas automatiquement le handle correspondant.

0 J'aime

_gile
Mentor
Mentor

Salut,

 

J'ai dû mal m'exprimer, le LISP att-in qui appelle une autre routine LISP (bns_attin) que je ne connais pas mais qui utilise les handles ne peut pas être utilisé dans un autre dessin que celui qui a servi a générer le fichier "C:\\users\\username\\Desktop\\att.txt" avec att-out.

 

 

Il ne s'agit pas de modifier des LISPs (dont tu ne donnes pas les codes) mais d'en écrire d'autres parce que je pense que ce que tu cherches à faire n'a pas grand chose à voir avec ce que semblent faire ceux que tu voudrais modifier.

 

Décris plutôt le plus précisément possible ce que tu voudrais faire en essayant de penser à la façon de récupérer les données et on verra alors s'il est plus opportun de modifier un LISP ou d'en créer un de toutes pièces.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime

lewis185
Advocate
Advocate

D'accord, merci de tes réponses.

 

J'aimerais arriver à exporter les valeurs d'attributs d'un bloc (ou plusieurs) vers un fichier "tempon" (txt,xml,...) comme le fait le ATTOUT (mais j'aimerais que le fichier se trouve à un lieu défini par le lisp) via une première commande.

 

Via une seconde commande pouvoir faire appel au fichier en question et qu'il s'insère soit automatiquement, soit en forçant l'intervention de l'utilisateur (comme ce que fait le ATTIN quand il ne retrouve pas l'handle).

 

Je souhaite pouvoir conserver ces étapes en deux commandes, afin de pouvoir exécuter d'autres fonctions entre l'exportation et l'importation.
Je souhaite temporiser les valeurs d'attributs dans un fichier externe à autocad afin de pouvoir utiliser la seconde commande par exemple le lendemain ou quelques jours plus tard.

 

Certains des dessins sur lesquels, je dois travailler sont de vrais torchons par moment, dans la plupart des cas, je dois repartir sur du vierge (ce qui me fait perdre les handle).

 

Ce que j'aimerais ressemble très fort au ATTOUT et ATTIN d'autocad, extraire vers un fichier externe à autocad et importer quand on veux via deux commandes distinctes. Et l'ATTIN permet de bypasser l'handle s'ils n'existent pas.

 

Le lisp auquel j'aimerais arriver, ne donne pas le choix de sélection du fichier "tempon".

 

Merci d'avance,

 

Lewis185

0 J'aime

_gile
Mentor
Mentor

Encore une fois, l'utilisation du Handle ne vaut que si le fichier tampon concerne le même dessin.

 

Si tu veux utiliser un même fichier tampon entre plusieurs dessins, il faut un autre identifiant. Le nom du bloc peut suffire si ce nom est unique dans le fichier tampon et si le dessin cible ne contient qu'une référence dudit bloc, sinon, une intervention de l'utilisateur sera nécessaire.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime

lewis185
Advocate
Advocate

Le nom du bloc reste inchangé entre le dessin A et le B.

Mis à part l'exportation du attout (qui utilise les handle), je ne connais aucun autre moyen.

0 J'aime

_gile
Mentor
Mentor
Solution acceptée

Le LISP ci-dessous fonctionne avec un fichier tels que généré avec ATTOUT (Express Tools). Il ne tient pas compte des Handles.

 

La commande ATTIMP invite l'utilisateur à spécifier le fichier txt généré par ATTOUT.

Les attributs des blocs uniques à la fois dans le fichier tampon et dans le dessin cible sont modifiés automatiquement.

En cas de blocs dupliqués, l'utilisateur est invité à sélectionner le bloc cible (les valeurs d'attributs s'affichent sur la ligne de commande.

 

;;; gc:str2lst
;;; Transforme un chaine avec séparateur en liste de chaines
;;; ;;; Arguments ;;; str : la chaîne ;;; sep : le séparateur (defun gc:str2lst (str sep / pos) (if (setq pos (vl-string-search sep str)) (cons (substr str 1 pos) (gc:str2lst (substr str (+ (strlen sep) pos 1)) sep)) (list str) ) ) ;;; gc:SetAttribs ;;; Modifie les valeurs d'attribut
;;; ;;; Arguments ;;; blk : le nom d'entité du bloc ;;; lst : la liste des attributs à modifier sous forme de paires pointées (ETIQUETTE . valeur) (defun gc:SetAttribs (bloc lst / attrib val) (setq attrib (entget (entnext bloc))) (while (= (cdr (assoc 0 attrib)) "ATTRIB") (if (setq val (assoc (cdr (assoc 2 attrib)) lst)) (entmod (subst (cons 1 (cdr val)) (assoc 1 attrib) attrib)) ) (setq attrib (entget (entnext (cdr (assoc -1 attrib))))) ) (reverse lst) ) ;;; ATTIMP ;;; Importe les attributs depuis un fichier tampon ;;; Les attributs des blocs uniques à la fois dans le fichier tampon et dans le dessin cible ;;; sont modifiés automatiquement ;;; En cas de blocs dupliqués, l'utilisateur est invité à sélectionner le bloc cible (defun c:ATTIMP (/ filename file line lst tags sel) (if (setq filename (getfiled "Sélectionnez le fichier" "" "txt" 8)) (progn (setq file (open filename "r")) (while (setq line (read-line file)) (setq lst (cons (cdr (gc:str2lst line "\t")) lst)) ) (close file) ) ) (setq lst (reverse lst) tags (cdar lst) lst (mapcar '(lambda (l) (cons (car l) (vl-remove-if '(lambda (x) (= (cdr x) "<>")) (mapcar '(lambda (a b) (cons a b)) tags (cdr l)) ) ) ) (cdr lst) ) ) (foreach l lst (if (setq sel (ssget "_X" (list (cons 0 "INSERT") (cons 2 (car l))))) (if (and (= 1 (sslength sel)) (= 1 (length (vl-remove-if-not '(lambda (x) (= (car x) (car l))) lst) ) ) ) (progn (gc:SetAttribs (ssname sel 0) (cdr l)) ) (progn (prompt (strcat "\nSelectionnez un bloc '" (car l) "' pour les attributs :" ) ) (foreach a (cdr l) (prompt (strcat "\n" (car a) " = " (cdr a))) ) (if (setq sel (ssget "_+.:E:S" (list (cons 0 "INSERT") (cons 2 (car l))) ) ) (gc:SetAttribs (ssname sel 0) (cdr l)) ) ) ) ) ) (princ) )


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

lewis185
Advocate
Advocate

Merci beaucoup, il fonctionne encore mieux que demandé.

0 J'aime