Aller au contenu

MA gestion d\'erreur... pour avis


Messages recommandés

Posté(e)

Salut,

En essayant de comprendre le fonctionnement des gestions d'erreurs, et en essayant d'en simplifier l'utilisation, je suis arrivé à ça, et j'aurais aimé que vous me donniez votre avis avant de continuer dans mes test ...

(je sais que des routines sont proposés dans ce site pour la gestion d'erreur (par exemple celle de (gile)), mais j'avais commencé à bosser dessus avant et ça me permet d'aprendre...)

 

 ;;; Routine de Sauvegarde des variables à sauver
(defun Sauv-var (listevar / num list1)
     (setq list_var_sauv nil
    num 0)
(repeat (length listevar)	  
  (setq list1 (list (cons (nth (+ 0 num) listevar)(getvar (nth (+ 0 num) listevar)))))
  (setq num (+ num 1))
  (setq list_var_sauv (append list_var_sauv list1))
  )
 )

 ;;; Routine Gestion d'un message d'erreur
(defun Gestion_erreur (msg)    
 (if (or (= msg "Fonction annulée")
  (= msg "Function cancelled")
  (= msg "quitter / sortir abandon")
         (= msg "quit / exit abort"))
     (progn
(setq num 0)
(repeat (length list_var_sauv)
(setvar (car (nth num list_var_sauv))(cdr (nth num list_var_sauv)))
(setq num (+ num 1))))
   )
 (setq *error* Sauv_EXerror)
 )

 

 ;;; DANS PROGRAMME --
(defun c:EXEMPLE ()
 (setq Sauv_EXerror *error*
*error* Gestion_erreur)
 (Sauv-var '("orthomode"
      "cmdecho"
      "pickfirst"
      "zoomfactor"
      "AFLAGS"))

 (...PROGRAMME...)

 (setq *error* Sauv_EXerror)
 )

 

... la liste de variable c'est n'importe quoi pour les tests ...

 

merci d'avance.

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

La méthode est bonne, il ne faut pas oublier de restaurer les variables à la fin du LISP (s'il n'y a eu ni erreur ni annulations), et je suis sûr que tu sauras l'amèliorer.

 

J'utilise une méthode semblable, que j'ai améliorée/épurée au fil du temps, la liste des variables n'est pas établie au début du LISP mais se constitue au fur et à mesure de la modification des variables en utilisant SAVE&SET_VAR au lieu de setvar. Chaque élément de la liste (SavedSysVarLst) est une liste composée du symbole 'setvar, du nom de la variable et de la valeur initiale. Voici la dernière version :

 

ex: (SAVE&SET_VAR "autosnap" nil) (SAVE&SET_VAR "orthomode" 1)

La liste SavedSysVarLst : ((setvar "orthomode" 0) (setvar "autosnap" 63))

après quoi,

(getvar "orthomode") retourne 1

(getvar "autosnap") retourne 55 (63 - 8 : le repérage polaire est désactivé)

 

;;; 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)


