LISP: calcul attribut sur plusieurs blocs, sommeprod()

LISP: calcul attribut sur plusieurs blocs, sommeprod()

Anonymous
Non applicable
1 340 Visites
7 Réponses
Message 1 sur 8

LISP: calcul attribut sur plusieurs blocs, sommeprod()

Anonymous
Non applicable

Bonjour,

 

Débutant en LISP, je tente de créer un programme reproduisant le SOMMEPROD() d'Excel.

J'ai plusieurs blocs, avec les mêmes attributs mais avec des valeurs différentes et j'aimerais obtenir la sommeprod() de certains attributs bien précis, en sélectionnant tous les blocs.

 

J'ai déjà récupérer une partie de LISP (LeeMac) que j'ai modifié pour mes besoins, et cela marche pour un bloc . Par contre je sèche pour la partie boucle sur les différents blocs et calcul final pour faire la somme globale.

Ci-dessous le code qui fonctionne pour un bloc et qui récupère le produit de l'attribut "quantity" par "power":

 

 

(vl-load-com)

(defun c:calc (/ LM:GetAttributeValue ss)

  (defun LM:GetAttributeValue (blk tag / val enx)
    (while
      (and
        (null val)
        (= "ATTRIB"
           (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk))))))
        )
      )
       (if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
         (setq val (cdr (assoc 1 enx)))
       )
    )
  )

  (if (and (setq ss (ssget))
           (setq attValue1 (LM:GetAttributeValue (ssname ss 0) "POWER"))
           (setq attValue2 (LM:GetAttributeValue (ssname ss 0) "QUANTITY"))
           (setq total (* (atof attValue1) (atof attValue2)))
      )
    (prin1 total)	
  )
  (princ)
)

 

 

La 2nd partie n'est pas forcément optimale vu que c'est de moi 😅

Quelqu'un peut il me venir en aide svp ?

 

Merci !

0 J'aime
Solutions acceptées (1)
1 341 Visites
7 Réponses
Replies (7)
Message 2 sur 8

CADaSchtroumpf
Advisor
Advisor
Solution acceptée

Bonjour,

En l'écrivant comme ceci?

La sélection est sécurisée par un filtre et le total est effectué si les attributs sont différent de nil.

(vl-load-com)

