Aller au contenu

Messages recommandés

Posté(e)

Salut Matt,

 

Ta solution donne tous les attributs qui suivent ceux du bloc sélectionné.

C'est pourquoi j'avais mis une condition d'arret au "seqend".

 

Changer l'attribut ne me parît pas bien compliqué, j'attends un peu de voir si quelqu"n d'autre se lance.

Je crois que Lovecraft peut commencer à répondre...

 

Pour info, c'est bien l'étiquette de l'attribut qui s'appelle "DATE" ?

  • Réponses 70
  • Créé
  • Dernière réponse

Meilleurs contributeurs dans ce sujet

Posté(e)

Donc, voici ma version vlisp comme promis

 

(defun c:vblat_pat(/ sel)
 (while (setq sel (entsel))
   (if (eq (vla-get-objectname (setq sel (vlax-ename->vla-object (car sel)))) "AcDbBlockReference")
     (if (eq (vla-get-hasattributes sel) :vlax-true)
(alert (substr (apply 'strcat (mapcar '(lambda (x) (strcat "\n" (vla-get-tagstring x) "\t: " (vla-get-textstring x))) (vlax-invoke sel 'getattributes))) 2))
(princ "\nCe bloc n'a pas d'attributs.")
     )
     (princ "\nCe n'est pas un bloc.")
   )
 )
 (princ)
)

 

ps : Matt666, tu as un souci avec ton lisp car tu ne testes pas la fin des entités qui composent le bloc avec le seqend, ce qui fait que si je clique un bloc, je peux me retrouver avec une liste impressionnante d'attributs (et pas obligatoirement la liste de tout les attributs (tout dépend de celui que l'on sélectionne. Si c'est le dernier bloc créé, je n'aurai que ses attributs)

pps : vinz34, l'affichage ne respecte pas l'ordre des attributs (c'est juste une inversion dans un strcat)

ppps : pour la date, un champ peut suffir

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

Hum hum...

 

C'est bien de donner des exercices... Quand on ne sait pas y répondre :casstet:

(defun c:vblat_matt (/ ent str)
   (while (or  
           (not (setq ent (car (entsel "\nSélectionner un bloc :"))))
           (/= (cdr (assoc 0 (entget ent))) "INSERT")
       )
   )
   (if (cdr (assoc 66 (entget ent)))
       (progn
           (setq str "\nCe bloc contient un ou des attributs : ")
           (while (and 
                   (setq ent (entnext ent))
                   (eq (cdr (assoc 0 (entget ent))) "ATTRIB")
               )
               (if (<= (strlen (cdr (assoc 2 (entget ent)))) 5)
                   (setq str (strcat 
                           str 
                           "\n" 
                           (cdr (assoc 2 (entget ent))) 
                           "  ->\t\t" 
                           (cdr (assoc 1 (entget ent)))
                   ))
                   (setq str (strcat 
                           str 
                           "\n" 
                           (cdr (assoc 2 (entget ent))) 
                           "  ->\t" 
                           (cdr (assoc 1 (entget ent)))
                   ))
               )
           )
           (alert str)
       )
       (princ "\nCe bloc ne contient pas d'attribut.")
   )
   (princ)
)

 

 

Oui, Bien vu patrick_35 et Vinz34, il y avait une condition manquante....

 

pour la date, un champ peut suffir

C'est juste pour l'exercice...

"Chacun compte pour un, et nul ne compte pour plus d'un."

Posté(e)

Salut,

 

Ma proposition :

 

(defun c:vblat_vinz (/ e elist date)
 (while (or
   (not (setq e (car (entsel "\nSélectionner un bloc :"))))
   (/= (cdr (assoc 0 (setq elist (entget e)))) "INSERT")
 )
 )
 (if (assoc 66 elist)
   (progn
     (setq e (entnext e))
     (while e
(cond
  ((= (cdr (assoc 0 (setq elist (entget e)))) "ATTRIB")
   (progn
     (setq date	(strcat
		  (substr (rtos (getvar "cdate")) 7 2)
		  "."
		  (substr (rtos (getvar "cdate")) 5 2)
		  "."
		  (substr (rtos (getvar "cdate")) 1 4)
		)
     )
     (if (= (cdr (assoc 2 elist)) "DATE")
       (entmod (subst (cons 1 date) (assoc 1 elist) elist))
     )
     (setq e (entnext e))
   )
  )
  ((= (cdr (assoc 0 (setq elist (entget e)))) "SEQEND")
   (setq e nil)
  )
)
     )
   )
   (princ "\nCe bloc ne contient pas d'attribut.")
 )
 (princ)
) 

 

PS : Patrick,

 

J'ai beau chercher, je n'y comprends rien au vlisp, enfin je le comprends mais je ne saurais pas le refaire.

Je ne sais pas d'où sortent des commandes comme "vla-get-hasattributes" ou "vla-get-tagstring" introuvables dans la documentation du développeur d'Autocad.

 

Pour l'ordre d'affichage des attributs, si j'avais à les classer ce serait par ordre alphabétique avec "acad_strlsort".

Posté(e)

Vinz34

Si tu le comprends, c'est déjà un grand pas :)

Je vais t'expliquer une démarche simple avec le vlisp.

tu sélectionnes un objet.

(setq ent (car (entsel)))

que tu transformes en objet vla.

(setq ent (vlax-ename->vla-object ent))

pour connaître ses propriétés (ou liste des dxf mais sauce vla).

(vlax-dump-object ent)

Donc, pour savoir par exemple si j’ai des attributs (code 66 en dxf), je trouve dans la liste HasAttributes.

Je fais un (vla-get-HasAttributes ent) qui me retourne :vlax-true. J’ai bien des attributs :) (un :vlax-false egal faux)

 

Pour les méthodes applicables (ou autrement dit, les commandes applicables à l'objet).

(vlax-dump-object ent T)

Je constate que j’ai GetAttributes, autrement dit, pour récupérer les attributs (chouette, je n’ai pas besoin d’une boucle pour faire le trie, comme en autolisp :) )

 

Un (vla-GetAttributes ent) me retourne un #<variant 8201 ...> qu’il va falloir transformer.

Donc un (vlax-variant-value (vla-GetAttributes ent)) me retourne un #<safearray...>

Grrrr, il va encore falloir convertir.

Donc un (vlax-safearray->list (vlax-variant-value (vla-GetAttributes ent))) me donne enfin ma liste d’attributs.

Heureusement, il y a plus court avec un (vlax-invoke ent ‘GetAttributes) qui me donne directement cette liste.

Il ne reste plus qu’a jouer avec un mapcar et un apply sur ma liste d'attributs (que de l’autolisp :o ;) ).

 

Maintenant, si tu veux une aide sur les objets (si, si, elle existe sur autocad)

tu lances vba (alt+f11)

tu lances l'explorateur d'objets (f2)

et pour retrouver ce que je t'ai expliqué plus haut avec le vlax-dump-object, comme par exemple pour notre exemple de bloc avec attributs, tu vas dans AcadBlocReference (tu remarqueras que la variable ent a par exemple comme valeur #<VLA-OBJECT IAcadBlockReference2 17074654> si c'est un bloc qui a été choisi) et tu auras les détails avec une aide et des exemples (en vba :( ;) )

Dans l'explorateur d'objets, il n'est pas évident au début de bien comprendre les différentes classes, mais on arrive petit à petit à saisir la logique.

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Posté(e)

1 journée d'absence...

maintenant faut que je traduise...

c'est en effet un peu rapide pour moi mais vous en faites pas

si j'ai une question précise je le ferai savoir...

Posté(e)

Pascal19,

 

Désolé, on ne t'as pas vu depuis jeudi, alors je pensais que tu avais oublié ce sujet.

 

Patrick_35

 

Merci beacoup de m'éclairer, j'y vois déja plus clair.

Je vais enfin pouvoir me pencher sur ce language bien plus puissant que l'autolisp.

Posté(e)

bonjour, ah la c'est du grand art patrick,

je connaissais la reponse en autolisp car j'avais dejàn un travail similaire avec des polylignes 3D donc le meme principe avec des blocs avec atribut. Donc j'ai essayé de de trouver un solution en vlisp que je decouvre grace a vous.

 

Une grand merci pour cette explication détaillée.

 

@plus

Posté(e)

Dément, une explication de code VLISP !!!

 

Je commence à comprendre, aussi...

Merci patrick_35 !!!

"Chacun compte pour un, et nul ne compte pour plus d'un."

  • 2 semaines après...
Posté(e)

Bonjour à tous

 

Pour relancer un peu ce spécial débutant, j'ai besoin d'un lisp

utilisant ce qui a été fait precedemment:

a partir d'une sélection de bloc je voudrai exploser les blocs sans attributs (explode)

et exploser en conservant les attributs les blocs à attributs (burst)

 

j'ai fait ça:

 

(defun c:exblatt(/ blatt)

(setq sel1 (ssget))

(setq compteur 0)

(setq longsel1 (sslength sel1))

(while (< compteur longsel1)

(setq entite (ssname sel1 compteur))

(setq blatt (cdr (assoc 66 (entget entite))))

 

(if (<> blatt nil)

(command "burst" entite)

(command "_explode" entite)

)

(setq compteur (1+ compteur))

 

)

)

 

mais ça marche pas à priori à cause de "burst"...

 

D'avance merci

Posté(e)

mais ça marche pas à priori à cause de "burst"...

 

Je pense aussi !

 

Le problème vient que BURST n'est pas une commande "originelle" mais une fonction lisp définissant une nouvelle commande.

Utiliser "command" pour l'utiliser fonctionne, mais le problème est que cette fonction de redonnera pas la main à ta fonction lisp appelante.

 

Le mieux est d'ouvrir le fichier burst.lsp dans les express et de voir quelle fonction tu pourrait utiliser. J'ai rapidement jeté un coup d'oeil et je pense qu'il faudrait utiliser la fonction:

(Defun BURST-ONE (BNAME / .....) ......)

 

donc dans ton code et dans ta boucle (while, faire (BURST-ONE entite) au lieu de (command 'burst entite)

 

Voilà, j'ai pas testé, mais je pense que comme ceci, cela fonctionnera

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Bonsoir à toutes et tous,

 

Testé vite fait avec cette écriture =>

 

 (defun c:exblatt(/ blatt)
(setq sel1 (ssget))
(setq compteur 0)
(setq longsel1 (sslength sel1))
(while ((setq entite (ssname sel1 compteur))
(setq blatt (cdr (assoc 66 (entget entite))))

(if ( blatt nil)
(BURST-ONE entite)
 (command "_explode" entite)
)
(setq compteur (1+ compteur))

)
)

 

AutoCAD renvoi =>

 

Commande:

Commande: EXBLATT

Choix des objets: 295 trouvé(s)

Choix des objets:

; erreur: no function definition:

Commande:

Civil 3D 2025 - COVADIS_18.3b

https://www.linkedin...3%ABt-95313341/

Posté(e)

Moi non plus ça marche pas...

j'arrive pas à lancer burst-one, même en lançant (burs-one) seul, il veut pas rentrer dans le sous-programme (nombre d'arguments insuffisants)

Posté(e)

; erreur: no function definition: <>

 

S'assurer dans le code que burst est disponible, donc il faudrait rajouter:

 

(if (not c:burst) (load"burst"))

 

Mais le problème est que dans la fonction (c:burst ( / burst-one ....)) burst-one est déclarée en variable locale, donc inaccessible.

Si vous bidouillez (déconseillé) le fichier burst.lsp en enlevant les variables locales, ça fonctionne

 

j'arrive pas à lancer burst-one

 

La fonction (burst-one) demande obligatoirement un argument, qui est le nom de l'entité.

(burst-one (car (entsel))) est par exemple un appel valide.

 

 

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

Il n'est jamais bon de modifier un fichier (qui fonctionne parfaitement) surtout venant des express.

 

En effet ces outils sont interdépendant pour l'initialisation (variables etc..) et les gestions d'erreur, pour s'en persuader, il suffit des rendre le chemin inaccessible, de faire une copie d'une fonction (par exemple burst.lsp) dans un autre dossier déclaré, et d'essayer de le lancer :casstet:

 

Aux mieux je suggère de faire une copie dans les express en changeant le nom du fichier et en changeant aussi les noms des fonctions principales liées à burst même.

 

Comme ça l'original sera préservé ainsi que le fonctionnement des Express ;)

 

Ou alors sans toucher à rien, faire comme au début: un appel par (command) , mais celui devra être la dernière exécution du code. Pas top et limité pour les possibilités d'inclure ce code des express... :(

 

[Edité le 31/1/2008 par bonuscad]

Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius

Posté(e)

J'ai une solution, je suis tout fier

mais les pro du lisp vont surement trouver à redire...

 

en fait j'ai grugé, comme j'y arrivais pas, j'ai mis les blocs à attribut

dans un jeu de sélection (sel2):

 

(defun c:exblatt(/ blatt)

(setq sel1 (ssget))

(setq sel2 (ssadd))

(setq compteur 0)

(setq longsel1 (sslength sel1))

(while (< compteur longsel1)

(setq entite (ssname sel1 compteur))

(setq blatt (cdr (assoc 66 (entget entite))))

(if (/= blatt nil)

(ssadd entite sel2)

(command "_.explode" entite)

)

 

(setq compteur (1+ compteur))

 

)

)

 

ensuite j'ai associé un boutton a la macro suivante:

 

^C^C(load"exblatt.lsp");exblatt; _.PSELECT;!sel2;;burst;

 

 

Résultat sur une sélection de blocs, en cliquant le boutton

autocad explose les blocs et fait "burst" sur les blocs à attribut

ce que je voulais...

 

Posté(e)

Salut,

 

Ca faisait longemps. Je ne donnerai pas l'avis d'un pro, mais tu simplifier tes setq :

 

setq sel1 (ssget))
(setq sel2 (ssadd))
(setq compteur 0)
(setq longsel1 (sslength sel1))

 

(setq sel1 (ssget)) sel2 (ssadd) compteur 0 longsel1 (sslength sel1))

 

En tout cas, je vois que tu as fait de beaux progrès.

 

[Edité le 31/1/2008 par vinz34]

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é