Aller au contenu

Code(s) de champ(s)


Messages recommandés

Posté(e)

Salut,

 

La fonction Visual LISP vla-FieldCode retourne le code de champ d'un texte ou mtexte mais ne fonctionne pas avec les attributs de bloc (du moins jusqu'à la version 2007).

 

J'ai donc essayé de faire une fonction plus polyvalente, qui retourne la chaîne de caractères des textes, mtextes et des attributs avec le(s) code(s) de champ(s).

 

Je n'ai pas testé avec tous les types de champs (la tache est trop vaste), mais ça semble fonctionner.

 

Merci à Patrick_35 pour la routine dec qui convertit un hexadécimal en décimal.

 

EDIT : correction mineures (variables locales)

 

EDIT 2 : modification de la routine Ename->ObjectID pour qu'elle fonctionne avec toutes les versions liguistiques.

 

;; FIELDCODE (gile)
;; Retourne la chaîne de caractère d'un attribut, texte ou mtexte
;; avec le(s) code(s) de champ(s)
;;
;; Argument : nom d'entité de l'objet (ENAME)

(defun FieldCode (ent / elst dict1 dict2 field1 field2 str pos objID)
 (setq elst (entget ent))
 (if (and
(member (cdr (assoc 0 elst)) '("ATTRIB" "MTEXT" "TEXT"))
(setq dict1 (cdr (assoc 360 elst)))
(setq dict2 (dictsearch (cdr (assoc 360 elst)) "ACAD_FIELD"))
(setq field1 (entget (cdr (assoc 360 dict2))))
(setq str (cdr (assoc 2 field1)))
(setq pos 0)
     )
   (while (setq pos (vl-string-search "\\_FldIdx " str pos))
     (setq field2 (entget (cdr (assoc 360 field1)))
    field1 (vl-remove (assoc 360 field1) field1)
    str	   (strcat
	     (substr str 1 pos)
	     (if (setq objID (cdr (assoc 331 field2)))
	       (vl-string-subst
		 (strcat "ObjId " (itoa (ename->objectID objID)))
		 "ObjIdx"
		 (cdr (assoc 2 field2))
	       )
	       (cdr (assoc 2 field2))
	     )
	     (substr str (1+ (vl-string-search ">%" str pos)))
	   )
     )
   )
 )
 str
)
;; ENAME->OBJECTID
;; Retourne l'ObjectID correspondant à un ename
;;
;; Argument : un ename

(defun ename->objectID (ename)
 ((lambda (str)
    (dec (substr str (+ 3 (vl-string-search ":" str)) 8))
  )
   (vl-princ-to-string ename)
 )
)

;; DEC (Patrick_35)
;; conversion hexadécimal -> décimal
;;
;; Argument : un hexadédimal (chaîne ou entier)

(defun dec (n / r s)
 (if (= (type n) 'INT)
   (setq n (itoa n))
 )
 (setq r 0)
 (foreach s (vl-string->list (strcase n))
   (setq r (+ (lsh r 4) (- s (if (  )
) 

[Edité le 26/4/2008 par (gile)]

 

[Edité le 27/4/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Haaarrggh je ne voulais pas regarder mais trop tard.... J'ai été tenté !!!

 

Hop ! Ctrl+C, Ctrl+V, et je reviens !!

 

Merci encore ! ;)

 

EDIT : Heu... Il me marque "Nombre arguments insuffisant"... Je l'ai copié directement dans un .lsp, et il manque pas qqchose après le Defun ?

 

A+++

 

[Edité le 26/4/2008 par phil_vsd]

"La ligne droite est le plus court chemin entre deux points, à condition que les deux points soient bien en face l'un de l'autre" P. Desproges.

Posté(e)

Salut,

 

Il me marque "Nombre arguments insuffisant"

 

FieldCode est une routine qui définit une nouvelle fonction, cette fonction s'utilise comme une fonction LISP prédéfinie et requiert un argument, le nom d'entité du texte, mtexte ou attribut.

 

Pour la tester tu peux faire :

 

(setq ent (car (nentsel "\nSélectionnez un champ: "))) 
(Fieldcode ent) 

 

ou directement :

 

(Fieldcode (car (nentsel "\nSélectionnez un champ: "))) 

 

[Edité le 27/4/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Hello,

 

J'ai commencé mon lisp en insérant quelque slignes. Tout va bien quand je lance, il me demande de choisir un champs mais après le choix j'ai le message :

 

erreur no function definition

 

 (defun c:ccp ()

(Fieldcode (car (nentsel "\nSélectionnez un champ: "))) 

(defun FieldCode (ent / elst dict1 dict2 field1 field2 str)
(setq elst (entget ent))
(if (and

etc...

 

 

T'a une idée de ce qu'il peut se passer ? Je suis sur une version 2009 full.

 

Merci d'avance.

 

 

"La ligne droite est le plus court chemin entre deux points, à condition que les deux points soient bien en face l'un de l'autre" P. Desproges.

Posté(e)

Salut,

 

De l'usage des routines, dites parfois sous-routines, dans des programmes qui les appellent.

 

Comme dit plus haut, une routine définit une nouvelle fonction LISP qui peut s'utiliser comme les fonctions LISP prédéfinies, à ceci près :

- les fonctions prédéfinies peuvent admettre des arguments optionnels ou un nombre variable d'arguments, les arguments des fonctions définies en LISP sont obligatoirement requis ;

- Les fonctions prédéfinies sont automatiquement chargées avec AutoCAD alors que celles qui sont définies en LISP doivent être chargées avant de pouvoir être appelées dans une expression LISP.

 

Quand dans un un programme LISP (par exemple c:ccp) une expression appelle une sous routine (par exemple FieldCode), celle-ci doit être chargée sinon on a le message :

; erreur: no function definition: FIELDCODE

De même la fonction FieldCode appelant les sous-routines ename->objetID et dec, celle-ci doivent être chargées aussi.

 

 

Donc dans la structure du programme :

 

- soit ces routines font partie d'une librairie automatiquement chargée à chaque nouveau dessin (coller le code donné plus haut dans acaddoc.lsp, par exemple) et elles peuvent alors être appelées comme n'importe quelle autre fonction prédéfinie. cette méthode est intéressante pour des fonctions qui servent dans plusieurs autres codes, mais faut que la librairie soit chargée sur tous les postes susceptibles de l'utilser;

 

- soit elles sont intégrées dans le même fichier que la commande (c:ccp) mais non imbriquées dans la définition de c:ccp (coller le code dans le fichier avant ou après le (defun c:ccp ...)), elles seront alors chargées dans le dessin en même temps que le fichier, donc accessible lors du premier lancement de ccp ou par tout autre expression. cette méthode, comme la suivante, permet d'avoir des fichiers complets, "autonomes" ;

(defun FieldCode ...)

(defun dec ...)

(defun ename->objectID ...)

(defun c:ccp ()
(Fieldcode (car (nentsel "\nSélectionnez un champ: "))) 
...
) 

 

- soit elles sont, comme tu semble l'avoir fait, imbriquées dans le (defun c:ccp ...), il faut alors que leurs définitions soient placées dans le code avant la première expression qui fait appel à elles. Cette dernière méthode, permet, si on déclare les noms de fonctions comme variables locales, qu'elles ne soient définies qu'à l'intérieur du programme et retournent à nil une foi l'exécution du programme terminée ce qui peut éviter des conflits avec des fonctions ayant le même nom.

(defun c:ccp (/ Fieldcode ename->objectID dec ...)

(defun FieldCode ...)
(defun ename->objectID ...)
(defun dec ...)

(Fieldcode (car (nentsel "\nSélectionnez un champ: "))) 
...
) 

 

[Edité le 27/4/2008 par (gile)]

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Posté(e)

Salut tous,

 

Merci Giles pour cette réponse constructive. Je note... Je note...

 

Mais je suis face à un problème. Quand on extrait le nom qui est dans l'onglet de la mise en page (Je pique la valeur système qui retourne la vue active) et que je tente de le copier vers l'espace objet, il me le transforme en "Model".... Faut que je résolve ça ou alors je transforme les champs en texte, perdant la dynamique. :o

 

 

A+++++

"La ligne droite est le plus court chemin entre deux points, à condition que les deux points soient bien en face l'un de l'autre" P. Desproges.

Posté(e)

Salut,

 

Quand on extrait le nom qui est dans l'onglet de la mise en page (Je pique la valeur système qui retourne la vue active) et que je tente de le copier vers l'espace objet, il me le transforme en "Model"...

 

Ben oui, c'est normal.

 

As tu regardé du côté des tableaux d'extraction d'attributs (si tes champs sont dans des attributs).

Dans le tableau tu auras la valeur du champ (pas une copie du code de champ) mais avec un lien vers l'attribut qui permet de mettre cette valeur à jour si l'attribut est modifié.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

  • 1 an après...
Posté(e)

Le code du premier message ne fonctionne pas avec les champs sont imbriqués.

Une nouvelle version (recursive) qui semble marcher dans tous les cas.

 

;; gc:FieldCode (gile)
;; Retourne la chaîne de caractère d'un attribut, texte ou mtexte
;; avec le(s) code(s) de champ(s)
;;
;; Argument : nom d'entité de l'objet (ENAME)

(defun gc:FieldCode (ent / foo elst xdict dict field str)

 ;;--------------------------------------------------------;;
 (defun foo (field str / pos fldID objID)
   (setq pos 0)
   (if (setq pos (vl-string-search "\\_FldIdx " str pos))
     (while (setq pos (vl-string-search "\\_FldIdx " str pos))
       (setq fldId (entget (cdr (assoc 360 field)))
             field (vl-remove (assoc 360 field) field)
             str   (strcat
                     (substr str 1 pos)
                     (if (setq objID (cdr (assoc 331 fldId)))
                       (vl-string-subst
                         (strcat "ObjId " (itoa (gc:EnameToObjectId objID)))
                         "ObjIdx"
                         (cdr (assoc 2 fldId))
                       )
                       (foo fldId (cdr (assoc 2 fldId)))
                     )
                     (substr str (1+ (vl-string-search ">%" str pos)))
                   )
       )
     )
     str
   )
 )
 ;;--------------------------------------------------------;;
 
 (setq elst (entget ent))
 (if (and
(member (cdr (assoc 0 elst)) '("ATTRIB" "MTEXT" "TEXT"))
(setq xdict (cdr (assoc 360 elst)))
(setq dict (dictsearch xdict "ACAD_FIELD"))
(setq field (dictsearch (cdr (assoc -1 dict)) "TEXT"))
     )
   (setq str (foo field (cdr (assoc 2 field))))
 )
)

;;============================================================;;

;; gc:EnameToObjectId (gile)
;; Retourne l'ObjectID correspondant à un ename
;;
;; Argument : un ename

(defun gc:EnameToObjectId (ename)
 ((lambda (str)
    (hex2dec
      (substr (vl-string-right-trim ">" str) (+ 3 (vl-string-search ":" str)))
    )
  )
   (vl-princ-to-string ename)
 )
)

;;============================================================;;

;; hex2dec (gile)
;; conversion hexadécimal -> décimal
;;
;; Argument : un hexadédimal (chaîne)

(defun hex2dec (s / r l n)
 (setq	r 0 l (vl-string->list (strcase s)))
 (while (setq n (car l))
   (setq l (cdr l)
         r (+ (* r 16) (- n (if (    )
 )
)

;;============================================================;;

;; lst2str (gile)
;; Concatène une liste et un séparateur en une chaine
;;
;; Arguments
;; lst : la liste à transformer en chaine
;; sep : le séparateur

(defun lst2str (lst sep)
 (if (cdr lst)
   (strcat (vl-princ-to-string (car lst))
    sep
    (lst2str (cdr lst) sep)
   )
   (vl-princ-to-string (car lst))
 )
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

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 compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité