Aller au contenu

Variables système / *error*


(gile)

Messages recommandés

Il est souvent nécessaire dans un LISP, de changer la valeur de certaines variables système.

 

La méthode habituelle est de sauvegarder la valeur initiale de la variable système dans une variable globale pour pouvoir lui restituer sa valeur initiale à la fin de l'exécution de la routine (ou lors d'une interruption pendant le déroulement du LISP -fonction *error*).

 

Je propose deux petites routines qui simplifient la manoeuvre, ces routines sont déjà apparues dans CADxp assosciées à certains LISP que j'ai publiés, elles sont ici dans une version plus aboutie :

 

SAVE&SET_VAR permet de changer la valeur d'une variable système (comme SETVAR), mais enregistre la valeur initiale de cette variable dans une liste de paires pointées (SavedSysVarLst), si ce n'est déjà fait (seul le premier appel à SAVE&SET_VAR pour une variable donnée est enregistré).

 

RESTORE_VAR restitue leurs valeurs initiales aux variables contenues dans SavedSysVarLst et vide cette liste.

 

;;; SAVE&SET_VAR & RESTORE_VAR
;;;
;;; SAVE&SET_VAR
;;; Enregistre la valeur initiale de la variable système dans une liste
;;; de paires pointées et lui attribue sa nouvelle valeur (si val est non nil)
;;;
;;; ex: (SAVE&SET_VAR "autosnap" nil) (SAVE&SET_VAR "orthomode" 1)
;;; -> SavedSysVarLst : (("orthomode" . 0) ("autosnap" . 63))
;;; -> (getvar "orthomode") : 1
;;; -> (getvar "autosnap") : 55 (63 - 8 : le repérage polaire est désactivé)

(defun SAVE&SET_VAR (var val)
 (cond
   ((not (getvar var))
    (princ (strcat "\nErreur: variable AutoCAD rejetée: " var))
    (princ)
   )
   (T
    (if (not
   (member (assoc var SavedSysVarLst) SavedSysVarLst)
 )
      (setq SavedSysVarLst
      (cons (cons var (getvar var))
	    SavedSysVarLst
      )
      )
    )
    (if val
      (setvar var val)
    )
   )
 )
)

;;; RESTORE_VAR
;;; Restaure leurs valeurs initiales aux variables système de "SavedSysVarLst"
;;;
;;; ex: (RESTORE_VAR)
;;; -> (getvar "orthomode") : 0
;;; -> (getvar "autosnap") : 63
;;; -> SavedSysVarLst : nil

(defun RESTORE_VAR ()
 (foreach pair	SavedSysVarLst
   (if	(/= (getvar (car pair)) (cdr pair))
     (setvar (car pair) (cdr pair))
   )
 )
 (setq SavedSysVarLst nil)
) 

 

Ces routines permettent en outre d'utiliser une redéfinition de la fonction *error* standard qui peut servir quelque soient les variables modifiées par le LISP.

 

 

;;; Redéfinition de *error*

