Aller au contenu

ANNULATION D\'UNE FONCTION LISP


Messages recommandés

Posté(e)

Ma petite question du jour :

 

Quand on fait un lisp qui lancent des commandes autocad (par exemple transférer des objets sur un nouveau calque du même nom que leur ancien calque mais avec un indice en plus), il est laborieux d'annuler... car il faut annuler moult "(expression lisp)".

 

Existe-t'il un moyen pour que l'annulation se fasse en un seul clic sur "annuler" ?

Autocad 2021 - Revit 2022 - Windows 10

Posté(e)

Il te faut placer AVANT un appel à (command ".......)

(command "_.UNDO" "_Begin")

et APRES le dernier appel à (command "....")

(command "_.UNDO" "_End")

 

Si tu veut être sûr (en étant perfectionniste) que tout se déroule bien, il te faut surveiller la variable 'UNDOCTL" (lecture seule), et suivant sa valeur, utiliser la commande "_.UNDO" "_Control" "......

Au cas où l'utilsateut aurait par fixer par exemple la commande Annuler à 1 seule opération., ou même aucune. (situation peu probable)

 

En faisant comme ceci le résultat de ta routine pourra être annuler en une seule opération, même si plusieur appel à (command) ont été fait.

 

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

Posté(e)

Bruno,

Je suggère ceci:

 

(defun foo (

)

(command "._undo" "_auto" "_off")

(command "._undo" "_begin") ; Note: Begin remplace Group depuis R13.

 

;; le programme ici

 

(command "._undo" "_end")

(command "._undo" "_auto" "_on")

)

 

Et ne pas oublier la fonction *error* qui contiendra aussi les 2 dernières lignes

 

Ludwig,

 

Parles-tu vraiment de faire plusieurs interventions pour tout arrêter ou bien de revenir en arrière en une seule étape (un seul _U) ?

 

Serge

 

Posté(e)

Serge,

 

J'utilise plutôt ce genre de procédure:

 

(if (<= (setq sv_und (getvar "undoctl")) 3)

(command "_.undo" "_control" "_all")

)

(command "_.undo" "_begin") ou _group qui fonctionne aussi

.....

......

(command "_.undo" "_end")

(if (<= sv_und 3) (command "_.undo" "_control" "_one"))

 

En effet si undoctl< 3 , _undo _auto _off sera refusé

Ce cas est extrème je le reconnais, mais est possible

En règle générale je pense qu'on peut se contenter de _begin et _end car peu d'utilisateur vont modifier le comportement de l'annulation.

 

Mais il m'es quand mêm arrivé d'utiliser, sur de très très gros fichier, Annuler sur aucun pour des traitements par lisp pour éviter d'avoir les fichiers temporaires $UNDO.AC$ (de mémoire) qui me fasse exploser l'espace disque. (bien sûr c'était au temps où l'espace disque et mémoire était beaucoup plus précieux)

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

Posté(e)

Bruno,

 

Le mieux est donc ceci

 

(defun beginUndo ()

;; le code aussi complexe dont on peut rêver

)

 

(defun closeUndo ()

;; Même chose

)

 

(defun *error* (msg)

(closeUndo)

)

 

(defun c:le_programme ()

(beginUndo)

(du_code)

(closeUndo)

(princ)

)

 

Posté(e)

bon je viens de me réintéressé à Begin/undo. J'ai eu du mal mais j'ai compris maintenant comment ça marche (je mettais begin juste après mon defun, undo à la fin, alors qu'il faut les mettre avant et après les " command" qu'on veut grouper)

 

Par contre, qq peut me dire comment fonctionne le (defun *error* (msg)) ?

 

Autocad 2021 - Revit 2022 - Windows 10

Posté(e)

Exemple de montage:

(defun mon_err (ch)

(cond

((eq ch "Function cancelled") nil)

((eq ch "quit / exit abort") nil)

((eq ch "console break") nil)

(T (princ ch))

)

(command "_.undo" "_end")

(command "_.u")

(if (<= sv_undo 3) (command "_.undo" "_control" "_one"))

(setvar "OSMODE" sv_var1)

(setvar "ATTDIA" sv_var2)

(setq *error* olderr)

(princ)

)

 

(defun C:MA-Fonction ( / olderr sv_undo sv_var1 sv_var2)

(setq olderr *error* *error* mon_err)on redéfini la fonction erreur standard avec la fonction mon_err

(if (<= (setq sv_undo (getvar "undoctl")) 3)

(command "_.undo" "_control" "_all")

)

(command "_.undo" "_group")

(setq sv_var1 (getvar "OSMODE") sv_var2 (getvar "ATTDIA")) On sauve l'état des variables initial

;.....

;Corps de la routine avec par exemple plusieurs appels à (command) et modification des variables OSMODE et ATTDIA

;.....

(setvar "OSMODE" sv_var1)on restore l'état des variables

(setvar "ATTDIA" sv_var2)

(command "_.undo" "_end")

(if (<= sv_undo 3) (command "_.undo" "_control" "_one"))

(setq *error* olderr)on remet la fonction *error* standard

(princ)

)

 

Si pendant l'execution du corps de la routine l'utilisateur annule la routine par Echap [ESC]

la fonction (mon_err) sera executé avant de retourné a la ligne de commande.

De ce fait l'état initial sera restoré, ca ne serait pas le cas si la fonction mon_err n'etait pas définie.

OSMODE ATTDIA et le mode de fonctionnement de UNDO seraient modifiés et pourrait pertuber un utilisateur non-averti et énerver un utilisateur plus averti.

 

Cet une démarche qu'on doit adopter si l'on diffuse ses applications

Faite ce que je dis, ne faites pas ce que je fais ;)

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

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é