stephan35 Posté(e) le 5 mars 2007 Posté(e) le 5 mars 2007 Bonjour à tous, Mon problème est le suivant: Je crée des fonctions:(defun @R1 ( $a / )...) (defun @R2 ( $a / )...) (defun @R3 ($a / )...) Je créé une fonction principale dans laquelle je veux appeler une fonction secondaire en parametre variable : (defun @Princ ( @macro $a / )(@macro $a)) Si je tape :(@princ @R1 "po") je cherche à appliquer (@macro $a) = (@R1 $a) !!! :casstet: Est-ce possible ??? Merci !
Patrick_35 Posté(e) le 5 mars 2007 Posté(e) le 5 mars 2007 Je ne comprends pas, ça marche (même si ta logique me dépasse) (defun @R1 ($a) (princ (strcat "\nFonction @R1, argument " $a)) ) (defun @R2 ($a) (princ (strcat "\nFonction @R2, argument " $a)) ) (defun @R3 ($a) (princ (strcat "\nFonction @R3, argument " $a)) ) (defun @Princ (@macro $a) (@macro $a) (princ) ) (@princ @R1 "po") --> Retourne Fonction @R1, argument po @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
stephan35 Posté(e) le 5 mars 2007 Auteur Posté(e) le 5 mars 2007 Et oui çà marche !En écrivant l'énoncée du problème j'avais corrigé mon erreur ... :casstet: (@princ @R1 "po") et non (@princ (@R1) "po") , milles excuses !!!!!! :( Je ne comprends pas, ça marche (même si ta logique me dépasse) Je ne sais pas si je dois le prendre comme un compliment ? ;) En fait, je remprends l'ensemble de mes listings en compilant les lignes d'écritures, soit au bas mot 250 lisp à revoir,et je me suis apperçu que dans 60% des cas je réécrivais ce que j'avais déjà écrit ailleur avec une ou deux variantes .... Comme tout le monde j'avais quelques fonctions définient dans le AutoCAD.lsp mais j'en ai créé une ribambelle à droite à gauche etc., Mon objectif est de réduire au minima les lignes de codes en créant des tronc commun, les variantes seront passées en paramètres dans les fonctions, y compris les fonctions appelées dans les fonctions .... :casstet: on y vient : tous mes ssget seront par exemple réduit à une fonction, idem pour l'exploration du résultat du ssget, exemple : (setq $nom_bloc (@R2 (setq &e (entget (setq #e (car(entsel))))))) ; Selectionne dans le document tous les blocs portant ce nom (@SS_@R0_@R2 (@R0 &e)(@R2 &e)) @R0 = assoc 0 &e@R2 = assoc 2 &e (defun @R2 ( &entget / tmp ) (if (not &entget)(progn (alert (strcat "@R2 \nValeur nil pour &entget"))(exit))) (cdr(assoc 2 &entget)) ) Puis une macro qui explore le jeu de selection : (defun @X_SS (#SS @macro/ #C) ;(if (not #SS)(progn (alert (strcat "@X_SS \nValeur nil pour #SS"))(exit))) (if (not @MX_SS)(progn (alert (strcat "@X_SS \nMacro nil pour @MX_SS"))(exit))) (setq #C 0) (if #SS (repeat (sslength #SS) (setq #SSN (ssname #SS #C)) (@Macro #SSN) (setq #C (1+ #C)) ) ) ) Une macro de traitement dans le jeu de selection (defun @MX_SS ( #SSN / ) (print (@S_AE #SSN "ATTRIB" "L3" 1 nil)) (@S_AE #SSN "ATTRIB" "L3" 1 (strcat ":" (@S_AE #SSN "ATTRIB" "L3" 8 nil) ":" (@S_AE #SSN "ATTRIB" "L3" 1 nil) ) ) ) Et enfin on l'utilise(@X_SS #SS @MX_SS) Etc. Bref, sur un test comparatif , répétérif (repeat 500) sur une routine développé de la sorte et une autre développé en linéaire ,le temps gagné est divisé par 20 ;) (et je ne sais pas pourquoi !) ... :casstet: Voilà ! [Edité le 5/3/2007 par stephan35]
Patrick_35 Posté(e) le 5 mars 2007 Posté(e) le 5 mars 2007 Je veux bien te croire, mais il faut être très rigoureuxLe problème avec ce type de logique, c'est la compréhension du lisp qui devient vite du chinois si on ne met pas un minimum de commentairesIl faut être ingénieur pour te suivre ;) Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
stephan35 Posté(e) le 5 mars 2007 Auteur Posté(e) le 5 mars 2007 Il est vrai qu'il faut laissé une floppée de commentaire, pour le cas ou on y revient 6 mois après .... ;) Mais aussi, avec une simple convention de repère que l'on s'impose, les choses vont toutes seules ... (en téhorie ...) ;) Exemple: pour les variables :$tmp = chaine#tmp = valeur&tmp = liste niveau 0&&tmp = liste imbriquée&&&tmp = etc@tmp = fonction(@tmp $tmp) = fonction avec 1 chaine en entrée et l'on peut tout imaginer .... d'ailleurs pourquoi ne pas proposer à autodesk de faire de la déclaration de variable pour le lisp ......... (ça va mettre le bazar ? :casstet: ) A+
stephan35 Posté(e) le 5 mars 2007 Auteur Posté(e) le 5 mars 2007 Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe Aîe !!!!!!! Bon ça ne marche pas ? :cool: Si ici : (defun @R1 ($b / ) (princ (strcat "\nFonction @R1, argument " $b)) ) (defun @R2 ($b / ) (princ (strcat "\nFonction @R2, argument " $b)) ) (defun @R3 ($b / ) (princ (strcat "\nFonction @R3, argument " $b)) ) (defun @Princ (@macro $a / ) (@macro $a) (princ) ) (@Princ @R1 "opop") (@Princ @R2 "opop") (@Princ @R3 "opop") Fonction @R1, argument opopFonction @R2, argument opopFonction @R3, argument opop Alors : (defun @X_SS (@Macro #SS / #C) (if (not #SS)(progn (alert (strcat "@X_SS \nValeur nil pour #SS"))(exit))) (if (not @Macro)(progn (alert (strcat "@X_SS \nMacro nil pour @MX_SS"))(exit))) (setq #C 0) (if #SS (repeat (sslength #SS) (@Macro (setq #SSN (ssname #SS #C))) (setq #C (1+ #C)) ) ) ) (defun @MX_SS ( #SSN / ) (setq &Liste_Globale(@S_AL_@R-1_@R2_@R1 #SSN "ATTRIB" (list "RA""RB""RC""RD""RE""RF""RG""RH""RI""RJ""RK""RL""RM""RN""RO""RP""RQ""RR""RS""RT""RU""RV""RW""RX""RY""RZ""DATEA""DATEB""DATEC""DATED""DATEE""DATEF""DATEG""DATEH""DATEI""DATEJ""DATEK""DATEL""DATEM""DATEN""DATEO""DATEP""DATEQ""DATER""DATES""DATET""DATEU""DATEV""DATEW""DATEX""DATEY""DATEZ""DESIGNATIONA""DESIGNATIONB""DESIGNATIONC""DESIGNATIOND""DESIGNATIONE""DESIGNATIONF""DESIGNATIONG""DESIGNATIONH""DESIGNATIONI""DESIGNATIONJ""DESIGNATIONK""DESIGNATIONL""DESIGNATIONM""DESIGNATIONN""DESIGNATIONO""DESIGNATIONP""DESIGNATIONQ""DESIGNATIONR""DESIGNATIONS""DESIGNATIONT""DESIGNATIONU""DESIGNATIONV""DESIGNATIONW""DESIGNATIONX""DESIGNATIONY""DESIGNATIONZ""PREPA""PREPB""PREPC""PREPD""PREPE""PREPF""PREPG""PREPH""PREPI""PREPJ""PREPK""PREPL""PREPM""PREPN""PREPO""PREPP""PREPQ""PREPR""PREPS""PREPT""PREPU""PREPV""PREPW""PREPX""PREPY""PREPZ""VERIFA""VERIFB""VERIFC""VERIFD""VERIFE""VERIFF""VERIFG""VERIFH""VERIFI""VERIFJ""VERIFK""VERIFL""VERIFM""VERIFN""VERIFO""VERIFP""VERIFQ""VERIFR""VERIFS""VERIFT""VERIFU""VERIFV""VERIFW""VERIFX""VERIFY""VERIFZ""APPA""APPB""APPC""APPD""APPE""APPF""APPG""APPH""APPI""APPJ""APPK""APPL""APPM""APPN""APPO""APPP""APPQ""APPR""APPS""APPT""APPU""APPV""APPW""APPX""APPY""APPZ"))) ) (@X_SS @MX_SS #SS) devrait fonctionner ?????? :casstet: Hum Hum ....
Patrick_35 Posté(e) le 5 mars 2007 Posté(e) le 5 mars 2007 Oui sauf qu'il manque la définition de @S_AL_@R-1_@R2_@R1 et de #SS @+ ps : en te servant de l'éditeur vlisp puis ctrl+alt+f pour ton code, tu remarqueras que tuu as des espaces qui ne sont pas au bon endroit dans ta liste Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
bonuscad Posté(e) le 5 mars 2007 Posté(e) le 5 mars 2007 e temps gagné est divisé par 20 Quand j'ai commencé le lisp, une recommandation de coder les variables sur 6 caractères maxi était conseillé pour la rapidité d'éxecution. Bien que les machines soit devenues de plus en plus rapide, je pense (mais cela est à vérifier) que cela reste d'actualité. En effet (setq var_1 987.654) prendrait moins de place en mémoire que (setq ma-variable_numéro1 987.654). Personnellement sans savoir si ceci est encore d'actualité, j'essaie d'appliquer encore cette règle, pour ne pas pénaliser le temps d'exécution (peut être que de 6 caractère cela est passé à 12?) Donc ta technique de condenser tes noms de variables et/ou fonction, bien que vite illisible améliore le temps d'exécution. Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
stephan35 Posté(e) le 6 mars 2007 Auteur Posté(e) le 6 mars 2007 Pour aller plus vite ....... : J'ai un bloc avec une série d'attributs :(list "RA""RB""RC""RD""RE""RF""RG""RH" ....... etcd'ailleurs mon bug viendrait de la longueur de cette liste :casstet: Imaginons une fonction qui permette d'explorer un bloc pour en extraite le contenu d'un attribut : ;#SSN nom de l'entité d'un jeu de selection ;$T Type = "ATTRIB" ;$E Etiquette $Valeur si nil , on lit, si = "***" on écrit la valeur (defun @S_AE ( #SSN $T $E #t $valeur / &Be $Be0 R) (if (not #SSN)(progn (alert (strcat "@S_AE \nValeur nil pour #SSN"))(exit))) (if (not $T)(progn (alert (strcat "@S_AE \nValeur nil pour $R"))(exit))) (if (not $E)(progn (alert (strcat "@S_AE \nValeur nil pour $V"))(exit))) (if (not #t)(progn (alert (strcat "@S_AE \nValeur nil pour #t"))(exit))) (setq &Be (entget #SSN)) (setq $Be0 (@R0 &Be)) (while (and (/= $Be0 "SEQEND") (/= (entnext #SSN) nil)) (setq &Be (entget (setq #SSN (entnext #SSN)))) (setq $Be0 (@R0 &Be)) (if (= $Be0 $T) ;Attribut (if (= $E (@R2 &Be)) ; Si Etiquette ok (if (not $valeur) (progn (cond ((= #t 8)(setq R (@R8 &Be))) ((= #t 1)(setq R (@R1 &Be))) ((= #t 2)(setq R (@R2 &Be))) ) ) (progn (cond ((= #t 8)(setq R (@W8 &Be $valeur))) ((= #t 1)(setq R (@W1 &Be $valeur))) ((= #t 2)(setq R (@W2 &Be $valeur))) ) ) ) ) ) ) R ) Mon problème est que dans certains cas, j'ai 25 attributs dans un bloc, donc je vais le scruté 25 fois pour en extraire les valeurs !!! Donc j'ai développé une fonction qui construit une liste en une seul passe de bloc, qui pour chaque attribut regarde si celui-ci est à extraire, puis l'ajoute a la liste résultante .... :casstet: (+ Rapide) [surligneur] N'y aurait-il pas une solution qui permet rapidement d'extraire la valeur d'un attribut ou de tout autre élément d'un bloc dans devoir passer le bloc en revue ????? (sans handle et sans n° entité bien surrrr !)[/surligneur] à vos clavier .... ;) :casstet: :casstet: :casstet: :casstet: :casstet: :casstet: :casstet: Merci
Patrick_35 Posté(e) le 6 mars 2007 Posté(e) le 6 mars 2007 Comme ceci (setq bl (vlax-ename->vla-object (car (entsel)))) (foreach att (vlax-invoke bl 'getattributes) (princ (strcat "\nEtiquette : " (vla-get-tagstring att) ", Valeur : " (vla-get-textstring att))) ) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
stephan35 Posté(e) le 6 mars 2007 Auteur Posté(e) le 6 mars 2007 Ok merci, Cependant, malgré tout, tu scrutes la totalité de la séquence bloc ! :cool: , Donc perte de temps ! Si je veux juste extraire la valeur contenue dans l'étiquette "L1" je suis obligé de faire un teste pour chaque att du foreach ???? N'est-ce pas ? Et avec le SSGET, on ne peut toujours pas, non plus, accèder directement à un attribut spécifique ! [surligneur] as-tu une solution ???[/surligneur] Je vais quand même comparer les 2 versions (Lisp <> Vlisp) ! avec le test sur chaque att Merci, a+ Ps: je viens de me rendre compte que le sujet vient de changer ??? [Edité le 6/3/2007 par stephan35]
Patrick_35 Posté(e) le 6 mars 2007 Posté(e) le 6 mars 2007 Et non, je ne scrute pas tout le bloc mais uniquement les attributs que je récupère dans une liste. Si tu sais que l'étiquette L1 est le 3em Attribut, tu peux faire(setq bl (vlax-ename->vla-object (car (entsel))) at (nth 2 (vlax-invoke bl 'getattributes))) Si tu ne connais pas sa position, mais que tu veux quand même la récupérer(setq bl (vlax-ename->vla-object (car (entsel)))) (vl-remove-if-not '(lambda (x) (eq (vla-get-tagstring x) "L1")) (vlax-invoke bl 'getattributes)) @+ Les Lisps de PatrickLe but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.Joseph Joubert, 1754-1824
stephan35 Posté(e) le 6 mars 2007 Auteur Posté(e) le 6 mars 2007 WWWWWWWWAAAAAAOOOOWWWWWW Et ! Pas ceinture noire pour rien ! ;) Bon et bien, je pense que j'ai de quoi potasser !!! Je fais mes petits tests comparatifs, et je donne mes résultats !!!! Merci beaucoup et à +
stephan35 Posté(e) le 6 mars 2007 Auteur Posté(e) le 6 mars 2007 Voici une partie des résultats : [surligneur] FRAPPADINGUE ![/surligneur] Donc sur une boucle de 500 (répété 3 fois)La méthode Linéaire est de 32 SecLe méthode fonction imbriquées 38 sec :( J'ai raccourcis mes noms de fonctions et de variables Même teste:La méthode Linéaire est de 27 SecLe méthode fonction imbriquées 20 sec Conclusion proposée :Raccourcir les noms de variable à 6 char max, idem pour les fonctions ! si quelqu'un pouvais confirmer ! Je continue avec le méthode de patrick_35 .... ;)
stephan35 Posté(e) le 6 mars 2007 Auteur Posté(e) le 6 mars 2007 Voici la seconde partie des résultats : [surligneur] DINGUE !!! [/surligneur] La méthode vlax-*** est à proscrire pour des traitements répétitifs , c'est trop long ...2min 18 pour 280 / 500 , bref, j'ai coupé en cours de route ... :( Cette méthode est cependant plus simple à écrire, c'est vrai ! à revérifier ....
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant