Annonces

Announcement: We’re aware of an issue affecting starting a new topic from category pages and creating new blog posts. New topics can still be started directly from the relevant board. Learn more here.

LISP: ssget + récupération nombre de bloc

LISP: ssget + récupération nombre de bloc

Anonymous
Non applicable
1 896 Visites
10 Réponses
Message 1 sur 11

LISP: ssget + récupération nombre de bloc

Anonymous
Non applicable

Bonjour,

 

J'ai besoin d'aide car je tente de créer un lisp permettant de créer une sélection, puis en cliquant sur un des blocs de la sélection, en récupérer la quantité, mais seulement dans la sélection de départ et  enfin d'écrire cette quantité dans une variable que j'utiliserai ensuite pour modifier un attribut d'un autre bloc.

 

Pour la sélection pas trop de problème:

 

(defun C:FB()

(setq ss1 (ssget))

)

Je sais qu'il est possible de filtrer mais pas vraiment d'utilité puisque je dois ensuite sélectionner un des blocs dans la sélection.

 

J'ai ensuite ce bout de code permettant de récupérer le nom du bloc que l'on choisit, afin de s'en servir pour compter le nombre de bloc du même nom dans la sélection (je ne sais pas si c'est la meilleure façon de faire ?) :

 

(defun C:BN()
 
(setq blname (cdr(assoc 2 (entget (ssname (ssget (cadr(entsel"\nSelection du bloc:"))) 0)))))
  
)

 

Une fois le bloc choisis, j'arrive bien à récupérer son nom en tapant !blname dans la barre de commande.

Le nom du bloc comporte des espaces.

 

Mais je n'arrive pas à l'utiliser avec sslength afin d'en connaitre le nombre présent dans la sélection.

Merci à vous pour votre aide ! 

0 J'aime
Solutions acceptées (2)
1 897 Visites
10 Réponses
Replies (10)
Message 2 sur 11

_gile
Consultant
Consultant

Salut,

 

En faisant les choses dans l'autre sens ça sera plus facile. Connaissant le nom du bloc, tu peux filtrer le jeu de sélection.