(defun c:calc (/ LM:GetAttributeValue ss sum n attvalue1 attvalue2 total)

  (defun LM:GetAttributeValue (blk tag / val enx)
    (while
      (and
        (null val)
        (= "ATTRIB"
           (cdr (assoc 0 (setq enx (entget (setq blk (entnext blk))))))
        )
      )
       (if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
         (setq val (cdr (assoc 1 enx)))
       )
    )
  )

  (if (setq ss (ssget '((0 . "INSERT") (66 . 1))) sum 0.0)
      (repeat (setq n (sslength ss))
           (setq attValue1 (LM:GetAttributeValue (ssname ss (setq n (1- n))) "POWER"))
           (setq attValue2 (LM:GetAttributeValue (ssname ss n) "QUANTITY"))
           (if (and attvalue1 attvalue2)
             (setq
               total (* (atof attValue1) (atof attValue2))
               sum (+ total sum)
             )
           )
      )
  )
  (prin1 sum)
  (princ)
)
Message 3 sur 8

patrick.emin
Alumni
Alumni

Bonjour @Anonymous 

Si une des réponses résout votre problème ou vous a permis de mieux le comprendre, voulez vous avoir l'amabilité de cliquer sur le bouton "Approuver la solution" en bas de la réponse qui apporte une solution?
Merci de ne pas accepter comme solution le message que vous êtes en train de lire.


Patrick Emin animateur de la communauté francophone


Vous avez trouvé un message utile? Alors donnez un "J'aime" à ce message!
Votre question a eu une réponse satisfaisante? Voulez vous avoir l'amabilité de cliquer sur le bouton
 APPROUVER LA SOLUTION  en bas de la réponse qui apporte une solution?
Signez notre Livre d'Or
0 J'aime
Message 4 sur 8

Anonymous
Non applicable

Impeccable ! un grand merci.

 

J'ai trouvé ce lien vers un forum:

https://www.cadtutor.net/forum/topic/57284-get-numbers-from-string/

afin de trier et garder que les parties numériques de string, mais je n'arrive pas à l'intégrer au code.

 

Y'a t il un autre moyen ?

0 J'aime
Message 5 sur 8

CADaSchtroumpf
Advisor
Advisor

@Anonymous  a écrit :

Impeccable ! un grand merci.

 

J'ai trouvé ce lien vers un forum:

https://www.cadtutor.net/forum/topic/57284-get-numbers-from-string/

afin de trier et garder que les parties numériques de string, mais je n'arrive pas à l'intégrer au code.

 

Y'a t il un autre moyen ?


Voilà pour l'intégrer, à la différence du code proposé j'ai inclus le caractère "." (point) pour interpréter éventuellement un nombre réel. Le petit problème et que cela va aussi inclure le caractère "/" donc à voir si cela peut poser problème et devoir affiner le code.

(vl-load-com)
(defun c:calc (/ LM:GetAttributeValue ss sum n attvalue1 attvalue2 total)
	(defun LM:GetAttributeValue (blk tag / val enx)
		(while
			(and
				(null val)
				(= "ATTRIB"
					(cdr (assoc 0 (setq enx (entget (setq blk (entnext blk))))))
				)
			)
			(if (= (strcase tag) (strcase (cdr (assoc 2 enx))))
				(setq val (cdr (assoc 1 enx)))
			)
		)
	)
	(if (setq ss (ssget '((0 . "INSERT") (66 . 1))) sum 0.0)
		(repeat (setq n (sslength ss))
			(setq
				attValue1(LM:GetAttributeValue (ssname ss (setq n (1- n))) "POWER")
				attValue2 (LM:GetAttributeValue (ssname ss n) "QUANTITY")
			)
			(if (and attvalue1 attvalue2)
				(setq
					total
					(*
						(atof
							(vl-list->string
								(vl-remove-if-not '(lambda (i) (< 45 i 58)) (vl-string->list attValue1))
							)
						)
						(atof
							(vl-list->string
								(vl-remove-if-not '(lambda (i) (< 45 i 58)) (vl-string->list attValue2))
							)
						)
					)
					sum (+ total sum)
				)
			)
		)
	)
	(prin1 sum)
	(princ)
)
0 J'aime
Message 6 sur 8

Anonymous
Non applicable

Bonjour,

 

j'ai tenté de rajouter un nouveau calcul, dans la même sélection de bloc, mais avec un 3ème attribut, afin d'avoir le résultat de la sommeprod(att1 x att2), que l'on a déjà avec le code au dessus, ET de la sommeprod(att2 x att3). l'attribut 2 "QUANTITY" étant commun aux deux calculs.

 

J'ai ajouté la ligne:

 

attValue3 (LM:GetAttributeValue (ssname ss (setq n (1- n))) "FLUX")

 

avec un nouveau total2 pour le résultat de la nouvelle multiplication.

 

Mais impossible d'avoir un résultat ou alors il faut sélectionner 2 fois de suite l'ensemble de blocs.

Est ce que le soucis se trouve au niveau du " sum (+ total sum) " étant donné que sum est définit au tout début dans la sélection à faire?

 

Pour le moment j'ai différencier les 2 lisp sous 2 commandes différentes, mais j'aimerais les regrouper en un, afin de ne pas avoir à sélectionner deux fois les mêmes blocs

 

merci pour votre aide !

 

0 J'aime
Message 7 sur 8

Blue8Burn
Advocate
Advocate

Bonjour à tous, 

 

Tout d'abord, j'utilise souvent ce lisp et il est top, merci 🙂

 

Ma question, j'ai un bloc avec plusieurs visibilités et un attribut qui s'appelle SOMMEPROD.1 pour la visibilité 1,  SOMMEPROD.2 pour la visibilité 2 etc... et je voudrais faire le calcul avec le SOMMEPROD."x" de la visibilité active. 

Cela vous semble-t-il réalisable ? Et si oui, pouvez-vous m'aider ?

 

Ps: j'ai essayé avec "SOMMEPROD." et "SOMMEPROD.*" sans succès 😕

 

Merci d'avance 🙂

0 J'aime
Message 8 sur 8

Blue8Burn
Advocate
Advocate

Bonjour à tous, 

 

Tout d'abord, j'utilise souvent ce lisp et il est top, merci 🙂

 

Ma question, j'ai un bloc avec plusieurs visibilités et un attribut qui s'appelle SOMMEPROD.1 pour la visibilité 1,  SOMMEPROD.2 pour la visibilité 2 etc... et je voudrais faire le calcul avec le "SOMMEPROD."x"" de la visibilité active. 

Cela vous semble-t-il réalisable ? Et si oui, pouvez-vous m'aider ?

 

Ps: j'ai essayé avec "SOMMEPROD." et "SOMMEPROD.*" sans succès 😕

 

Merci d'avance 🙂

0 J'aime