(defun STD_ERR	(msg)
 (if (or
(= msg "Fonction annulée")
(= msg "quitter / sortir abandon")
     )
   (princ)
   (princ (strcat "\nErreur: " msg))
 )
 (command)
 (command "_undo" "_end")
 (RESTORE_VAR)
 (setq	*error*	m:err
m:err nil
 )
 (princ)
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

J'ai un cadeau pour toi :)

 

Voici le code compilé parmi les différents utilisateurs du site CADXp.

ces fonctions permettent dans un premier temps de sauvegarder dans une liste (PUBLIC_ERROR)

 

(defun BeginUndo (/ VAR_UNDO VAR_CMDECHO STANDARD_ERROR)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Fonction à mettre en entête de chaque fonction appelée par         ;;;
;;;  l'utilisateur (souvent defun c:... () ...) dite parente           ;;;
;;;                                                                    ;;;
;;;  cette fonction vient de la brillante intervention de Serge        ;;;
;;;  et la pugnacité de LUDWIG pour commprendre le BeginUndo           ;;;
;;;  sur CADXP [url=http://www.cadxp.com/]CADxp[/url]                  ;;;
;;;                                                                    ;;;
;;; Retourne : une liste de variable à redéfinir après l'éxécution.    ;;;
;;;                  de la fonction parente                            ;;;
;;;                                                                    ;;;
;;;  Le "#" en entête prévient que ce sont des variables               ;;;
;;;   en lecture seule. Il faut donc utiliser un artifice pour les     ;;;
;;;   restaurer: on définit par un " " pour séparer les commandes des  ;;;
;;;   choix, pour ceux qui ont un * au début : variable LISP (setq ...);;;
;;;   on peut utiliser un (setvar ....) pour les autres                ;;;
;;;                                                                    ;;;
;;;  Remarque : CMDECHO doit rester à la fin pour ne pas gêner         ;;;
;;;              visuellemnt la ligne de commande.                     ;;;
;;;                                                                    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Définition de la fonction Erreur Standard avec la fonction du BE_Error
 (setq	STANDARD_ERROR *ERROR*
*ERROR*	       Maximilien_ERROR
 )
 (setq VAR_CMDECHO (getvar "CMDECHO"))
 (setvar "CMDECHO" 0)
;;; Détermine le Niveau de la Fonction ANNULER
 (if (<= (setq VAR_UNDO (getvar "UNDOCTL")) 3)
   (command "_.UNDO" "_CONTROL" "3")
   (command "_.UNDO" "_BEGIN")
 )
;;; ACAD.LSP DOIT ÊTRE CHARGER A CHAQUE DESSIN
 (setvar "ACADLSPASDOC" 1)
;;; Definition des limites sur tout le dessin
 (if (= (getvar "TILEMODE") 1)
   (progn
     (setvar "LIMMIN"
      (list (car (getvar "EXTMIN")) (cadr (getvar "EXTMIN")))
     )
     (setvar "LIMMAX"
      (list (car (getvar "EXTMAX")) (cadr (getvar "EXTMAX")))
     )
   )
 )

;;; Sauvegarde LES VARIABLES SYSTEMES
 (list
   (cons "#_-DIMSTYLE _restore" (getvar "DIMSTYLE"))
   (cons "AFLAGS" (getvar "AFLAGS"))
   (cons "ATTDIA" (getvar "ATTDIA"))
   (cons "BLIPMODE" (getvar "BLIPMODE"))
   (cons "CECOLOR" (getvar "CECOLOR"))
   (cons "CELTYPE" (getvar "CELTYPE"))
   (cons "CELTSCALE" (getvar "CELTSCALE"))
   (cons "CLAYER" (getvar "CLAYER"))
   (cons "FILEDIA" (getvar "FILEDIA"))
   (cons "ORTHOMODE" (getvar "ORTHOMODE"))
   (cons "OSMODE" (getvar "OSMODE"))
   (cons "PICKSTYLE" (getvar "PICKSTYLE"))
   (cons "TEXTSTYLE" (getvar "TEXTSTYLE"))
   (cons "*_*ERROR*" STANDARD_ERROR)
   (cons (if (<= VAR_UNDO 3)
    "#_.UNDO _CONTROL"
    "#_.UNDO"
  )
  (if (<= VAR_UNDO 3)
    "_ONE"
    "_END"
  )
   )
   (cons "CMDECHO" VAR_CMDECHO)
 )

)
;;; ----------------------------------------------------------------------

;;; ----------------------------------------------------------------------
(defun CloseUndo (ARG_VARIABLE / POINTEUR COMM1 COMM2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Fonction à mettre à la fin de chaque fonction appelée par          ;;;
;;;  l'utilisateur (souvent defun c:... () ...) dite parente           ;;;
;;;                                                                    ;;;
;;;  cette fonction vient de la brillante intervention de Serge        ;;;
;;;  sur CADXP [url=http://www.cadxp.com/]CADxp[/url]                  ;;;
;;;                                                                    ;;;
;;; Argument : La liste créée par la fonction BeginUndo                ;;;
;;;                                                                    ;;;
;;; Retourne : nil                                                     ;;;
;;;                                                                    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Parcours de la liste
;;;
 (setvar "CMDECHO" 0)
 (foreach POINTEUR ARG_VARIABLE
   (progn
     ;; COMM1 est la commande ou variable définie
     (setq COMM1 (vl-string-left-trim
	    "#"
	    (substr (car POINTEUR)
		    1
		    (vl-string-position
		      (ascii " ")
		      (car POINTEUR)
		    )
	    )
	  )
     )
     ;; COMM2 est le choix éventuel pour restaurer les variables en lecture seule
     (setq COMM2 (vl-string-left-trim
	    " "
	    (vl-string-left-trim
	      (strcat "#" COMM1)
	      (car POINTEUR)
	    )
	  )
     )
     (if (/= COMM2 "")
;; cas des variables en lecture seule
(command COMM1 COMM2 (cdr POINTEUR))
(if (= (chr (vl-string-elt (car POINTEUR) 0)) "#")
  ;; pour les commande ou variables où un choix est inutile
  (command COMM1 (cdr POINTEUR))
  ;; pour les variables où un setvar est judicieux (pas de CR+LF)
  (if (/= (chr (vl-string-elt (car POINTEUR) 0)) "*")
    (setvar COMM1 (cdr POINTEUR))
  )
)
     )
     ;; cas des variables ou un (SETQ ...) est indispensable
     (if (= (chr (vl-string-elt (car POINTEUR) 0)) "*")
(cond
  ((= (car POINTEUR) "*_*ERROR*")
   (setq *ERROR* (cdr POINTEUR))
  )
  ;; Vous avez oubliez de la définir.....
  (t (alert "Variable non défini dans le CloseUndo"))
)
     )
   )
 )
 (princ)
)
;;; ----------------------------------------------------------------------

;;; ----------------------------------------------------------------------
(defun Maximilien_ERROR	(VAR_STR)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Fonction de gestion d'erreur                                       ;;;
;;;  cette fonction vient de la brillante intervention de bonucad      ;;;
;;;  sur CADXP [url=http://www.cadxp.com/]CADxp[/url]                  ;;;
;;;                                                                    ;;;
;;; Argument : La valeur d'erreur retournée par AutoCAD                ;;;
;;;                                                                    ;;;
;;; Retourne : nil                                                     ;;;
;;;                                                                    ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (cond
   ((eq VAR-STR "Function cancelled") nil)
   ((eq VAR-STR "quit / exit abort") nil)
   ((eq VAR-STR "console break") nil)
   ((eq VAR-STR "no function definition") nil)
   (T (Princ VAR_STR))
 )
 (CloseUndo PUBLIC_ERROR)
 (princ)
)
;;; ----------------------------------------------------------------------

 

dans tes routines :)

 

(defun c:ROUTINE  ()
 (setq PUBLIC_ERROR (BeginUndo))
.....
 (CloseUndo PUBLIC_ERROR))

Dessinateur AutoCAD, Modeleur BIM, consultant informatique logiciels métier

Lenovo ThinkStation P330 i9 9900K 32Gb RAM 512 SSD + 1To

GstarCAD, Fisa-CAD, Revit, FisaBIM CVC, Microsoft Office

 

PlaquetteDeplianteMars2024.pdf

Lien vers le commentaire
Partager sur d’autres sites

Quel émulation ?

 

Si seulement j'avais le temps de lire ! ...je blague mais si on pouvait tout essayer et se concentrer sur tout

 

Y a des empêcheur d'erreurs puissants en Vlisp

Au boulot les gars, j'attends !

Ca m'évitera de bricoler :cool:

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

:D C'est çà Tramber, fout toi de ma gueule!! :D

 

Je l'utilise en permanence ces routines :D

 

T'es en forme ce week end!! :D

Dessinateur AutoCAD, Modeleur BIM, consultant informatique logiciels métier

Lenovo ThinkStation P330 i9 9900K 32Gb RAM 512 SSD + 1To

GstarCAD, Fisa-CAD, Revit, FisaBIM CVC, Microsoft Office

 

PlaquetteDeplianteMars2024.pdf

Lien vers le commentaire
Partager sur d’autres sites

J'ai regardé d'un peu plus près et fais quelques tests avec le code de Maximilien.

 

Tout d'abord, BRAVO !

 

D'un point de vue général :

 

- j'aime beaucoup la manière de gérer à partir d'une liste unique les (setvar ...), (setq ...) et (command ...).

 

- j'aime moins le fait que la liste des variables soit définie "à priori", cela suppose une liste fort longue (celle proposée, ne contient pas toutes les variables suceptibles d'être modidfiées dans tous les LISP que j'utilise) et manque donc, à mon goût, de souplesse.

 

En ce qui concerne la gestion du groupe UNDO, je me permettrais deux petites remarques :

 

- l'option "3" dans (command "_.UNDO" "_CONTROL" "3") me semble curieuse et n'est pas acceptée chez moi, il me semble que les options pour (command "_.UNDO" "_CONTROL" ...) sont : "_ALL", "_NONE" et "_ONE", je remplacerais donc "3" par "_ALL".

 

- mettre CMDECHO à 0 avant de constituer le groupe UNDO fait que ce changement de variable n'est pas inclus dans le goupe UNDO (cmdecho reste à 0 dans le cas d'une seule annulation après execution du LISP).

Par rapport à la dernière remarque, il serait possible de metrre CMDECHO à 0 après avoir fait le (command "_.undo" _begin") auquel cas un echo sera renvoyé sur la ligne de commande pour ce (command "_.undo" _begin").

Il existe, depuis v2004 (je crois), une routine dans le fichier ai_utils.lsp qui permet de palier à ce problème :

 

;;; Set CMDECHO without undo recording (ai_utils.lsp)
;;;
;;; This is useful for LISP defined commands that use UNDO grouping
;;; so that a single undo group is recorded in the undo/redo history
;;; Otherwise, the setting of the CMDECHO value may result in an
;;; additional "Group of Commands" entry in the undo/redo history.
;;;
(defun ai_setCmdEcho (newVal / _oldEnvVal)
 ;; Only do it if the value is different than the current value
 (if (/= newVal (getvar "CMDECHO"))
   (progn
     (setq _oldEnvVal (getenv "acedChangeCmdEchoWithoutUndo"))
     ;; If not set yet, use 0 for default
     (if (not _oldEnvVal)
(setq _oldEnvVal "0")
     )
     (setenv "acedChangeCmdEchoWithoutUndo" "1")
     (setvar "cmdecho" newVal)
     (setenv "acedChangeCmdEchoWithoutUndo" _oldEnvVal)
   )
 )
)

 

Attention le fichier ai_utils.lsp n'est pas chargé automatiquement par AutoCAD, il faut donc copier la routine dans un fichier .lsp (ou .mnl) chargé pour chaque dessin.

 

De mon côté, je préfère avoir plusieurs routines que j'utilise ou pas suivant les besoins de chaque LISP. J'essaye de les faire le plus possible polyvalentes et compatibles entre elles. Elles sont regoupées dans un fichier Gile_utils.lsp dont le chargement est automatiquement commandé depuis les fichiers .MNL de mes menus personnalisés.

 

Par exemple, j'utilise ai_setCmdEcho notamment dans deux routines qui ouvrent et ferment un groupe UNDO :

 

;;; GILE_UNDO_BEGIN et GILE_UNDO_END d'après ai_undo_push et ai_undo_pop (acad.mnl)
;;; Utilisation de ai_setCmdEcho (défini dans ai_utils.lsp)

(defun GILE_UNDO_BEGIN (/ old_echo)
 (setq	old_echo  (getvar "cmdecho")
undo_init (getvar "undoctl")
 )
 (ai_setCmdEcho 0)
 (cond
   ((and (= 1 (logand undo_init 1))
  (/= 2 (logand undo_init 2))
  (/= 8 (logand undo_init 8))
    )
    (command "_.undo" "_begin")
   )
   (T)
 )
 (if (= 4 (logand undo_init 4))
   (command "_.undo" "_auto" "_off")
 )
 (ai_setCmdEcho old_echo)
)

(defun GILE_UNDO_END (/ old_echo)
 (setq old_echo (getvar "cmdecho"))
 (ai_setCmdEcho 0)
 (cond
   ((and (= 1 (logand undo_init 1))
  (/= 2 (logand undo_init 2))
  (/= 8 (logand undo_init 8))
    )
    (command "_.undo" "_end")
   )
   (T)
 )
 (if (= 4 (logand undo_init 4))
   (command "_.undo" "_auto" "_on")
 )
 (ai_setCmdEcho old_echo)
)

 

Ainsi qu'une routine GILE_RESTORE à placer à la fin de la "fonction mère". cette routine polyvalente fonctionne qu'un groupe UNDO est été constitué ou non, que *error* ait été redéfinie ou non, que des variables systéme aient été modifiées ou non avec SAVE&SET_VAR ou que seul CMDECHO ait été modifié avec ai_setCmdEcho :

 

;;; GILE_RESTORE Fonction polyvalente de restauration de l'environnement initial

(defun GILE_RESTORE ()
 (if undo_init
   (GILE_UNDO_END)
 )
 (if SavedSysVarLst
   (RESTORE_VAR)
 )
 (if old_echo
   (ai_setCmdEcho old_echo)
 )
 (if m:err
   (setq *error* m:err
  m:err	nil
   )
 )
)

 

Cette dernière routine peut être appelée à la fin de la redéfinition de *error* :

 

;;; GILE_ERR Redéfinition de *error*
;;; Ferme le groupe "undo", s'il existe, et restaure la valeur initiale des variables.

(defun GILE_ERR	(msg)
 (if (or
(= msg "Fonction annulée")
(= msg "quitter / sortir abandon")
     )
   (princ)
   (princ (strcat "\nErreur: " msg))
 )
 (command)
 (GILE_RESTORE)
)

 

Il me reste maintenant à essayer de m'inspirer de la routine de Maximilien pour améliorer SAVE&SET_VAR et RESTORE_VAR afin qu'elles fonctionnent aussi avec (command ...) et (setq ...)

 

(à suivre ...)

 

 

 

 

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Bonjour à vous tous

Juste une remarque. Moins on se sert des commands et plus on tend vers des fonctions vlisp, moins on se sert de la redéfinition de variables

 

Exemple avec les undo

(vla-startundomark (vla-get-activedocument (vlax-get-acad-object)))

et

(vla-endundomark (vla-get-activedocument (vlax-get-acad-object)))

 

@+

Les Lisps de Patrick

Le but n'est pas toujours placé pour être atteint, mais pour servir de point de mire.

Joseph Joubert, 1754-1824

Lien vers le commentaire
Partager sur d’autres sites

Ou encore les fonctions :

 

( vl-catch-all-apply `function list)

( vl-catch-all-error-message error-obj)

( vl-catch-all-error-p arg)

 

Mais j'attends toujours que les autres bossent pour moi ! :cool:

 

J'ai déjà essayé d'enfermer des fonctions dans vl-catch-all-apply et c'est au poil, même si je ne maitrise pas tout de la position idéale de la fonction.

Bureau d'études dessin.

Spécialiste Escaliers

Développement - Formation

 

./__\.
(.°=°.)
Lien vers le commentaire
Partager sur d’autres sites

Quand j'ai démarré ce sujet, je pensais aider, à mon niveau, les plus débutants que moi, avec des astuces abordables par le plus grand nombre, mais, émulation aidant, la barre est rapidement montée bien haut !

 

Moins on se sert des commands et plus on tend vers des fonctions vlisp, moins on se sert de la redéfinition de variables

 

Certes, mais la crétion de certains objets graphiques reste plus simple, plus accessible, avec command qu'avec vla-add... ou entmake.

 

Par exemple, pour faire une LWpolyligne dans le SCU courant à partir d'une liste de points définis dans le SCU, il n'y a pas photo !

 

avec command :

 

(setvar "osmode" (+ (getvar "osmode") 16384))
 (command "_pline")
 (mapcar 'command pts)
 (command "")
 (setvar "osmode" (- (getvar "osmode") 16384)) 

 

avec entmake :

 

(setq ucszdir (trans '(0 0 1) 1 0 T))
 (entmake
   (append
     (list '(0 . "LWPOLYLINE")
    '(100 . "AcDbEntity")
    '(100 . "AcDbPolyline")
    '(70 . 0)
    (cons 90 (length pts))
    (cons 38 (- (caddr (car pts)) (caddr (trans '(0 0) 0 1))))
    (cons 210 ucszdir)
     )
     (mapcar '(lambda (pt) (cons 10 (trans pt 1 ucszdir))) pts)
   )
 )

 

avec vla-addLightweightPolyline

 

(setq	AcDoc (vla-get-activedocument (vlax-get-acad-object))
ModSp (vla-get-ModelSpace AcDoc)
Norm  (trans '(0 0 1) 1 0 T)
lst   (apply 'append
	     (mapcar
	       '(lambda	(x)
		  (setq x (trans x 1 Norm))
		  (list (car x) (cadr x))
		)
	       pts
	     )
      )
 )
 (setq	pline (vla-addLightweightPolyline
	ModSp
	(vlax-make-variant
	  (vlax-SafeArray-fill
	    (vlax-make-SafeArray
	      vlax-vbDouble
	      (cons 0
		    (- (length lst) 1)
	      )
	    )
	    lst
	  )
	)
      )
 )
 (vla-put-Elevation
   pline
   (- (caddr (car pts)) (caddr (trans '(0 0) 0 1)))
 ) 

 

Ceci dit l'exemple est choisi avec un peu de mauvaise foi ;) ,je ne cesse de découvrir la puissance et les côtés pratiques du VisualLISP en essayant de "visualiser" mes routines.

 

J'ai déjà essayé d'enfermer des fonctions dans vl-catch-all-apply et c'est au poil

 

J'ai un peu essayé aussi, il me semble même que parfois un :

 

(if (not (vl-catch-all-error-p (vl-catch-all-apply ...

 

soit le seul moyen d'obtenir un nil à la place d'une erreur et que la fonction puisse continuer.

 

Merci encore à vous tous pour l'intérêt que vous portez à mes "bidouilles"

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 3 semaines après...

En m'inspirant largement de Elpanov Evgeniy, une nouvelle version de SAVE&SET_VAR (à utiliser à la place de setvar si on veut conserver la valeur initiale de la variable pour la restaurer en fin de LISP ou en cas d'erreur)

 

;;; SAVE&SET_VAR
;;; Enregistre la valeur initiale de la variable système dans une liste
;;; et lui attribue sa nouvelle valeur (si val est non nil)
;;;
;;; ex: (SAVE&SET_VAR "autosnap" nil) (SAVE&SET_VAR "orthomode" 1)
;;; -> SavedSysVarLst : ((setvar "orthomode"  0) (setvar "autosnap"  63))
;;; -> (getvar "orthomode") : 1
;;; -> (getvar "autosnap") : 55 (63 - 8 : le repérage polaire est désactivé)

(defun save&set_var (var val)
 (setq	SavedSysVarLst
 (cons (list 'setvar var (getvar var)) SavedSysVarLst)
 )
(if val
 (setvar var val)
)
) 

 

Et RESTORE_VAR à utiliser enfin de LISP et dans redéfinition de *error*

 

;;; RESTORE_VAR
;;; Restaure leurs valeurs initiales aux variables système de "SavedSysVarLst"
;;;
;;; ex: (RESTORE_VAR)
;;; -> (getvar "orthomode") : 0
;;; -> (getvar "autosnap") : 63
;;; -> SavedSysVarLst : nil 

(defun restore_var ()
 (mapcar 'eval SavedSysVarLst)
 (setq SavedSysVarLst nil)
)

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

  • 5 ans après...

Bonsoir,

 

Au départ un petit peu dans le même esprit que (gile) en voulant aider des plus débutants que moi, je publie ma routine de sauvegarde et de restauration des variables AutoCAD. Je pense que ce post et le bon endroit pour (inutile de multiplier les doublons).

 
;; ******* SAUVEGARDE & RESTAURATION DES VARIABLES AUTOCAD *******
;; ---------------------------------------------------------------
;; (bv:sr_var lvar)                                      VDH-Bruno
;; Routine de Sauvegarde et de Restauration des VARiables AutoCAD.
;; ---------------------------------------------------------------
;; Description:                                                   
;; L'argument lvar est une liste de variables AutoCAD ou nil.     
;; Si lvar est vrai la fonction sauvegarde l'état des variables   
;; passées en argument, si lvar vaut nil la fonction restaure     
;; leurs états antérieurs.                                        
;; ---------------------------------------------------------------
;; Exemples:                                                      
;; (bv:sr_var '(CMDECHO OSMODE CECOLOR)) ;Sauvegarde les variables
;; (bv:sr_var nil)                      ;Restaure les variables   
;; ---------------------------------------------------------------
;; Notes:                                                         
;; Pendant la phase d'écriture et de débogage d'un prog, il peut  
;; être interréssant de précéder l'expression (setq res_lvar nil) 
;; d'un point virgule.                                            
(defun bv:sr_var (lvar)
 (if lvar
   (setq *res_lvar*
   (mapcar '(lambda (x) (cons x (cons (getvar x) ()))) lvar)
   )
   (progn
     (mapcar '(lambda (l) (setvar (car l) (cadr l))) *res_lvar*)
     (setq *res_lvar* nil)
   )
 )
)

;| variante sans progn dans le if
(defun bv:sr_var (lvar)
 (if lvar
   (setq res_lvar
   (mapcar '(lambda (x) (cons x (cons (getvar x) ()))) lvar)
   )
   ((lambda (lst)
      (mapcar '(lambda (l) (setvar (car l) (cadr l))) lst)
      (setq res_lvar nil)
    )
     res_lvar
   )
 )
)
|; 

 

C’est une fonction que j’aime bien (du 2 en 1) simple d’utilisation et qui accepte des listes de variables. Il est possible de la localiser, et l’appeler au début de votre programme avec la liste des variables à sauvegarder, par exemple :

 (bv:sr_var '(CMDECHO OSMODE CECOLOR BLIPMODE PLINEWID)) 

 

Par la suite dans le déroulement de votre programme vous modifiez l’état de ces variables comme bon vous semble. Et en sortie (ainsi que dans votre routine d’erreur) vous rappelez la fonction comme ceci.

 (bv:sr_var nil) 

Et l’état initial de vos variables sera restauré.

Bon j’ai bien conscience que cela n’a rien de révolutionnaire, mais il ne me semblait pas avoir vu ces lignes de codes dans le forum (je peux me tromper..).

 

 

 

Avant de publier j'ai voulu confronter mon code à ce qui se faisait sur le forum et je suis tombé sur ce post, visiblement la logique ici privilégie plutôt de faire du SAVE-SET que du SAVE-RESTORE donc même si j’ai une préférence pour mon code précédent, je me suis livré à l’exercice en m’inspirant du code (gile), tout en essayant de garder la philosophie du mien..

 

Ce qui donne ceci du 3 en 1 ( SAVE-SET-RESTORE) sous forme de liste d’arguments..

 
;; ********* SAVE & SET & RESTORE LES VARIABLES AUTOCAD **********
;; ---------------------------------------------------------------
;; (bv:ssr_var lvar)                                     VDH-Bruno
;; Sauvegarde, Modifie et de Restaure les VARiables AutoCAD.      
;; ---------------------------------------------------------------
;; Description:                                                   
;; L'argument lvar est une liste de variables AutoCAD à           
;; sauvegarder (et à modifier), si lvar vaut nil la fonction      
;; restore leurs états initial.                                   
;; ---------------------------------------------------------------
;; Exemples:                                                      
;; (bv:ssr_var '(("CMDECHO" 0);Sauve et modifie la variable à 0   
;;               (OSMODE 119) ;Sauve et modifie la variable à 119 
;;               (CECOLOR)    ;Sauve (sans modifier la variable)  
;;               (TOTO)       ;Alert et ignore l'erreur           
;;              )                                                 
;; )                                                              
;; (bv:ssr_var nil)           ;Restore l'état des variables       
;; ---------------------------------------------------------------
;; Remarques:                                                     
;; A tout moment dans votre programme vous pouvez rappeler la     
;; fonction bv:ssr_var pour lui ajouter de nouvelle variable à    
;; sauvegarder (et à modifier). Si par erreur vous rappelez la    
;; fonction avec une variable déjà sauvegardé, elle sera seulement
;; modifié.                                                       
;; La fonction tolère également les syntaxes stringp ou symbolp   
;; comme nom de variable, du type -> 'CECOLOR ou "CECOLOR"        
;; ---------------------------------------------------------------

(defun bv:ssr_var (lvar / fun)

 ;; Prédicat recherche ele dans list à 1 profondeur
 (defun fun (ele lst)
   (cond
     ((member ele (car lst)) T)
     ((null lst) nil)
     (T (fun ele (cdr lst)))
   )
 )

 (if lvar
   ;; si lvar vrai construire ou compléter *res_lvar*
   (setq *res_lvar*
   (append
     (apply
       'append
       (mapcar
	 '(lambda (x / var)
	    (cond
	      ;; si x est un atom et pas une variable AutoCAD renvoi nil
	      ((or (atom x) (not (getvar (car x))))
	       (alert
		 (strcat
		   "\n (bv:ssr_var) Erreur: variable AutoCAD rejetée: "
		   (vl-princ-to-string x)
		 )
	       )
	      )
	      ;; si pas de fun (member) 
	      ((not
		 (fun (vl-princ-to-string (car x)) *res_lvar*)
	       )
	       ;; mémoriser la variable
	       (setq var (list 'setvar
			       (vl-princ-to-string (car x))
			       (getvar (car x))
			 )
	       )
	       ;; si (cdr x) modifier la variable 
	       (if (cdr x)
		 (setvar (car x) (cadr x))
	       )
	       ;; retourne la variable
	       (list var)
	      )
	      ;; si (cdr x) modifié la variable et renvoi nil
	      ((cdr x) (setvar (car x) (cadr x)) nil)
	    )
	  )
	 lvar
       )
     )
     *res_lvar*
   )
   )
   ;; si lvar vaut nil restaurer l'état des variables
   (progn (mapcar 'eval *res_lvar*) (setq *res_lvar* nil))
 )
)

 

J’espère de n’avoir pas trop compliqué les choses par rapport à mon intention première, en espérant également de ne pas avoir fait de grosse erreur de logique dans les and cond et if. Il y a peut être moyen de simplifier un peu je m’y pencherai dessus à tête reposé, aux premiers testes ça à l’air de tenir la route.

 

A+ Bruno

(Comme d'hab toutes critiques, remarques ou suggestions sont le bienvenue)

 

 

 

[Edité le 27/5/2011 par VDH-Bruno]

Apprendre => Prendre => Rendre

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Pour les changements des valeurs de variables système et leur restauration, voir la routine : ai_sysvar définie dans acad20XXdoc.lsp (donc automatiquement chargée dans chaque document) qui fait une utilisation intéressante de defun-q pour redéfinir la fonction.

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

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é