Fraid Posté(e) le 4 janvier 2011 Posté(e) le 4 janvier 2011 Bonjour, J'essaie d'agir dans les blocs et en meme temps apprendre le VLA. Comme exercice je tente d'exploser tout les MTEXT's contenus dans les blocspour les transformer en texte simple. je pensais pouvoir y arriver comme cela (defun c:ExplodeMtextInBlocks (/ AcDoc bloc mt) (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-for bloc (vla-get-Blocks AcDoc) (vlax-for mt bloc (if (= "AcDbMText" (vla-get-ObjectName mt)) (vl-cmdf "_explode" mt) ) ) ) (vla-regen AcDoc acActiveViewport) (princ) ) mais, Horreur (pour la rime ;) )j'obtient cette Erreur ; erreur: type de données incorrect ou dépassement de données: #IAcadMText 00000000412b4188> https://github.com/Fraiddd
(gile) Posté(e) le 4 janvier 2011 Posté(e) le 4 janvier 2011 Salut, Il faut bien comprendre que Visual LISP (ou vla) est une technique pour accéder en LISP à l'environnement COM/ActiveX Automation.Les 'objets' acquis dans cet environnement sont d'un type différent de ceux acquis avec AutoLISP, les premiers sont de type VLA-OBJECT, le seconds de type ENAME. Quand tu parcours la collection de blocs avec vlax-for chaque objet (définition de bloc) est de type VLA-OBJECT. Puis quand tu parcours les composants de chaque blocs, toujours avec vlax-for, chaque entité est aussi de type VLA-OBJECT.En faisant la même chose avec tblnext et entnext, on obtient les composant avec le type ENAME. Il est possible de convertir le type de l'objet avec les fonctions vlax-vla-object->ename et vlax-ename->vla-object Avec la fonction command les entités doivent être spécifiées sous la forme de ENAME (ou de jeu de sélection comme acquis avec ssget). Il faut donc que tu fasses :(if (= "AcDbMText" (vla-get-ObjectName mt)) (vl-cmdf "_explode" (vlax-vla-object->ename mt)) ) Autre chose, quand tu fait (vlax-for bloc (vla-get-Blocks AcDoc) ...) tu parcours la collection des blocs 'au sens large', à savoir, espaces objet et papier compris qui sont aussi considérés comme des 'définitions de bloc'. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
VDH-Bruno Posté(e) le 4 janvier 2011 Posté(e) le 4 janvier 2011 Bonsoir, Comme toi Fraid, je songe de plus en plus à m’intéresser à l’environnement COM/ActiveX Automation, au regard de certains codes que je vois circuler et qui me sont encore inaccessible (au passage j’en profite pour te remercier pour ton aide sur setenv & getenv). Mais quant je lis la réponse de (gile), je me dis que je vais consolider un peu encore mes connaissance en Lisp, et en attendant collectionner les sujets comme celui-ci concernant ce thème car le palier ne me semble pas évident à franchir.. Cela va demander un gros investissement personnel et des heures de sommeil en moins.. (surtout que l’aide fr de la R14 ne contient pas ces chapitres), pour assimiler une philosophie qui me semble complètement différente de celle déjà entrevu.. Bon courage à toi Apprendre => Prendre => Rendre
Fraid Posté(e) le 4 janvier 2011 Auteur Posté(e) le 4 janvier 2011 Merci Bruno pour tes encouragements J'ai décidé de consacrer plus de temps au développement Jusqu'a maintenant c'etait trés sporadique (le temps de regonfler les roues de la charette)Du coup j'oubliais trés vite :P Ayant sous le nez beaucoup de code en VLA, il fallait bien que j'osasse le faire :casstet: Merci (gile) pour ces éclaircicementMais j'avais cherché avec vlax-vla-object->enameque j'ai eu un mal de chien a trouvé dans l'aideet j'obtient ce message d'erreur du meme genre _explode Je commence a comprendre l'environement COMEt le fait de travailler sur des collections entiere me motive.Et surtout qu'ici on n'est est a bonne école ;) https://github.com/Fraiddd
(gile) Posté(e) le 4 janvier 2011 Posté(e) le 4 janvier 2011 Fraid, Je ne comprends pas pourquoi tu as ce message, ça marche très bien chez moi. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 4 janvier 2011 Auteur Posté(e) le 4 janvier 2011 Et ce n'est pas la premiere fois que j'ai des problemes a l'interieur des blocs je n'arrive toujours pas a remplacer un simple texte... que ce soit en Autolisp simple ou avec du VLA je soupsonne une variable coquine dérriere cela... https://github.com/Fraiddd
Fraid Posté(e) le 5 janvier 2011 Auteur Posté(e) le 5 janvier 2011 Je viens de passer 2 heures a parcourir l'ensemble des variablesje n'ai rien vu qui pourrai bloquer l'edition de texte dans les blocs je vous joint un test http://up.ahst.fr/?f=igkr31 sa marche chez vous? https://github.com/Fraiddd
bonuscad Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 sa marche chez vous? Non, la même erreur que toi... Par contre j'ai modifié simplement la ligne suivante comme ceci (en mettant l'ename en liste), et là ça fonctionne. (vl-cmdf "_.explode" (list (vlax-vla-object->ename mt))) Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
(gile) Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 Toutes mes excuses, je n'avais pas testé dans une définition de bloc. Comme la fonction vla-Explode n'est pas utilisable avec les textes multiligne, je te propose une petite entourloupe consistant à insérer le bloc contenant des mtextes en 0,0 et le décomposer. Puis, décomposer les mtextes résultant de la décomposition du bloc pour récupérer les textes simples et les copier dans la définition dans laquelle on supprime les mtextes. (defun c:ExplodeMtextInBlocks (/ explodeNestedMtext hasMt) (vl-load-com) (or *acad* (setq *acad* (vlax-get-acad-object))) (or *acdoc* (setq *acdoc* (vla-getActiveDocument *acad*))) (or *blocks* (setq *blocks* (vla-get-Blocks *acdoc*))) ;; sous-routine locale (defun explodeNestedMtext (blk / name ref expl lst) (setq name (vla-get-Name blk)) (vla-put-Explodable blk :vlax-true) ;; insérer le bloc en 0,0 (setq ref (vla-InsertBlock (vla-get-ModelSpace *acdoc*) (vlax-3d-point '(0. 0. 0.)) name 1. 1. 1. 0. ) ) ;; décomposer la référence (setq expl (vlax-invoke ref 'Explode)) ;; pour chaque entité résultante, décomposer si c'est un mtext et ajouter le texte à lst (foreach o expl (if (= (vla-get-ObjectName o) "AcDbMText") (progn (vl-cmdf "_.explode" (vlax-vla-object->ename o)) (setq txt (vlax-ename->vla-object (entlast)) expl (cons txt (vl-remove o expl)) lst (cons txt lst) ) ) ) ) ;; supprimer tous les mtextes de la définition (vlax-for o blk (if (= (vla-get-ObjectName o) "AcDbMText") (vla-delete o) ) ) ;; copier les textes dans la définition (vlax-invoke *acdoc* 'CopyObjects lst (vla-Add *blocks* (vlax-3d-point '(0. 0. 0.)) name) ) ;; supprimer la référence et les entités résultant de la décomposition (mapcar 'vla-Delete (cons ref expl)) ) ;; routine principale (vlax-for bloc *blocks* (if (= (vla-get-IsLayout bloc) :vlax-true) ;; traitement des mtextes dans les espaces objet et papier (vlax-for mt bloc (if (= "AcDbMText" (vla-get-ObjectName mt)) (vl-cmdf "_.explode" (vlax-vla-object->ename mt)) ) ) ;; traitement des mtextes dans les blocs (progn (setq hasMt nil) (vlax-for mt bloc (if (= "AcDbMText" (vla-get-ObjectName mt)) (setq hasMt T) ) ) (if hasMt (explodeNestedMtext bloc) ) ) ) ) (princ) ) EDIT : je n'avais pas vu la réponse de Bonuscad, beaucoup plus simple.On dira que le code ci-dessus, peut servir d'exemple d'utilisation de vlax-invoke ... 'explode (récupération de la liste des objets résultants) et de vlax-invoke ... CopyObjects (deep cloning). Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 5 janvier 2011 Auteur Posté(e) le 5 janvier 2011 Merci a tout les 2 BonuscadJe pensais que la variable mt était déjà une listeEn tout cas, si elle l'est, elle ne se présente pas de la bonne manière :exclam: par contre cela ne fonctionne toujours pas ERREUR d'application: Liste entité/point incorrecte.Régénération du modèle. (gile)je ne m'attendais pas a devoir tourner du c_l pour réaliser une chose aussi "simple"Trés formateur ton code!J'aime beaucoup la partie qui colle un objet dans une définition de bloc ;) En plus sa marche https://github.com/Fraiddd
Fraid Posté(e) le 5 janvier 2011 Auteur Posté(e) le 5 janvier 2011 Premiere question Pourquoi les variables servant à récupérer les collections (*acad*) sont elles globales et est ce obligatoire? 2) Pourquoi la Fonction explodeNestedMtext est elle déclaré comme une variable locale? Merci PS: tu as oublié un tiré entre get et ActiveDocument ligne 4 https://github.com/Fraiddd
(gile) Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 Pourquoi les variables servant à récupérer les collections (*acad*) sont elles globales et est ce obligatoire? Ce n'est pas obligatoire, c'est juste une habitude. Chez moi, ces variables et quelques autres (*layers*, *utility*, ...) sont initialisées dans chaque nouveau document, ça permet d'écrire rapidement des expressions pour les tester. Il faut juste que je n'oublie pas d'ajouter ces initialisations quand je publie un code*.L'avantage ne réside pas uniquement dans le fait qu'elles soient globales, mais aussi dans l'expression (or ...) qui évite d'évaluer la suivante et de créer une nouvelle instance de ces objets. Pourquoi la Fonction explodeNestedMtext est elle déclaré comme une variable locale? Là non plus, rien d'obligatoire, mais quand une fonction ne sert pas ailleurs que dans une la fonction qui l'appelle, la déclarer localement est un moyen d'éviter les conflits au cas où une autre définition de fonction aurait le même nom. *C'est aussi pour ça que je ne me suis pas rendu compte de la faute dans "vla-getActiveDocument". Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
bonuscad Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 par contre cela ne fonctionne toujours pas Exact ! :( L'explication de ma suggestion foireuse... Je sais que explode attend une liste de la même forme que pourrait retourner (entsel) -> liste de ename et point de sélection. Donc dans mon essai de déboguage j'avais essayé:(vl-cmdf "_.explode" (list (vlax-vla-object->ename mt) (getpoint)))J'ai donc sélectionné le Mtext durant le déroulement du code et cela à fonctionné. J'ai donc enlever le (getpoint) fais un U dans le dessin (certainement mon erreur, car la liste à du être conservé en mémoire), rechargé le code et retenté et cela à fonctionné. En refaisant le test ce soir effectivement cela ne fonctionne pas. Et là je me rend compte qu'il n'est pas évident d'obtenir un tel point sans sélection manuelle pour corriger ton code, pourtant la solution simple pour explode serait bien celle ci. Désolé. Choisissez un travail que vous aimez et vous n'aurez pas à travailler un seul jour de votre vie. - Confucius
(gile) Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 Et là je me rend compte qu'il n'est pas évident d'obtenir un tel point sans sélection manuelle pour corriger ton code, pourtant la solution simple pour explode serait bien celle ci. D'un autre côté, je crains qu'on ne puisse invoquer les commandes (via command ou vl-cmdf) que dans l'éditeur (espace objet ou papier) et que ça ne soit pas possible à l'intérieur d'une définition de bloc. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 5 janvier 2011 Auteur Posté(e) le 5 janvier 2011 C'est ce que j'aime dans le lispC'est l'aventureJamais rien de certainToujours en expérimentation Je me suis donc penché sur vlax-invokequi, soit dit en passant a l'air plutôt obsolète et remplacée par vlax-invoke-method Y a t'il une liste des méthodes et leur argumentscar je n'ai rien trouvé dans l'aide. Faut il pour cela parcourir les ressources dans Visual Studio?Ou faire une sorte de dump? :casstet: Si cela ce trouve c'est devant mon nez :P https://github.com/Fraiddd
(gile) Posté(e) le 5 janvier 2011 Posté(e) le 5 janvier 2011 Je me suis donc penché sur vlax-invokequi, soit dit en passant a l'air plutôt obsolète et remplacée par vlax-invoke-method vlax-invoke (comme vlax-get et vlax-put) n'est toujours pas encore obsolète et présente, à mon avis un avantage sur vlax-invoke-method (ou vla-*) c'est qu'il prend et/ou retourne des listes LISP au lieu de variants.Voir ce sujet Y a t'il une liste des méthodes et leur argumentscar je n'ai rien trouvé dans l'aide. Les objets, propriétés et méthodes COM se trouvent dans la rubrique ActiveX and VBA Reference de l'aide aux développeurs jusqu'à la version 2010 (elle ont disparues de la calamiteuse aide 2011)*.Il faut adapter la syntaxe VBA à Visual LISP, mais ce n'est pas bien difficile.En général on ajoute vla- pour les méthodes et vla-get- ou vla-put- pour les propriétés et on passe en premier argument l'objet auquel s'applique la méthode ou la propriété (ou vlax-invoke(-method), vlax-get(-property), vlax-put(-property), puis l'objet, puis la méthode ou la propriété, puis les éventuels arguments).Les fonction vlax-* sont renseignées dans AutoLISP Reference. * Je me suis mis un raccourci sur mon bureau qui pointe vers le dossier d'aide de 2010 pour pouvoir l'utiliser avec 2011. Si tu n'as plus de versions d'AutoCAD antérieures à 2011, je peux t'envoyer ce dossier. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Fraid Posté(e) le 5 janvier 2011 Auteur Posté(e) le 5 janvier 2011 je pensais bien que c'etait devant moi je te remercie mais j'ai une collection d'aide assez bien fournie c'est dans l'Autolisp reference de 2004 This function was known as vlax-invoke prior to AutoCAD 2000. Je me sert de 2011 que depuis 1 semaine (je n'avais pas eu le temps de l'installer) et c'est vrais que leur aide sur le net est LAMENTABLE sinon j'utilise de moins en moins les raccourcis sur le bureau J'utilise un logiciel d'arbres heuristiques Freemind http://www.01net.com/telecharger/windows/Loisirs/education_et_scolarite/fiches/34923.html qui permet d'accedé a tes documents tout aussi facilementje le conseil, je le trouve terriblecela permet de mettre a plat toute sorte de projetet quand on a le cerveau qui coule par les oreilles, c'est bien pratique. En tout cas je te remercie encore pour cette leçon a bientot https://github.com/Fraiddd
Messages recommandés
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 compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant