CADxp: Lisp et VBA - CADxp

Aller au contenu

  • 3 Pages +
  • 1
  • 2
  • 3
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

Lisp et VBA

#41 L'utilisateur est hors-ligne   didier 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 7861
  • Inscrit(e) : 18-décembre 02
  • LocationPlanète : Terre

Posté 14 avril 2018 - 08:04

Coucou

Au moins tu as travaillé, c'est bien mais comme je n'ai pas vu le fichier DCL donc je n'ai pas pu tester ton travail.

En attendant le passage de (gile) qui va être bien plus précis que moi car c'est lui qui nous a appris à travailler les blocs dynamiques..
Je suis en train de traiter les fonction VL sur da-code et c'est justement de ces fonctions VL dont tu vas avoir besoin
Du style :

(and
  	(= (vla-get-ObjectName blk) "AcDbBlockReference")
  	(= (vla-get-IsDynamicBlock blk) :vlax-true)
	)
;et encore : 
vla-GetDynamicBlockProperties

Je te laisse regarder l'aide en attendant pour te familiariser avec ces nouvelles fonctions

Amicalement

Éternel débutant ...
Les bases AutoLisp
0

#42 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11036
  • Inscrit(e) : 02-septembre 05

Posté 14 avril 2018 - 08:09

Voir le messageThelduin, le 13 avril 2018 - 23:52 , dit :

J'ai pas déclaré de variable comme vous me l'avez dit, parce que j'utilise les mêmes variables avec les mêmes valeurs dans plusieurs fonctions


Si on t'a conseillé de déclarer localement les variables, ce n'est pas "par principe". En ne le faisant pas tu t'exposes à des bugs difficiles à localiser.
La probabilité que ces bugs surviennent augmente avec le nombre de variables globales. Il y en a déjà un nombre assez considérable. Si j'ai bien compris, tu penses étoffer ta routine et, vu la façon dont tu as commencé, ça veut dine encore plus de variables.

Je vais essayer, à l'aide d'un exemple très simple, d'expliquer ce qui pourrait être une meilleure pratique et ensuite, ce que je pense être une bonne pratique

La manière dont tu procèdes avec des variables globales :
(defun c:mauvaisePratique	()
  (setq a 10)
  (calculGlobal)
  (prompt (strcat "\n" (itoa B)))
  (princ)
)

(defun calculGlobal ()
  (setq b (+ a 5))
)


En localisant variables et fonctions, tu éviteras tout risque d'interaction avec l'extérieur de ta routine :
(defun c:meilleurePratique (/ calculLocal a B)

  (defun calculLocal ()
    (setq b (+ a 5))
  )

  (setq a 10)
  (calcul)
  (prompt (strcat "\n" (itoa B)))
  (princ)
)


Mais vu le nombre de variables que tu utilises, même si le problème des effets secondaires (effets de bord) est conscrit à ta routine, il existe tout de même à l'intérieur de celle-ci.
La bonne pratique est d'utiliser des fonctions auxquelles on passe un ou plusieurs arguments et qui renvoient une valeur.
(defun c:bonnePratique (/ a B)
  (setq a 10
        b (calculArg a)    ; appel de la fonction calculArg en lui passant a comme argument
  )
  (prompt (strcat "\n" (itoa B)))
  (princ)
)

(defun calculArg (x)       ; x est l'argument de la fonction calculArg
  (+ x 5)                  ; valeur retournée par la fonction
)


De plus, cette façon de faire permet souvent de réduire le nombre de variables locales, donc d'effets secondaires.
(defun c:bonnePratique ()
  (prompt (strcat "\n" (itoa (calculArg 10))))
  (princ)
)



En ce qui concerne les propriétés dynamiques des blocs, il faut utiliser les fonctions vla* pour y accéder.
Mais personnellement, je n'ai pas trop envie de t'en dire plus tant que que tu continues dans une voie qui fait fi des conseils qu'on a pu te donner.
Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
Image IPB
0

#43 L'utilisateur est hors-ligne   Thelduin 

  • ceinture orange
  • Groupe : Membres
  • Messages : 29
  • Inscrit(e) : 22-février 18

Posté 14 avril 2018 - 12:37

Salut !

Citation

je n'ai pas vu le fichier DCL donc je n'ai pas pu tester ton travail


Effectivement, je l'ai oublié. Le voilà :

trace : dialog{

label = "Données";

: edit_box {
  label = "Epaisseur de la dalle";
  key = "epdalle";
  }

: edit_box {
  label = "Niveau brut";
  key = "brut";
  }

: edit_box {
  label = "Niveau fini";
  key = "fini";
  }

: edit_box {
  label = "Epaisseur du relevé";
  key = "eprel";
  }

: edit_box {
  label = "Arase supérieure du relevé";
  key = "arase_sup";
  }
  
: edit_box {
  label = "Longueur de l'élément";
  key = "longueur";
  }

: row {
  : button {
    label = "OK";
    is_default = true;
    key = "accept";
    }

  : button {
    label = "Annuler";
    is_default = false;
    is_cancel = true;
    key = "cancel";
    }
}
}



