
BTO
Membres-
Compteur de contenus
38 -
Inscription
-
Dernière visite
Tout ce qui a été posté par BTO
-
bonjour, Le chemin du fichier existe-t-il ? S'il n'existe pas alors il faut le créer avant de tenter la sauvegarde, sinon autocad proposera d'enregistrer dans son dossier de travail par. On peut vérifier son existence de plusieurs manières, en voici 2 : (findfile (vl-filename-directory NomeFile)) (vl-file-directory-p (strcat (vl-filename-directory NomeFile) "\\")) Bruno Toniutti
-
Bonjour, je voudrais effacer ce message, merci Bruno Toniutti [Edité le 26/2/2007 par BTO]
-
:o Je viens de le revérifier sur map 3D 2007 (il me semble que c'est apparu avec autocad 2004) (setq objName (vlax-ename->vla-object (setq ename (car (entsel))))) (vla-explode objName) A moins que quelque chose de nouveau m'ait échappé, malheureusement la méthode explode est bugguée et ne fonctionne pas sur les blocs avec une échelle non uniforme (on obtient même une erreur). Bruno Toniutti [Edité le 23/2/2007 par BTO]
-
Simplification code CHEKSUM d\'un DWG
BTO a répondu à un(e) sujet de stephan35 dans Pour aller plus loin en LISP
bonjour en complément, on peut aussi explorer une autre voie, accéder à un fichier via FileSystemObject pour récupérer une multitude d'informations. le principe général : (setq filePath (getfiled "Sélection d'un fichier" "" "" 0)) (setq objWsh (vlax-create-object "Scripting.FileSystemObject")) (setq objFile (vlax-invoke-method objWsh 'GetFile filePath)) (vlax-get objFile 'Attributes) (vlax-get objFile 'DateCreated) (vlax-get objFile 'DateLastAccessed) (vlax-get objFile 'DateLastModified) (vlax-get objFile 'Drive) (vlax-get objFile 'Name) (vlax-get objFile 'ParentFolder) (vlax-get objFile 'Path) (vlax-get objFile 'ShortName) (vlax-get objFile 'ShortPath) (vlax-get objFile 'Size) (vlax-get objFile 'Type) Bruno Toniutti -
Patrick, Si tu parles de l'expression diesel (et non de son résultat à l'écran) c'est le code 1 d'un rtext donc le principe général est : (cdr (assoc 1 (entget (car (entsel))))) Bruno Toniutti [Edité le 14/2/2007 par BTO]
-
bonjour à tous oui ça fonctionne, mais comme c'est l'objet du forum, je vais continuer dans le coté pinaillement :) a) (ssget "_X" '((0 . "*TEXT"))) retourne nil si aucun texte n'est trouvé => ssnamex plante. je ne pense pas qu'on puisse s'affranchir d'une structure classique de sélection : (if (setq ss (ssget "_X" '((0 . "*TEXT")))) ...... b) De manière générale, la fonction mapcar exécute une fonction sur chacun des éléments d'une liste et retourne une liste de même longueur, ce qui veut dire qu'après un mapcar on a en mémoire 2 listes. Même l'écriture : (setq listA (mapcar 'fonction listA)) ocuppe l'espace de 2 listA en mémoire puisque la réaffection à listA de la liste retournée par mapcar intervient après la création de la liste de retour de mapcar. Une liste issue d'une sélection sur l'ensemble d'un dessin peut être très grande (ne considérons plus ce cas particulier des textes à effacer) 10000, 100 000, 1 000 000 d'éléments ? dans une structure : (mapcar 'entdel (mapcar 'cadr (ssnamex (ssget "_X" '((0 . "*TEXT")))) ) ) on a en mémoire : 1 jeu de sélectoin complet 1 liste compléte pour ssnamex 1 liste compléte pour le premier mapcar 1 liste compléte pour le second mapcar la première raison d'être d'un mapcar est de récupérer une liste après le balayage d'une liste, or ici l'objet du balayage de la liste n'est pas de récupérer une liste mais simplement de la parcourir. Donc, on peut au moins fusionner les 2 mapcar via une fonction lambda ou utiliser des structures classiques : (repeat (sslength ss) ..... ) (surtout pas de while qui oblige à un test non justifié quand le nombre de répétitions d'une boucle est connu) oui je sais, c'est moins beau que des mapcars enchainés les uns dans les autres ;) Bruno Toniutti[Edité le 14/2/2007 par BTO] [Edité le 20/2/2007 par BTO]
-
Patrick, des boucles qui contruisent des listes de plus 1000 élèments et plus, il y en a plein :) et quand bien même l'ordre des éléments serait important (ce qui de plus, souvent n'est pas le cas, dont le notre de modification de la couleur), le reverse est négligeable. par exemple : (defun methode1 () (setq a "a" l nil) (repeat 1000 (setq l (cons a l)) ) (reverse l) ) (defun methode2 () (setq a "a" l nil) (repeat 1000 (setq l (append l (list a))) ) ) donne : (METHODE1)......1062 / 59.9 - fastest (METHODE2).....63609 / 1 - slowest pour des listes de 10 éléments l'écart est faible : (METHODE1).....1016 / 1.17 -fastest (METHODE2).....1187 / 1 slowest mais pour des listes de 100 éléments on a déjà des écarts significatifs : (METHODE1).....1219 / 5.68 (METHODE2).....6922 / 1 une lwpolyligne de seulement 2 sommets, correspond à une liste de 23 éléments. Bref c'est juste histoire de discuter du lisp, les cas pour lesquels ça n'a aucune influence sont nombreux, cependant parfois ça peut être critique. Edit 1 : comme tu le précises avec entmake l'ordre de la liste a son importance, mais entmod semble s'accommoder d'un cons. Bruno Toniutti [Edité le 8/2/2007 par BTO]
-
bonjour :) Gile, en fait la manière utilisée dans ton test n'est pas représentative du décalage entre un cons et un append, plus la liste est grande plus l'écart est important. De manière génèrale quand on contruit une liste au cours d'une boucle (ce n'est pas notre cas dans la question initiale, mais autant avoir la solution la plus efficace), au fur et à mesure que la liste grandi, l'écart s'accentue. Un append mal placé peut même rendre un lisp inexploitable. Exemple (defun methode1 () (setq a "a" l nil) (repeat 1000 (setq l (cons a l)) ) ) (defun methode2 () (setq a "a" l nil) (repeat 1000 (setq l (append (list a) l)) ) ) on obtient : Benchmarking ..............Elapsed milliseconds / relative speed for 2048 iteration(s): (METHODE1).......1969 / 56.41 - fastest (METHODE2).....111062 / 1 - slowest ce qui est énorme ;) Bruno Toniutti [Edité le 8/2/2007 par BTO]
-
bonjour, pour aller un peu plus loin un append est beaucoup plus lent qu'un cons, or de manière générale c'est toujours à éviter dans la manipulation des listes. ici je ne vois pas de raison particulière d'utiliser un append, sinon merci de le précisier :yltype: Il me semble préfèrable d'utiliser une écriture de la forme : (setq elst (cons (cons 62 Nouvelle_Couleur) elst)) Bruno Toniutti
-
Bonjour Patrick, pour effectuer un traitement par lot (en ouvrant les fichiers dans AutoCAD) le principe le plus utilisé est le suivant : - créer un script qui sera répété sur chaque fichier, ça peut être : [b] exemple 1 :[/b] (if (= 0 (getvar "tilemode")) (command "espacep")) zoom _e purger to n [b] exemple 2 :[/b] ssx E wipeout _erase _p (load "DeleteBlockWipeouts.lsp") DeleteBlockWipeouts Tu remarques que finalement le fait de passer par un script n'est pas génant puisqu'on peut faire appel à tout ce qu'on veut via un (load....) - créer un moteur.lsp dont les taches sont : * établir la liste des fichiers à traiter * sélection du script1(voir au dessus) à répéter * création d'un megascript.scr de la forme suivante : ouverture du fichier1.dwg exécution de script1 save fichier1.dwg ouverture du fichier2.dwg exécution de script1 save fichier2.dwg etc. ça donne par exemple pour megascript.scr : _qnew _open "D:/_traitement/5eme.dwg" (if (= 0 (getvar "tilemode")) (command "espacep")) zoom _e purger to n _qsave _open "D:/_traitement/coupe AA.dwg" (if (= 0 (getvar "tilemode")) (command "espacep")) zoom _e purger to n _qsave _open "D:/_traitement/etage courant.dwg" (if (= 0 (getvar "tilemode")) (command "espacep")) zoom _e purger to ... .... .. _qnew filedia 1 cmdecho 1 et enfin ton moteur.lsp devra finir par le lancement de l'exécution megascript.scr. C'est plus impressionant que compliqué, et ce message et plus long que le moteur.lsp à créer mais dsl je ne peux pas diffuser ma version. Pour ce qui est des quelques lsp que je charge au début ( très peu car je préfère faire un (load... dans mes menus), je les place dans les fichiers .mnl de mes menus personnalisés, on peut en créer un par .cui et c'est fait pour :) Bruno Toniutti [Edité le 2/2/2007 par BTO]
-
Bonjour, pour vérifier qu'un etat des calques particulier est présent : par exemple (checkLayerStateName "toto") en vlisp : ; bto 1.070201 (defun checkLayerStateName (LayersStateName / objXdict return) (setq objXdict (vla-GetExtensionDictionary (vla-get-Layers (vla-get-activedocument (vlax-get-acad-object))))) (setq return (not (vl-catch-all-error-p (vl-catch-all-apply '(lambda () (vla-item (vla-Item objXDict "ACAD_LAYERSTATES") LayersStateName)))))) (vlax-release-object objXdict) return ) voila, ça devrait fonctionner Bruno Toniutti [Edité le 1/2/2007 par BTO]
-
ok, parce que je cherchais la différence avec : (if (findfile item) Il doit pas te manquer grand chose, a prioris tu as tout ce qui nécessaire. Des fois il faut laisser reposer, ça ira mieux demain ;) BTO
-
A quoi sert cette partie ? Bruno Toniutti
-
ça ne correspond toujours pas à ce que je diffuse !! Je n'ai pas envi que mes variables contenant l'expression "m a i l " (sans espaces entres les lettres) soit remplacées par "courriel". Résultat la fonction correspondant au defun est fausse ! Bruno Toniutti[Edité le 2/10/2006 par BTO] [Edité le 2/10/2006 par BTO]
-
la version affichée sur le site ne correspond pas à celle que j'ai diffusée !! voici un nouveau message avec les tags du site pour le code : (defun CreateMail (RecipientTxt SubjectTxt MessageTxt PathFileTxt / OutlookObj EmailObj) (setq OutlookObj (vlax-get-or-create-object "Outlook.Application")) (setq EmailObj (vlax-invoke-method OutlookObj 'CreateItem 0)) (vlax-put-property EmailObj 'Body MessageTxt) (vlax-put-property EmailObj 'Subject SubjectTxt) (vlax-put-property EmailObj 'to RecipientTxt) (vlax-invoke-method (vlax-get-property EmailObj 'Attachments) 'Add PathFileTxt) (vlax-invoke-method EmailObj 'Display 1) (mapcar 'vlax-release-object (list OutlookObj EmailObj)) (gc) (princ) ) ; utilisation (CreateMail "toto@fai.fr" "essai" "\ntexte\ndu\nmessage\n" "D:\\_traitement\\toto.txt") Pour Tramber : je ne sais pas d'où vient ton problème mais "c:ab.txt" ça ne fonctionne pas en lisp, tente avec : "c:\\ab.txt" ou "c:/ab.txt" Pour Patrick35 : oui c'est spécifique à outlook et je ne suis pas sur que ça fonctionne avec toutes les versions (en particulier avec la version express) Bruno Toniutti [Edité le 2/10/2006 par BTO]
-
voila ce que j'utilise : ; 1.061001 Bruno Toniutti (defun CreateMail (RecipientTxt SubjectTxt MessageTxt PathFileTxt / OutlookObj EmailObj) (setq OutlookObj (vlax-get-or-create-object "Outlook.Application")) (setq EmailObj (vlax-invoke-method OutlookObj 'CreateItem 0)) (vlax-put-property EmailObj 'Body MessageTxt) (vlax-put-property EmailObj 'Subject SubjectTxt) (vlax-put-property EmailObj 'to RecipientTxt) (vlax-invoke-method (vlax-get-property EmailObj 'Attachments) 'Add PathFileTxt) (vlax-invoke-method EmailObj 'Display 1) (mapcar 'vlax-release-object (list OutlookObj EmailObj)) (gc) (princ) ) utilisation : (CreateMail "toto@fai.fr" "essai" "\ntexte\ndu\nmessage\n" "D:\\_traitement\\toto.txt") Bruno Toniutti
-
Salut , la méthode la plus simple depuis AutoCAD, c'est d'utiliser la commande mailto: qui est intégré à windows : (command "start" "mailto:toto@fai.fr?cc=totobis@fai.us?subject=Salut?body=C'est%20un%20test") donnée par Dave Fitz Patrick sur customization par contre on ne peut pas joindre un fichier. Bruno Toniutti
-
superbe lien ! avec une excellente ergonomie, tout est regroupé...ça donnent des idées, merci. Très bonnes vacances également. Bruno Toniutti
-
J’aurais mieux fait de me taire, depuis hier j'ai un intérêt à la question sur l'accès au spool, par contre en dehors du coté sportif, je ne pense pas qu'il y est vraiment d'intérêt à le faire via du lisp. Ca sera pour la rentrée, ce soir se sont les vacances ;) . Bruno Toniutti
-
bonjour, ça dépend ou se trouve le spooler (sur ta machine ? ou c'est une machine dédiée ? et ça dépend de tes droits dans ce cas). de mémoire : Il faut regarder du coté de WMI et s'intéresser à des objet comme WbemScripting.SWbemLocator (voir tout ça avec google et sur le site de Microsoft) Je pense que l'accés au spooler se fait également par WMI, mais je n'ai pas le temps (et l'intêret) de regarder dans le détail. Pour se faire une idée, l'incontounable : Tony Tanzillo sur http://www.caddzone.com/wmi.lsp et une application directe de Jeff Mishler : ; Jeff Mishler ;;Example to close all Notepad applications (killApp "Notepad.exe") ;|Function that use the WMI to terminate ALL running instances of a particlar Application. Thanks to Tony Tanzillo for the sample code to utilize the WMI. Note that no attempt to save any open document(s) is made. by Jeff Mishler, January 2006 |; (defun killApp (appName / Server processList) (setq Server (vlax-invoke-method (vlax-create-object "WbemScripting.SWbemLocator") 'ConnectServer nil nil nil nil nil nil nil nil ) ) (setq processList (vlax-invoke Server 'ExecQuery (strcat "Select * from Win32_Process Where Name = '" appName "'"))) (vlax-for app processList (vlax-invoke app 'Terminate) ) (vlax-release-object Server) ) Bruno Toniutti [Edité le 8/8/2006 par BTO]
-
Bonjour, J’utilise régulièrement cette technologie car elle permet de faire à peu prés ce qu'on veut, Un fichier d'aide existe : chercher Script56.CHM avec google, il doit être disponible sur le site de Microsoft. A ma connaissance c'est Tony Tanzillo avec sa routine BrowseForFolder (voir son site) qui a popularisé cette technologie et effectivement Jeff Mishler (et d'autres) en fait un usage intensif. voici un exemple d'une utilisation (qui est une partie d'un ensemble de routines, donc seule elle n'a pas de sens) Bruno Toniutti ;FONCTION : copie un fichier avec respect de : ; la date d'origine du fichier copier ; controle des status lecture seule et/ou en cours d'édition du fichier destination ; identification de la session pour un fichier en cours d'édition ; ;LANCEMENT PAR : (CopyFileServer source target) ; ;PROPRIETE : BERIM ; ;REALISATION : Bruno TONIUTTI BTO Responsable CAO DAO ; ;VERSION : 1.051109 première version ; 1.051110 ajout de l'identification de la session pour un fichier en cours d'édition ; 1.051114 utilisation de vl-filename-base (débugué avec la 2006) ; 1.051115 correction de la construction du fichier dwl ; +optimisation mineure ; ;REMARQUE : 1.051115 testée sous AutoCAD MAP 3D 2006 Win XP Pro sp2 ; L'identification des sessions fonctionne aussi avec AutoCAD LT 2005 2006 ; Du fait de l'usage de vl-filename-base, nécessite AutoCAD >= 2006 pour être OK avec fichier terminé par " .dwg" ; ;-------------------------------------------------------------------------------------------------------------- (defun CopyFileServer (oldPathFileName newPathFileName / catch idDwl dwl objWsh objFile idFile success message) (setq success nil) (if (findfile oldPathFileName) (progn (setq objWsh (vlax-create-object "Scripting.FileSystemObject")) (if (findfile newPathFileName) (if (setq idFile (open newPathFileName "a")) (progn (close idFile) (vlax-invoke-method objWsh 'CopyFile oldPathFileName newPathFileName :vlax-true) (setq message "copy is OK") (setq success T) ) (progn (setq objFile (vlax-invoke-method objWsh 'GetFile newPathFileName)) (if (eq 1 (logand 1 (vlax-get objFile 'Attributes))) (setq message "target file is read only") (progn (setq dwl (strcat path_job "\\" (vl-filename-base newPathFileName) ".dwl")) (if (findfile dwl) (progn (setq idDwl (open dwl "r")) (setq message (strcat "target file is open by " (read-line idDwl))) (close idDwl) ) (setq message "target file is opened by unknown user") ) ) ) (vlax-release-object objFile) ) ) (progn (vlax-invoke-method objWsh 'CopyFile oldPathFileName newPathFileName :vlax-true) (setq message "copy is OK") (setq success T) ) ) (vlax-release-object objWsh) ) (setq message "source file not found") ) (mapcar '(lambda (x) (set x nil)) '(catch oldPathFileName newPathFileName idDwl dwl objWsh objFile idFile)) (list success message) )
-
Bonjour Gile, je viens de m'intéresser à ta suggestion. De manière générale le fait d'utiliser (sssetfirst) avant (sssetfirst nil ss) a une grande incidence si le nombre initial d'entités avec grip est important (plusieurs milliers). Pour chaque entité, on peut aussi supprimer un if et un member, puisqu’on retranche toutes les entités de ssf à ssa. Finalement en partant de ton travail j'arrive à : (defun c:inv_sel2 (/ ssa ssf n) (setq ssa (ssget "_A" (list (cons 410 (getvar "ctab"))))) (if (setq ssf (cadr (ssgetfirst))) (repeat (setq n (sslength ssf)) (ssdel (ssname ssf (setq n (1- n))) ssa) ) ) (sssetfirst) (sssetfirst nil ssa) ) Cordialement, Bruno Toniutti
-
Patrick, maintenant que tu le précises, cela est particulier puisque ça porte sur un reactor qui réagit au niveau de sous-entités, je n'ai jamais programmer cela. Par contre voici, une réponse de Luis Esquivel : http://discussion.autodesk.com/thread.jspa?messageID=4781038 Reply From: Luis Esquivel Date: Mar/24/05 - 15:33 (GMT) Peut être que cela te permettra de trouver une solution à ton code. Bruno Toniutti, ce soir en vacances. [Edité le 19/5/2006 par BTO]
-
bonjour, on peut aussi obtenir directement un résultat exploitable avec : (vlax-get vla-object 'coordinates) exemple : (setq ename (car (entsel "Sélectionnez une lwpolyligne: "))) (vlax-get (vlax-ename->vla-object ename) 'coordinates) le retour est de la forme : (143.074 221.014 95.5496 226.048 93.976 110.591 185.247 136.703 ........) ensuite on peut formater aisément cette liste de sommets comme on le souhaite. Bruno Toniutti [Edité le 19/5/2006 par BTO] [Edité le 19/5/2006 par BTO]
-
Bonjour, Dans quelle proportion l'objet est-il modifié ? L'objet modifié doit rester compatible avec le reactor initiale (plutôt la fonction callback initiale), est-ce le cas ? Comment as-tu procédé ? en réaffectant la même fonction callback ? ( Eventuellement similaire sous un autre nom ) normalement ça ne devrait pas être le cas. Bruno Toniutti.