(defun c:BN (/ ent elst ss)
  (if
    (and
      (setq ent (car (entsel "\nSélectionnez le bloc source: ")))
      (setq elst (entget ent))
      (= (cdr (assoc 0 elst)) "INSERT")
      (setq ss (ssget (list (cons 0 "INSERT") (assoc 2 elst))))
    )
     (alert (strcat (itoa (sslength ss)) " blocs sélectionnés"))
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 sur 11

Anonymous
Non applicable

Merci pour cette réponse rapide !

 

Ça marche très bien en filtrant de cette manière, mais on est obligé de sélectionner à chaque fois le jeu de sélection "ss".

Ce que j'aimerais faire, c'est créer un jeu de sélection en amont, comportant plusieurs blocs différents et le garder en mémoire afin d'aller rechercher par après le nombre de blocs via une 2nd manipulation, en ne sélectionnant que le bloc source.

0 J'aime
Message 4 sur 11

_gile
Consultant
Consultant

Dans ce cas, autant compter directement les blocs dans la sélection :

(defun c:BN (/ ss i n l p)
  (if (setq ss (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq n (getpropertyvalue
		(getpropertyvalue
		  (ssname ss (setq i (1- i)))
		  "BlockTableRecord"
		)
		"Name"
	      )
	    l
	      (if (setq p (assoc n l))
		(subst (cons n (1+ (cdr p))) p l)
		(cons (cons n 1) l)
	      )
      )
    )
  )
  (if l
    (foreach p l
      (prompt (strcat "\n" (car p) " : " (itoa (cdr p))))
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime
Message 5 sur 11

Anonymous
Non applicable

Oui en effet, comme un lisp de comptage de bloc. Mais en faisant cela comment fait on pour transmettre la quantité de blocs à un attribut d'un autre?

 

En y réfléchissant plus, le but principal serait en fait de se servir du lisp existant "cat" de Patrick_35, afin de copier les attributs d'un bloc A vers un bloc B, et d'écrire la quantité de blocs A présent dans la sélection de départ SS à un attribut "quantité" du bloc B. Et on répéterai cette opération autant de fois que nécessaire.

 

Pour résumé:

 

- création d'une sélection, via un (setq ss (ssget))

- lisp cat

- sélection bloc A d'origine

- sélection bloc B destinataire

- les attributs identiques se copient de A vers B

- SI une sélection SS existe, le nombre de blocs A dans SS est transmis à l'attribut "quantité" du bloc B

 

Je ne sais pas si on peut modifier le lisp CAT pour arriver à ce résultat ?

0 J'aime
Message 6 sur 11

_gile
Consultant
Consultant
Solution acceptée

C'est difficile de suivre ce genre de discussion où la demande évolue (elle n'est plus la même que celle de départ).

 

D'après la dernière demande, tu voudrais :

1. stocker le décompte de blocs sélectionnés

2. sélectionner un bloc cible contenant un attribut "QUANTITE" pour y écrire la valeur dans le décompte correspondant à un bloc source sélectionné ensuite.

 

Pour la première commande, tu peux reprendre la commande c:BN ci dessus en écrivant la liste d'association contenant le décompte des blocs dans un dictionnaire (ldata).

Pour la seconde, il suffit d'inviter l'utilisateur à sélectionner le bloc cible puis le bloc source et d'écrire dans l'attribut "QUANTITE" du bloc cible la valeur correspondant au bloc source dans le décompte.

 

(defun c:BN (/ ss i n l p)
  (if (setq ss (ssget '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq n (getpropertyvalue
		(getpropertyvalue
		  (ssname ss (setq i (1- i)))
		  "BlockTableRecord"
		)
		"Name"
	      )
	    l (if (setq p (assoc n l))
		(subst (cons n (1+ (cdr p))) p l)
		(cons (cons n 1) l)
	      )
      )
    )
  )
  (vlax-ldata-put "romano_brice" "compte_blocs" l)
  (princ)
)

(defun c:EA (/ s c n i)
  (and
    (setq c (car (entsel "\nSélectionnez le bloc cible: ")))
    (= (cdr (assoc 0 (entget c))) "INSERT")
    (setq s (car (entsel "\nSélectionnez le bloc source: ")))
    (= (cdr (assoc 0 (entget s))) "INSERT")
    (setq n (getpropertyvalue (getpropertyvalue s "BlockTableRecord") "Name"))
    (setq i (cond
	      ((cdr (assoc n (vlax-ldata-get "romano_brice" "compte_blocs"))))
	      (T 0)
	    )
    )
    (setpropertyvalue c "QUANTITE" (itoa i))
  )
  (princ)
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime
Message 7 sur 11

Anonymous
Non applicable

Ça marche parfaitement sur Autocad, un grand merci.

Des collègues utilisant d'autres logiciels de DAO ont le message " Erreur : fonction indéfinie - GETPROPERTYVALUE ". Je suppose que cette fonction est propre à Autocad ??

 

 

0 J'aime
Message 8 sur 11

_gile
Consultant
Consultant
Solution acceptée

Les versions ci-dessous devraient fonctionner sur tous les logiciels qui supportent Visual LISP.

 

(vl-load-com)
(defun c:BN (/ ss i n l p)
  (if (ssget '((0 . "INSERT")))
    (progn
      (vlax-for	b (setq	ss (vla-get-ActiveSelectionSet
			     (vla-get-ActiveDocument
			       (vlax-get-acad-object)
			     )
			   )
		  )
	(setq n	(vla-get-EffectiveName b)
	      l	(if (setq p (assoc n l))
		  (subst (cons n (1+ (cdr p))) p l)
		  (cons (cons n 1) l)
		)
	)
      )
      (vla-Delete ss)
    )
  )
  (vlax-ldata-put "romano_brice" "compte_blocs" l)
  (princ)
)

(defun c:EA (/ s c n i)
  (and
    (setq c (car (entsel "\nSélectionnez le bloc cible: ")))
    (= (cdr (assoc 0 (entget c))) "INSERT")
    (setq s (car (entsel "\nSélectionnez le bloc source: ")))
    (= (cdr (assoc 0 (entget s))) "INSERT")
    (setq n (vla-get-EffectiveName (vlax-ename->vla-object s))
	  i (cond
	      ((cdr (assoc n (vlax-ldata-get "romano_brice" "compte_blocs"))))
	      (T 0)
	    )
    )
    (foreach a (vlax-invoke (vlax-ename->vla-object c) 'GetAttributes)
      (if (= (vla-get-TagString a) "QUANTITE")
	(vla-put-TextString a (itoa i))
      )
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime
Message 9 sur 11

Anonymous
Non applicable

Bonjour,

 

En effet on utilise plusieurs LISP se servant de Visual Lisp.

La partie EA fonctionne bien sur tous les software mais la partie BN me renvoie:

 

Erreur : fonction indéfinie - SETQSS

0 J'aime
Message 10 sur 11

_gile
Consultant
Consultant

Si je lis bien le message d'erreur, il semble que soit simplement l'espace entre SETQ et SS qui a sauté, vérifie le code.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 J'aime
Message 11 sur 11

Anonymous
Non applicable

De base ça fonctionne sur Autocad, une maj vers la SP3 de Zwcad 2019 a résolu le problème pour ce soft.

Un grand merci !

0 J'aime