Citation

Mais personnellement, je n'ai pas trop envie de t'en dire plus tant que que tu continues dans une voie qui fait fi des conseils qu'on a pu te donner.


Je n'en fais pas fi, c'est juste que j'avais mal compris cette histoire de variable globale et locale. En fait, savais pas où déclarer mes variables parce qu'elles passent d'une fonction à une autre, mais en restant la même chose.

Mais ce que j'ai compris de ton message, c'est que ma fonction defun c:trace_releve est ma fonction principale, et que, parmi les variables, il y aura les fonctions que je vais définir dans ma fonction principale avec un defun, c'est bien ça ?

Je vais donc avoir :

(defun c:trace_releve(/ toutes_mes_variables recup initia reinitia kw_oui rel_haut rel_bas calcul_h calcul_B)

Et derrière, je vais définir mes fonctions dans mon defun c:trace_releve
C'est bien ça ? :D
0

#44 L'utilisateur est hors-ligne   didier 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 7861
  • Inscrit(e) : 18-décembre 02
  • LocationPlanète : Terre

Posté 14 avril 2018 - 13:40

Coucou

Merci pour le DCL, si je trouve un peu de temps je regarde

Il me semblait t'avoir dirigé vers ma page d'explications sur les variables, non ?

Edit : je viens de vérifier, dans le message #22 tu as bien un lien sur la fonction SETQ
et en fin de sa page je parle des variables,
va voir et dis-moi si quelque chose manque aux explications

Amicalement

Éternel débutant ...
Les bases AutoLisp
0

#45 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11036
  • Inscrit(e) : 02-septembre 05

Posté 14 avril 2018 - 14:03

Voir le messageThelduin, le 14 avril 2018 - 12:37 , dit :

Je n'en fais pas fi, c'est juste que j'avais mal compris cette histoire de variable globale et locale. En fait, savais pas où déclarer mes variables parce qu'elles passent d'une fonction à une autre, mais en restant la même chose.

Mais ce que j'ai compris de ton message, c'est que ma fonction defun c:trace_releve est ma fonction principale, et que, parmi les variables, il y aura les fonctions que je vais définir dans ma fonction principale avec un defun, c'est bien ça ?

Je vais donc avoir :

(defun c:trace_releve(/ toutes_mes_variables recup initia reinitia kw_oui rel_haut rel_bas calcul_h calcul_B)

Et derrière, je vais définir mes fonctions dans mon defun c:trace_releve
C'est bien ça ? :D


Déclarer localement variables et fonctions serait un moindre mal.
Mais, à mon avis, prendre l'habitude de définir des fonctions qui prennent un ou plusieurs argument et d'utiliser la valeur renvoyée par ces fonctions (comme on le fait avec les fonctions prédéfinies) est essentiel.

Je te rappelle ce sujet dont je te recommande grandement la lecture.
Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
Image IPB
0

#46 L'utilisateur est hors-ligne   Thelduin 

  • ceinture orange
  • Groupe : Membres
  • Messages : 29
  • Inscrit(e) : 22-février 18

Posté 07 mai 2018 - 13:32

Salut !
Bon, je fais face à un problème, je ne sais pas comment déclarer toutes mes variables, sachant qu'elles passent d'une fonction à une autre. Et je ne sais pas quelles variables je peux passer en argument dans mes fonctions
Ça va faire deux semaines que j'essaye de faire bien, comme me l'a fortement conseillé (gile) et là j'avoue que je sèche complètement ...
Je pense que j'ai trop avancé dans mon code, j'aurai du le faire dès le début (mais je ne le savais pas) et du coup, il est pas du tout pensé pour des fonctions à arguments
0

#47 L'utilisateur est hors-ligne   Thelduin 

  • ceinture orange
  • Groupe : Membres
  • Messages : 29
  • Inscrit(e) : 22-février 18

Posté 14 mai 2018 - 20:20

Bonjour ! (ou bonsoir ^^)
J'ai eu une petite baisse de motivation, mais je viens de m'y remettre et j'ai une question !
J'ai cru comprendre, en testant, que l'ordre dans lequel sont définies les fonctions ont une importance, par exemple si j'écris ça :
(defun c:sub(/ calcul a B)

(setq a (getreal "\nValeur de a ?"))
(calcul)
(prompt (strcat "/n" itoa B))
(princ)

(defun calcul()
(setq b (+ a 10))
)

J'ai un message d'erreur me disant que la fonction calcul n'existe pas, alors que si j'écris mon code comme ceci :
(defun c:sub(/ calcul a B)

(defun calcul()
(setq b (+ a 10))
)

(setq a (getreal "\nValeur de a ?"))
(calcul)
(prompt (strcat "/n" itoa B))
(princ)

à ce moment-là, ça fonctionne. Est-ce normal ? Et du coup, est-ce que cet ordre d'écriture est à respecter avec des sous-routines avec argument ?
0

#48 L'utilisateur est hors-ligne   Fraid 

  • ceinture noire 3em dan
  • Groupe : Membres
  • Messages : 1816
  • Inscrit(e) : 08-août 05
  • LocationST Malo 35

Posté 14 mai 2018 - 20:41

Bonjour

Ta fonction calcul n'a pas besoin d’être dans ton programme principal.

Une simple parenthèse fermante après le (princ) de ton 1er exemple suffit a régler le problème.(pour clore ton defun c)

a oui, il y a aussi a à passer en argument dans calcul.

(defun c:sub(/ a )

(setq a (getreal "\nValeur de a ?"))

(prompt (strcat "\n" itoa (calcul a)))
(princ)
)
(defun calcul(a)
(+ a 10)
)


...plus je sais où je suis, moin je sais où je vais.... Extrait d''une double interview simultanée d'une particule élémentaire.
0

#49 L'utilisateur est hors-ligne   Thelduin 

  • ceinture orange
  • Groupe : Membres
  • Messages : 29
  • Inscrit(e) : 22-février 18

Posté 14 mai 2018 - 20:57

Ah mais dans ce cas, je ne déclare pas calcul dans mon defun c:sub()
0

#50 L'utilisateur est hors-ligne   Fraid 

  • ceinture noire 3em dan
  • Groupe : Membres
  • Messages : 1816
  • Inscrit(e) : 08-août 05
  • LocationST Malo 35

Posté 14 mai 2018 - 21:29

je ne pense pas.

L'un des interet des fonctions, est qu'elles peuvent être utilisées par d'autre lisp, suffit qu'elles soient chargées une fois.
Un autre est de clarifier le programme principal afin de nous maintenir plus aisément dans notre algorithme.
...plus je sais où je suis, moin je sais où je vais.... Extrait d''une double interview simultanée d'une particule élémentaire.
0

#51 L'utilisateur est hors-ligne   (gile) 

  • ceinture rouge et blanche 8em dan
  • Groupe : Moderateurs
  • Messages : 11036
  • Inscrit(e) : 02-septembre 05

Posté 15 mai 2018 - 06:24

Salut

Les fonctions (comme les variables) peuvent être locales ou globales.

Les fonctions globales, une fois chargées, sont accessibles par toute autre expression LISP. Comme le dit Fraid, ça peut être intéressant pour des fonctions très utiles (et souvent utilisées). Le risque avec ce type de fonction est le conflit de nom (c'est la dernière fonction de même nom chargée dans le dessin qui est active.

Déclarer localement les fonctions permet d'éviter ce problème. Dans ce cas la fonction locale doit être définie avant son utilisation dans la fonction parent (exactement comme une variable locale).
Gilles Chanteau - gileCAD -
Développements sur mesure pour AutoCAD
Image IPB
0

#52 L'utilisateur est hors-ligne   Thelduin 

  • ceinture orange
  • Groupe : Membres
  • Messages : 29
  • Inscrit(e) : 22-février 18

Posté 21 mai 2018 - 00:20

Salut !

Je me suis penché sur le changement des valeurs des paramètres dynamiques d'un bloc dynamique via le lisp (en fouillant le site à la recherche d'info sur les fonctions vla et vlax).
Sur un bloc dynamique, j'arrive à changer la valeur du premier paramètre, mais dès que j'ai plusieurs paramètres (en général, j'en ai 6 ou 7), je suis incapable de changer ces autres valeurs, j'ai une erreur : AutoCAD.Application : entree incorrecte ...

Je vous mets un extrait du code :

(defun c:test()
(setq acob (getvar "osmode"))
(setvar "osmode" 0)
(command "-inserer" "Cadre + façonnage 25e" "e" 0.1 0 0)

  
(vl-load-com)
(setq cadre (vlax-ename->vla-object (entlast)))
(setq pr (vlax-invoke cadre 'getdynamicblockproperties))

(setq h_cadre (nth 0 pr))
(setq enr_g (nth 1 pr))
(setq enr_d (nth 2 pr))
(setq enr_h (nth 3 pr))
(setq enr_b (nth 4 pr))
(setq l_cadre (nth 5 pr))

(vlax-put h_cadre 'value 40.0)
(vlax-put enr_g 'value 4.0)
(vlax-put enr_d 'value 3.0)
(vlax-put enr_h 'value 5.0)
(vlax-put enr_b 'value 2.0)
(vlax-put l_cadre 'value 16.0)

(command "regntout")
(setvar "osmode" acob)
)

Mon cadre a bien une hauteur de 40, par contre, tous les autres paramètres ne bougent pas...Pourquoi ? :unsure:

Merci d'avance
0

Partager ce sujet :


  • 3 Pages +
  • 1
  • 2
  • 3
  • Vous ne pouvez pas commencer un sujet
  • Vous ne pouvez pas répondre à ce sujet

1 utilisateur(s) en train de lire ce sujet
0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)