(defun SAVE&SET_VAR (var val)
(cond
((getvar var)
(setq SavedSysVarLst
(cons (list 'setvar var (getvar var)) SavedSysVarLst)
)
(if val
(setvar var val)
)
)
)
) 

 

Pour restaurer les valeurs initiales à la fin du LISP ou de la fonction de gestion d'erreur il suffit d'évaluer tous les éléments de la liste en faisant :

 

(mapcar 'eval SavedSysVarLst) 

[Edité le 29/6/2006 par (gile)]

 

[Edité le 29/6/2006 par (gile)]

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

Posté(e)

Ha!... c'est sûr que vu comme ça c'est "sympa" : enregistrer et modifier dans la même étape permet de se "reposer" sur la routine ... je n'y avais pas penser, et c'est exactement le genre de "simplification" qui m'interesse... [surligneur] merci n°1[/surligneur]

 

En effet je n'avais pas retourner les valeurs des variables si réussi (vu que je testais les erreurs, j'avais fait abstraction du programme réussi... pas trés malin de ma part...) ... [surligneur] merci n°2[/surligneur]

 

et maintenant 2 soucis suplémentaires :

 

Je ne suis pas tranquiliser dans mon choix de "message d'erreur" ... j'ai essayé de le faire fonctionner pour un escape ou un quit (lisp), mais j'ai un doute sur la manière dont la gestion d'erreur réagis en cas d'erreur de "données de programmes" (une erreur du lisp)...

 

... De plus je n'arrive pas à mettre la main sur une variable me permettant d'enregistrer le SCU actif (si il est modifié pendant le lisp) ... j'ai testé avec des enregistrement de SCU, mais ma gestion d'erreur ne le prend pas en compte ...

 

merci merci...

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Pour le message, ce qui se fait, c'est de faire un (princ) en cas dannulation ou de (quit) et de laisser délivrer le message d'erreur AutoCAD dans les autres cas :

 

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

 

C'est ensuite, et dans tous les cas que l'on restaure l'environnement (variables, SCU, groupe "_undo" ...)

 

Pour le SCU comme pour toutes les variables en lecture seule, il faut passer par un (command ...)

 

par exemple après avoir sauvé le SCU initial dans un SCU nommé :

 

(command "_ucs" "_save" "scu_init")

 

On peut changer le SCU dans la routine et à la fin de la routine et de la fonction de gestion des erreurs, on fait :

 

(command "_ucs" "_restore" "scu_init")
(command "scu" "_del" "scu_init")

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

Posté(e)

Donc on recommence les merci :

 

Concernant le message d'erreur, je pense qu'il faut que je m'y penche un peu plus, parceque je pensais que c'était ces messages qui faisait enclenché la routine de gestion d'erreurs (restauration variable et autre...) et que l'on créé donc dans le lisp principal une gestion des erreurs "perso" qui remplaçait celle d'autocad par défaut (d'où mon

 

 (setq Sauv_EXerror *error*
*error* Gestion_erreur)

 

... je pense que je n'ai pas dû comprendre ...

 

Par contre pour la restauration du SCU, j'avais fait ce que tu proposes, mais comme je dois avoir un souci dans ma routine de gestion d'erreur principal, il ne me prenais pas à tout les coups le (command "scu" "_del" "scu_init"), ce qui me créé une erreur si je relançais le lisp, vu que lorsque je fait un (command "_ucs" "_save" "scu_init"), il me le refuse vu que "scu_init" existe déjà ... mais je pense que lorsque j'aurais mis au point (et vraiment compris) la remarque précedente, ce problème ne se poseras plus...

 

merci en tout cas... je fairais suivre mes progrés ...

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Ce ne sont pas les messages, mais les erreurs (les vraies ou annuler, quitter) qui déclenchent l'exécution de la fonction *error*.

 

Cette fonction *error* dans sa version prédéfinie délivre un message du type :

 

"; erreur: type d'argument incorrect : numberp NIL"

ou

"; erreur: Fonction annulée"

 

Elle pourrait avoir été définie en LISP comme ceci :

 

(defun *error* (msg)

(princ (strcat "; erreur: " msg))

(princ)

)

 

Quand on fait le mic mac autour des messages d'erreur, c'est uniquement pour ne pas avoir à la ligne de commande ce type de message :

*Annuler*

; erreur: Fonction annulée

 

mais seulement : *Annuler*

 

Sinon tu as bien compris, on remplace, pendant le temps de l'exécution de la routine, la fonction *error* originelle (après l'avoir sauvegardée dans une autre variable) par celle qu'on a redéfinie :

 

(setq Sauv_EXerror *error*

*error* Gestion_erreur)

 

et à la fin de la routine et de la fonction Gestion_erreur on restaure la fonction originelle :

 

(setq *errror* Sauv_EXerror

Sauv_EXerror nil)

 

D'une manière générale la fin de la routine principale et la fin de la routine de gestion d'erreur sont identiques en ce qui concerne toute la restauration de l'environnement (groupe annuler, variables systèmes, fonction *error* ...)

 

 

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

Posté(e)

... ben voilà à quoi j'arrive ... pour avis (surtout la manière de traiter le SCU!!!...)

 

 

 ;;; TRAITEMENT - EXEMPLES
;;;--------------------------						
; (defun c: mon_programme ()					
;	(INTRO_PRG_ERR);					

; ---- ( ... programme - modif variable avec (SAVE&SET_VAR "variable" nouv-valeur) ...	
;		... modif sens SCU si besoin  ...)			.
;							.
; fin de programme   (END_PRG_ERR)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Traitements des variables habituels (à compléter)
(defun TRAIT_VAR_TYPE ()
 (SAVE&SET_VAR "cmdecho" 0)
 (SAVE&SET_VAR "attdia" 0)
 (SAVE&SET_VAR "attreq" 1)
)
;;; Enregistrement du SCU Actif
(defun TRAIT_SCU_ACTIF ()
 (setq orig (getvar "ucsorg")
     dirx (getvar "ucsxdir"))
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Introduction du programme - Redéfinition de *error*
(defun INTRO_PRG_ERR ()
 (setq Sauv_EXerror *error*)
 (TRAIT_VAR_TYPE)
 (TRAIT_SCU_ACTIF)
 (setq *error* REDEF_ERROR)
)  

;;; Routine d'enregistrementde variable modifiable ((gile) cadXP)
(defun SAVE&SET_VAR (var val)
 (setq SavedSysVarLst nil)
 (cond
   ((getvar var)
    (setq SavedSysVarLst
    (cons (list 'setvar var (getvar var)) SavedSysVarLst))
    (if val
      (setvar var val)))
   )
)

;;; Restauration des Variables modifiables enregistrer avec SAVE&SET_VAR ((gile) cadXP)
(defun SET_VAR_SAVE ()
 (mapcar 'eval SavedSysVarLst)
)

;;; Restauration du SCU
(defun SET_SCU_SAVE ()
 (command "_ucs" "_w"
 "_ucs" "_o" orig
 "_ucs" "_3" '(0 0 0) dirx "")
)

;;; Routine de Gestion des Erreur remplaçant celle d'Autocad (setq msg "Fonction annulée")
(defun REDEF_ERROR (msg)    
 (if (or (= msg "Fonction annulée")
  (= msg "Function cancelled")
  (= msg "quitter / sortir abandon")
         (= msg "quit / exit abort"))
   (progn (princ "Action: ")(princ msg)(princ))
   )
 (SET_VAR_SAVE)
 (SET_SCU_SAVE)    
 (setq *error* Sauv_EXerror) ; retour *error* initial
)

;;; Fin de Programme - ; retour *error* initial
(defun END_PRG_ERR ()
 (SET_VAR_SAVE)
 (SET_SCU_SAVE)
 (setq *error* Sauv_EXerror)  
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

... alors ????

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut,

 

Je remarque deux petites "erreurs"

 

- Dans la fonction REDEF_ERROR il ne faut pas faire de (progn ...). C'est : si annuler ou quitter, alors pas de message, sinon (dans les autres cas d'erreurs) le message est délivré.

 

(defun REDEF_ERROR (msg)
(if (or (= msg "Fonction annulée")
(= msg "Function cancelled")
(= msg "quitter / sortir abandon")
(= msg "quit / exit abort"))
(princ) ;_ pas de message
(princ (strcat "\nErreur: " msg)) ;_le message est délivré
)
(END_PRG_ERR)
) 

 

- L'idée de récupérer le SCU avec les variables est excellente (pas de SCU nommé) mais incomplète. Pour faire un SCU 3 points fiable il faut aussi récupérer UCSYDIR.

 

(defun TRAIT_SCU_ACTIF ()
(setq orig (getvar "ucsorg")
dirx (getvar "ucsxdir")
diry (getvar "ucsydir"))
) 

 

Et au moment du SCU 3 points il est préférable que les accrochages aux objets soient désactivés. On peut aussi utiliser l'accrochage temporaire "_NON" ou "AUC" (pour aucun) avant de spécifier chacun des points.

En utilisant la fonction (trans ...), il n'est pas nécessaire de passer par un SCG puis un SCU origine :

 

(defun SET_SCU_SAVE ()
 (command "_.ucs"
   "_3"
   "_non"
   (trans orig 0 1)
   "_non"
   (trans dirx 0 1)
   "_non"
   (trans diry 0 1)
 )
)

 

Sinon, pour la forme, çà fait pas mal de variables définies (orig, dirx, diry, Sauv_EXerror, SavedSysVarLst) qu'il serait préférable de déclarer dans la fonction principale :

 

(defun c: mon_programme (/ orig dirx diry Sauv_EXerror SavedSysVarLst) ...)

 

ou de remettre à nil dans la fonction END_PRG_ERR.

 

Cette fonction, d'ailleurs, pourrait être appelée à la fin de REDEF_ERROR (voir plus haut).

 

Dernière chose, si tu utilises SAVE&SET_VAR, je ne vois pas l'intérêt de faire TRAIT_VAR_TYPE, j'avais fais cette routine justement pour ne pas avoir à faire de liste de variables prédéfinie.

 

Dans ce sujet la question est un peu approfondie.

 

 

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

Posté(e)

Salut,

merci (gile) pour tes remarques.

j'ai donc modifiés mes erreurs comme tu me l'as préconisé.

 

Concernant le nombre de variables à "re-initialisé", j'ai simplifié l'"Enregistrement du SCU Actif" :

 ;;; Enregistrement du SCU Actif
(defun TRAIT_SCU_ACTIF ()
 (setq list_scu_actif (list (getvar "ucsorg")
		     (getvar "ucsxdir")
		     (getvar "ucsydir"))
)

 

que je traite donc comme ceci :

 ;;; Restauration du SCU
(defun SET_SCU_SAVE ()
 (command "_.ucs""_3" "_non"(trans (car list_scu_actif) 0 1)
   "_non" (trans (cadr list_scu_actif) 0 1)
   "_non" (trans (caddr list_scu_actif) 0 1))
)

 

.. et je n'est donc "plus que" 3 variables à mettre à nil, que je fais comme tu me la proposer dans END_PRG_ERR :

 ;;; Fin de Programme - ; retour *error* initial
(defun END_PRG_ERR ()
 (SET_VAR_SAVE)
 (SET_SCU_SAVE)
 (setq *error* Sauv_EXerror
list_scu_actif nil
SavedSysVarLst nil
Sauv_EXerror nil)  
)

 

............................

 

Dernière chose, si tu utilises SAVE&SET_VAR, je ne vois pas l'intérêt de faire TRAIT_VAR_TYPE, j'avais fais cette routine justement pour ne pas avoir à faire de liste de variables prédéfinie.

 

... je l'avais compris, mais je suis "faignant", et comme dans la plupart de mes lisps j'utilise quasiment toujour les même variables, je me craierais une liste "type"... juqu'au jour ou je me rendrais sompte que c'est inutile !!!... mais le fait de créér une liste type ne m'interdis pas dans mon programme de rajouter des variables ponctuellement grâce à ton (SAVE&SET_VAR ...)

 

... merci en tout cas pour ton aide (encore)...

et tu peux continuer, ça ne me dérange pas du tout (;))... j'apprends énormément par ton aide (et aussi par l'aide d'autre de ce forum, je ne les oublies pas!!!)

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Tous ça est très bien, bravo !

 

Utiliser une liste plutôt que 3 variables est trés "lispien" et, à mon goût, bien plus élégant, je suis content (et un peu fier aussi) que tu anticipes les suggestions que j'aurais pu te faire.

 

Une autre façon de faire, quand on groupe toutes les actions (setvar et command) à l'intérieur d'un même groupe d'annulation, est de fermer le groupe dans la routine de redéfinition de *error* :

(command "_.undo" "_end")

puis d'annuler le groupe de commande :

(command "_u") ou (command "_.undo" 1)

 

C'est la méthode utilisée ici.

 

 

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

Posté(e)

Salut (gile)

J'ai jeté un coup d'oeuil sur ton lisp que tu cites ci-dessus, et j'ai compris la manière dont tu utilises "_undo".

Je touve ta routine SAVE&SET_VAR tellement bien et facile d'utilisation que je vais l'utiliser en priorité...

(au sujet de cette routine d'ailleur, je n'utilise jamais le maillage 3D en 3D, mais les solides... donc je n'ai aucune remarque "constructive" à faire, à part que tu fais vraiment des truc épatant :D ...)

Par contre l'utilisation de "-undo" m'a donné l'idée de mettre une "marque" en début de programme, et de la rappeler en cas d'erreur :

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Introduction du programme - Redéfinition de *error*
(defun INTRO_PRG_ERR ()
 (setq Sauv_EXerror *error*)
 (command "_undo" "m")
 (TRAIT_VAR_TYPE)
 (TRAIT_ENV_ACTIF)
 (setq *error* REDEF_ERROR)
)

 

 ;;; Routine de Gestion des Erreur remplaçant celle d'Autocad
(defun REDEF_ERROR (msg)
 (if (or (= msg "Fonction annulée")
  (= msg "Function cancelled")
  (= msg "quitter / sortir abandon")
  (= msg "quit / exit abort"))
   (princ) 
   (princ (strcat "\nErreur: " msg))
   )
 (command "_undo" "r")
 (END_PRG_ERR)
) 

 

... et de refaire une marque si le lisp arrive au bout

 ;;; Fin de Programme - ; retour *error* initial
(defun END_PRG_ERR ()
 (SET_VAR_SAVE)
 (SET_ENV_SAVE)
 (setq *error* Sauv_EXerror
list_env_actif nil
SavedSysVarLst nil
Sauv_EXerror nil)
(command "_undo" "m")
)

 

(D'ailleur, je connais (getcname) pour traduire une commande, mais pour connaitre le choix de l'option en anglais, je ne sais pas comment faire...)

 

De plus, j'ai rajouté dans mon introduction de gestion d'erreur, en + du SCU, le calque actif... je verrai à l'utilisation ce que je peux rajouter comme paramètres d'environnement suplémentaire...peut-être l'espace objet/papier, mais je n'en vois pas l'utilité pour l'instant.

 ;;; Enregistrement du environnement Actif (SCU / Calque)
(defun TRAIT_ENV_ACTIF ()
 (setq list_env_actif (list (getvar "ucsorg")
		     (getvar "ucsxdir")
		     (getvar "ucsydir")
		     (getvar "clayer")))
)

 ;;; Restauration de l'Environnement (SCU / Calque)
(defun SET_ENV_SAVE ()
 (command "_.ucs""_3" "_non"(trans (nth 0 list_env_actif) 0 1)
   "_non" (trans (nth 1 list_env_actif) 0 1)
   "_non" (trans (nth 2 list_env_actif) 0 1))
 (setvar "clayer" (nth 3 list_env_actif))
)

 

... merci des remarques...

 

[Edité le 3/7/2006 par Bred]

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Bon ben après reflexion je simplifie encore : c'est vraiment n'importe quoi de faire une marque d'annulation ET de restaurer les variables (l'annulation le fait trés bien, comme la routine de (gile) précedement cité le fait!!!...)

Donc :

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Introduction du programme - Redéfinition de *error*
(defun INTRO_PRG_ERR ()
 (setq Sauv_EXerror *error*)
 (command "_undo" "m");;;marque d'annulation
 
 ; Traitements des variables habituels (à compléter/modifier)
 (SAVE&SET_VAR "cmdecho" 0)
 
 ; Enregistrement du environnement Actif (SCU / Calque)
 (setq list_env_actif (list (getvar "ucsorg")
		     (getvar "ucsxdir")
		     (getvar "ucsydir")
		     (getvar "clayer")))
 
 ; Gestion des Erreur remplaçant celle d'Autocad
 (setq *error* REDEF_ERROR) 
)
;;; Routine de Gestion des Erreur remplaçant celle d'Autocad
(defun REDEF_ERROR (msg)
 (if (or (= msg "Fonction annulée")
  (= msg "Function cancelled")
  (= msg "quitter / sortir abandon")
  (= msg "quit / exit abort"))
   (princ) 
   (princ (strcat "\nErreur: " msg))
   )
 (command "_undo" "r")  
)

;;; Routine d'enregistrementde variable modifiable ((gile) cadXP)
(defun SAVE&SET_VAR (var val)
  (cond
   ((getvar var)
    (setq SavedSysVarLst
    (cons (list 'setvar var (getvar var)) SavedSysVarLst))
    (if val
      (setvar var val)))
   )
)


;;; Fin de Programme - ; retour *error* initial
(defun END_PRG_ERR ()
 ; Restauration des Variables modifiables enregistrer avec SAVE&SET_VAR
 (mapcar 'eval SavedSysVarLst)
 ; Restauration de l'environnement Actif enregistré
 (command "_.ucs""_3" "_non"(trans (nth 0 list_env_actif) 0 1)
   "_non" (trans (nth 1 list_env_actif) 0 1)
   "_non" (trans (nth 2 list_env_actif) 0 1))
 (setvar "clayer" (nth 3 list_env_actif))
 (setq *error* Sauv_EXerror
list_env_actif nil
SavedSysVarLst nil
Sauv_EXerror nil)
(command "_undo" "m"); marque d'annulation
)

 

... c'est plus malin et avec moins "d'aller-retour" .... non ???

 

[Edité le 3/7/2006 par Bred]

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut

tu peux utiliser (vla-startundomark (vla-get-activedocument (vlax-get-acad-object))) comme (command "_.undo" _group") --> début du undo

et (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) comme (command "_.undo" "_end") --> fin du undo

 

Juste une astuce pour trouver les options en anglais, il suffit de faire la traduction et de l'essayer au clavier, et en général, la première lettre suffit, mais si on a le terme complet, c'est mieux

 

Je constate que comme tu te sers de command, tu n'as pas rsdéfinit la variable cmdecho, ce qui évite de voir séfiler les lignes de commandes que tu utilises dans ton lisp.D'aiileur, cette variable n'a pas besoin d'être modifiée en vlisp

 

@+

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

Posté(e)

Merci Patrick_35,

j'ai compris l'utilité des commandes vl pour certaines choses, mais pourrais-tu m'expliquer le "bienfait" ce commandes vl ici, comparé à un "_undo" ?...

 

merci encore

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

De ne pas avoir besoin de redéfinir la varibale cmdecho

D'ailleurs, dès que l'on utilise un command, on redéfinit cette variable et puis ça fait plus "lispien" De plus, je trouve que moins on se sert de command, plus le lisp est portable d'une version à une autre d'autocad

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

Posté(e)

Bonsoir,

 

Un des avantages des commandes vla- est, comme le dit Patrick_35, l'absence d'echo sur la ligne de commande.

 

Le (command "_.undo" "_begin") ou "_group" ou "_mark" doit être fait avant de désactiver CMDECHO pour que le changement de variable soit inclus dans le groupe undo, donc l'écho de la commande apparaît à la ligne de commande.

Il existe une alternative aux fonction vla- pour palier à ce "problème" (qui n'est qu'esthétique, mais j'y suis sensible) depuis les versions 2004, c'est le LISP ai_setCmdEcho qui en jouant avec une variable d'environnement (acedChangeCmdEchoWithoutUndo) permet de desactiver CMDECHO sans que ceci ne soit pris en compte par _undo.

Ce LISP est dans le fichier ai_utils.lsp qui n'est pas chargé automatiquement.

J'en ai déjà parlé, tu peux faire une recherche dans les forum avec ai_setCmdEcho.

 

Sinon, je comprends ta démarche et j'ai moi aussi essayé de trouver une méthode "universelle" de gestion des erreurs, et ce faisant j'ai beaucoup appris, mais j'ai remarqué que souvent il faut faire différemment. Par exemple dans le LISP cité plus haut (SurfDev) je n'utilise pas Save&Set_var parce que je voulais restaurer l'accochage aux objets avant la fin de la routine pour l'insertion du bloc.

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

Posté(e)

OK...OK... merci

mais je ne suis vraiment pas assez bon pour ne plus avoir besoin de (command...)...

J'ai écris dernièrement un lisp (grâce à l'aide des personnes de ce site) qui récupère des données dans un tableau Excel afin de dessiner des profilés métalliques en 3D... la récupération je la fait en vl (et c'est justement grâce à ton aide, Patrick) mais le dessin de la section en polyligne, j'ai été totalement incapable de le faire sans (command ...)...

avec (entmake) je ne réussis qu'a dessiner un rond rouge (c'est l'exemple de l'aide d'Autocad), mais tracer une polyligne à plusieurs (trés nombreux) sommets, je me suis épuisé dessus, alors qu'avec (command) je l'ai fait "simplement" ..... par contre il est vrais que j'ai un bug de dessin "hors Ecran" ... mais ceci est une autre histoire et je me pencherais dessus... quand j'aurais le temp !!!

 

Hop là, j'ai raté la réponse de (gile) en parrallèle de ma réponse donc "j'édite"...

 

merci (gile), je vais allez voir ça...

 

 

 

[Edité le 3/7/2006 par Bred]

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

je n'utilise pas Save&Set_var parce que je voulais restaurer l'accochage aux objets avant la fin de la routine pour l'insertion du bloc.

 

... heu... je ne comprend pas : Save&Set_var t'enregitre la variable active et te modifie la variable comme demandé... qu'est-ce qui t'empèches dans ta routine de faire un (setvar "osmode" valeur) ... quoiqu'il arrive ton Save&Set_var reinitialiseras la variables, même si celle-ci à la "même valeur" ... non ???

 

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Je viens justement de retrouver un message dans lequel je décris avec mauvaise foi mais réalisme, la manière de créer une polyligne avec (command ...) (entmake ...) et (vla-add ...).

 

Le sujet dans lequel se trouve ce message, fait tout à fait écho à celui ci.

 

Personnellement, si j'utilise de plus en plus le VisualLISP, je continue à utiliser les (command ...) comme dans SurfDev où les (command ... pause ...) permettent de rendre la main à l'utilisateur dans l'environnement habituel. J'aime beaucoup aussi les (entmake ...) (entmod ...) qui permettent parfois des codes très élégants quand il s'agit de manipuler des listes (comme dans le petit dernier dont je suis, je dois l'avouer, assez fier).

 

Je viens de voir les dernières réponses.

 

... heu... je ne comprend pas : Save&Set_var t'enregitre la variable active et te modifie la variable comme demandé... qu'est-ce qui t'empèches dans ta routine de faire un (setvar "osmode" valeur) ... quoiqu'il arrive ton Save&Set_var reinitialiseras la variables, même si celle-ci à la "même valeur" ... non ???

 

Tu parfaitement raison (et parfaitement compris !), il y a en fait une autre raison, j'utilise beaucoup de sous-routines (dont save&set_var) qui sont chargées automatiquement dans mon profil utilsateur, mais quand je publie dans CADxp ou que je fais une routine pour quelqu'un d'autre, j'écris souvent les LISP sans les utiliser pour ne pas trop encombrer le code.

 

[Edité le 4/7/2006 par (gile)]

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

Posté(e)

Alors... je me pencherais plus sur les fonctions entmake et autre plus tard, et je lancerais un nouveau post, mais là il faut que je revienne à la gestion d'erreur (si je commence à "m'éparpiller" je n'avancerais pas...)

 

1 - je n'ai pas trouvé ai_setCmdEcho.lsp ...

 

2 - ... donc j'ai utilisé les commandes vl- comme suit :

;;; INTRODUCTION du PROGRAMME - Redéfinition de *error*
(defun INTRO_PRG_ERR ()  
 (setq Sauv_EXerror *error*) ; enregistrement *error* autocad  
 (vla-startundomark (vla-get-activedocument (vlax-get-acad-object)));;;début "undo"  
 ; Traitements des variables habituels (à compléter/modifier)
 (SAVE&SET_VAR "cmdecho" 0)   
 ; Enregistrement du environnement Actif (SCU / Calque)
 (setq list_env_actif (list (getvar "ucsorg")
		     (getvar "ucsxdir")
		     (getvar "ucsydir")
		     (getvar "ucsicon")
		     (getvar "clayer")))  
 ; Gestion des Erreur remplaçant celle d'Autocad
 (setq *error* REDEF_ERROR) 
)

;;; ROUTINE de GESTION des ERREURS remplaçant celle d'Autocad
(defun REDEF_ERROR (msg)
 (if (or (= msg "Fonction annulée")
  (= msg "Function cancelled")
  (= msg "quitter / sortir abandon")
  (= msg "quit / exit abort"))
   (princ) 
   (princ (strcat "\nErreur: " msg))
   )
 (command "_undo" "r")  
)

;;; Routine d'enregistrementde variable modifiable ((gile) cadXP)
(defun SAVE&SET_VAR (var val)
  (cond
   ((getvar var)
    (setq SavedSysVarLst
    (cons (list 'setvar var (getvar var)) SavedSysVarLst))
    (if val
      (setvar var val)))
   )
)
;;; FIN de PROGRAMME - ; retour *error* initial
(defun END_PRG_ERR ()
 ; Restauration des Variables modifiables enregistrer avec SAVE&SET_VAR
 (mapcar 'eval SavedSysVarLst)
 ; Restauration de l'environnement Actif enregistré
 (command "_.ucs""_3" "_non"(trans (nth 0 list_env_actif) 0 1)
   "_non" (trans (nth 1 list_env_actif) 0 1)
   "_non" (trans (nth 2 list_env_actif) 0 1))
 (setvar "ucsicon" (nth 3 list_env_actif))
 (setvar "clayer" (nth 4 list_env_actif))
 (setq *error* Sauv_EXerror
list_env_actif nil
SavedSysVarLst nil
Sauv_EXerror nil)
(vla-endundomark (vla-get-activedocument (vlax-get-acad-object))); fin du "undo"
)

 

... he bien je lance un lisp avec (INTRO_PRG_ERR) au début ..... puis (END_PRG_ERR) à la fin, ça fonctionne 1fois... et ça me fait planter Autocad (!!!)...

je ne vois pas pourquoi...

 

3 - Est-il possible de faire une gestion d'erreur incluant un "malfonctionnement" du lisp... c'est à dire: en prenant l'exemple precedement cité, lorsque j'ai une action hors-affichage et qu'il me la refuse (quelquefois), j'ai le lisp qui continue quand même à défiler j'usqu'à la fin, en écrivant des " "x" commande inconnu - appuyer sur F1..." ... j'aurais aimé qu'il revienne à mon "_undo", au lieu de faire n'importe quoi et de le laisser !!!

 

... merci de votre aide...

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut

Je viens de tester et ça a l'air de fonctionner correctement. Il y a juste un (command "_undo" "r") qui traine dans la gestion des erreurs qu'il faudrait remplacer par un (vla-endundomark (vla-get-activedocument (vlax-get-acad-object))) afin de boucler le undo mark et j'ai constaté dans ta routine de gestion d'erreurs que tu ne remettais pas tes variables à leurs états d'origine et que tu ne repointais pas non plus sur la gestion d'erreur d'origine

 

@+

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

Posté(e)

Re...

Patrick_35 :

... le "retour à la marque" (command "_undo" "r") répond justement à toutes ta remarques : j'ai dans l'idée que lorque ma gestion d'erreur se lance, elle retourne justement à l'"undo" qui est dans INTRO_PRG_ERR, et donc ramène toutes mes variables à leur état initial...

le "retour" à la marque en vl- je ne le connais pas, donc j'ai laissé (command "_undo" "r")...

 

.. de plus je ne vois pas pourquoi il me faut faire une "fin de undo" dans ma gestion d'erreur : si justement elle se lance, je ne veux pas arréter un groupe mais revenir en arrière au groupe précedent...

 

mais j'avoue ne pas être certain de tout ça...

 

.... Grrr...

et un souci suplémentaire, un !... :

la remise au SCU actif ne fonctionne pas dans tous la cas...

si j'ai un SCU=SCG, et que je l'enregistre dans cette configuration, puis que je le modifie, le retour au scu actif fonctionne...

par contre, si je fais le contraire, c.à.d. si je met le scu en "vrac", que je l'enregistre tel quel, que je le modifie (je le passe en général), le rétablissement ne fonctionne pas... j'ai beau cherché depuis quelques heures, je ne vois pas pourquoi!!! ...

 

 (setq list_env_actif (list (getvar "ucsorg")
		     (getvar "ucsxdir")
		     (getvar "ucsydir"))

 (command "_.ucs""_3" "_non"(trans (nth 0 list_env_actif) 0 1)
   "_non" (trans (nth 1 list_env_actif) 0 1)
   "_non" (trans (nth 2 list_env_actif) 0 1))

 

 

 

 

 

 

[Edité le 4/7/2006 par Bred]

Si vous êtes persuadés de tout savoir sur un sujet, c''est que vous en ignorez quelque chose...

Posté(e)

Salut,

 

Tu trouveras ai_setCmdEcho ici.

 

Si ti utitlises _undo pour la restauration de l'environnement initial, je pense qu'il vaut mieux faire :

 

(command "_.undo" "_begin") ou (command "_.undo" "_group") -c'est la même chose- au début du LISP et

(command "_.undo" "_end") (command "_u") dans la routine de redéfinition de *error*, pour fermer le groupe et annuler tout ce qui a été fait depuis son ouverture (ce qui devrait ausssi marcher pour les SCU).

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

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é