Aller au contenu

Super purge


Fraid

Messages recommandés

Salut,

 

J'ai compilé les bouts de codes du lien donné par sergeluc pour en faire une fonction : purge_xref.

 

La fonction crée une liste de toutes les xrefs du dessin (même les xrefs imbriquées) puis teste la validité du chemin et détache celles dont le chemin n'est pas valide.

 

Elle est définie avec un (defun c: ...) et peut donc être appelée à la ligne de commande en tapant purge_xref, elle peut aussi être appelée depuis un autre LISP (puisque tu dis vouloir l'intégrer) avec un (c:purge_xref).

 

Attention tout de même, je nai pas fait de tests approfondis.

 

Versions modifiées, ajout de contrôles et d'un message pour chaque xref ou raster supprimé.

 

;;; PURGE_XREF Détache toutes les xrefs du dessin dont le chemin n'est pas valide

(defun c:purge_xref
      (/ AcDoc n lay l_lst ss obj lst n_lst name bloc ent)

 ;; Chargement des fonctions ActiveX

 (vl-load-com)

 ;; AcDoc : pointeur vers le document actif

 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))

 ;; Dévérouillage de tous les calques

 (repeat (setq n (vla-get-count (vla-get-Layers AcDoc)))
   (setq lay (vla-item (vla-get-Layers AcDoc) (setq n (1- n))))
   (if	(= :vlax-true
   (vla-get-lock lay)
)
     (progn
(vla-put-lock lay :vlax-false)
(setq l_lst (cons lay l_lst))
     )
   )
 )

 ;; ss : sélection de tous les blocs et Xrefs insérés sur les calques dévérouillés

 (setq ss (ssget "_X" '((0 . "INSERT"))))

 ;; On parcourt le jeu de sélection pour constituer une liste (lst)
 ;; avec seulement les noms des Xrefs

 (if ss
   (progn
     (repeat (setq n (sslength ss))
(setq
  obj (vlax-ename->vla-object (ssname ss (setq n (1- n))))
)
(if
  (and
    (not (member (vla-get-name obj) lst)) ;_ éviter les doublons
    (= :vlax-true ;_ uniquement les Xrefs
       (vla-get-isXref
	 (vla-item (vla-get-Blocks AcDoc) (vla-get-Name obj))
       )
    )
  )
   (setq lst
	  (cons
	    (vla-get-name obj)
	    lst
	  )
   )
)
     )

     ;; On parcourt la liste lst et pour chaque Xref, on cherche si
     ;; dans ces composants il y a une (ou des) Xref. Si ces le cas,
     ;; elles sont rajoutées en fin de liste et seront traitées à leur tour.

     (setq n_lst 0)
     (if lst
(while (setq name (nth n_lst lst))
  (setq bloc (vla-item (vla-get-blocks acDoc) name))
  (repeat (setq n (vla-get-count bloc)) ;_ nombre de composant du bloc (Xref)
    (setq ent (vla-item bloc (setq n (1- n))))
    (if	(and (= (vla-get-ObjectName ent) "AcDbBlockReference") ;_ si le composant est un bloc
	     (not (member (vla-get-name ent) lst)) ;_ s'il n'est pas déjà dans la liste
	     (=	:vlax-true ;_ si c'est une Xref
		(vla-get-isXref
		  (vla-item (vla-get-Blocks AcDoc)
			    (vla-get-Name ent)
		  )
		)
	     )
	)
      (setq
	lst (reverse (cons (vla-get-Name ent) (reverse lst))) ;_ la Xref est ajoutée en fin de liste
      )
    )
  )
  (setq n_lst (1+ n_lst))
)
     )
   )
 )

 ;; On parcourt la liste et on teste, pour chaque xref, si le chemin est valide
 ;; Si le chemin n'est pas valide la xref est détachée

 (mapcar '(lambda (x)
     (setq path (vla-get-Path (vla-item (vla-get-blocks acdoc) x)))
     (if (not (open path "r"))
       (progn
	 (princ (strcat "\Suppression de la xref : " x))
	 (vla-detach (vla-item (vla-get-Blocks AcDoc) x))
       )
     )
   )
  lst
 )

 ;; Restauration de l'état des calques

 (if l_lst
   (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    l_lst
   )
 )
 (princ)
)

 

Dans le même esprit pour les images raster :

 

;;; PURGE_RASTER Supprime toutes les images raster du dessin dont le chemin n'est pas valide

(defun c:purge_raster (/ AcDoc n lay l_lst ss img pat)
 (vl-load-com)
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))

 ;; Dévérouillage de tous les calques
 
 (repeat (setq n (vla-get-count (vla-get-Layers AcDoc)))
   (setq lay (vla-item (vla-get-Layers AcDoc) (setq n (1- n))))
   (if	(= :vlax-true
   (vla-get-lock lay)
)
     (progn
(vla-put-lock lay :vlax-false)
(setq l_lst (cons lay l_lst))
     )
   )
 )

 ;; Sélection de toutes les images raster
 
 (setq ss (ssget "_X" '((0 . "IMAGE"))))
 
 ;; Suppression de celles qui ne sont pas référencées
 
 (if ss
   (repeat (setq n (sslength ss))
     (setq img	(vlax-ename->vla-object (ssname ss (setq n (1- n))))
    pat	(vla-get-ImageFile img)
     )
     (if (not (open pat "r"))
(progn
  (princ
    (strcat "\nSuppression de l'image : " (vla-get-Name img))
  )
  (vla-delete img)
)
     )
   )
 )

 ;; Restauration de l'état des calques
 
 (if l_lst
   (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    l_lst
   )
 )
 (princ)
)

 

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

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

Lien vers le commentaire
Partager sur d’autres sites

merci gile

 

je vais rajouter cela au petit lisp qui me permet de purger sans passer par la boite de dialogue

 

 

(defun c:spurge (/)

 

(command "_.PURGE" "_A" "*" "_N")

 

(command "_audit" "o")

 

(princ)

 

)

comme tu vois on a pas du tout le meme niveau :P

 

mon metier est de tirer les charettes des autres

 

la moindre occasion de pouvoir les allégées est bien venu

 

encore merci

Lien vers le commentaire
Partager sur d’autres sites

bonjour Gile ,

j'ai testé ta routine "purge_xref" sur un autocad 2000 et la fonction "vla-detach " a la ligne

"(setq path (vla-get-Path (vla-item (vla-get-blocks acdoc) x)))" retourne ces messages d'erreur :

1); erreur: Erreur Automation Clé dupliquée

2); erreur:Le serveur ActiveX a renvoyé l'erreur: nom inconnu: Path

A première vue je pense que c'est un problème dans le nom complet chemin+nom+extension

En interrogeant la variable "path" , elle reste à nil .

Je ne maitrise pas encore les fonctions vlisp ,je ne peux donc pas apporter de solution.

Ou autre possibilité une fonction "VLA" de plus qui fonctionne mal sur acad2000 ,je n'ai

pas vérifié sur une autre version .

 

[Edité le 6/6/2006 par sergeluc]

Lien vers le commentaire
Partager sur d’autres sites

Salut,

 

Pour serge luc, merci pour le retour.

 

Le premier message d'erreur : "; erreur: Erreur Automation Clé dupliquée" est effectivement le message retourné si le nom du bloc (ou de la xref) est donné avec son extension, comme par exemple :

 

(vla-item (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))) [surligneur]"NomDuBloc.dwg"[/surligneur])

 

la syntaxe correcte est :

 

(vla-item (vla-get-blocks (vla-get-ActiveDocument (vlax-get-acad-object))) [surligneur]"NomDuBloc"[/surligneur])

 

Est-ce toi qui as entré le nom de la xref ou est il acquis par le lisp (vla-get-Name ...) ?

 

En clair, sur AutoCAD 2000, si tu fais (comme le fait le LISP) :

 

(vla-get-Name (vlax-ename->vla-object (car (entsel))))

 

et que tu sélectionnes une xref, est-ce qu'il t'est retourné le nom de la xref avec son extension ?

 

Si oui, il faut, pour AutoCAD 2000, ajouter à la routine une ligne de code pour supprimer l'extension du nom de chaque xref de la liste avant le mapcar qui teste la validité du chemin.

 

(setq lst (mapcar '(lambda (x) (vl-string-right-trim ".dwg" x))))

 

 

Pour Fraid

 

Ton LISP spurge pourrait utiliser les fonctions vlisp à la place des (command ... )(généralement l'exécution est plus rapide) :

 

(defun c:spurge	(/ AcDoc)
 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
 (vla-PurgeAll AcDoc)
 (c:purge_xref)
 (c:purge_raster)
 (vla-AuditInfo AcDoc :vlax-true)
 (princ)
) 

 

Il faut bien sûr que les routines purge_xref et purge_raster soient chargées.

 

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

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

Lien vers le commentaire
Partager sur d’autres sites

merci gile

 

je vais le remplacer tout de suite

 

par contre voici les messages d'erreur que je recois quand j'utilise tes lisps

 

Commande: _purge_xref

; erreur: type d'argument incorrect: consp nil

 

Commande:

Commande: _purge_raster

; erreur: type d'argument incorrect: lselsetp nil :exclam:

Lien vers le commentaire
Partager sur d’autres sites

Bonjour Gile ,

Pour ta 1ere question :

Est-ce toi qui as entré le nom de la xref ou est il acquis par le lisp (vla-get-Name ...) ?

il m'est acquis par (vla-get-Name ...)

Ta 2eme question :

(vla-get-Name (vlax-ename->vla-object (car (entsel))))

me retourne : ; erreur:no function definition: VLAX-ENAME->VLA-OBJECT

Et pour ma remarque : "je n'ai pas vérifié sur une autre version ".

"purge_xref" fonctionne sur autocad2006 .

 

Je vais regardé cela plus en détail........

 

merci Gile

 

 

 

 

[Edité le 7/6/2006 par sergeluc]

Lien vers le commentaire
Partager sur d’autres sites

Pour Fraid

 

Au temps pour moi !

 

Les LISP sont un peu "brut de décoffrage". Les messages d'erreur que tu as eu signifient que la liste de xref était vide et que jeu de sélection des images aussi.

 

J'ajoute des contrôles dans les deux LISP pour éviter ces messages si les routines sont lancées dans des dessin ne contenant pas de xref et/ou pas d'images.

 

Pour sergeluc

 

Avant de faire (vla-get-Name (vlax-ename->vla-object (car (entsel)))) sur la 2000 avais-tu fais (vl-load-com) pour charger les fonctions ActiveX ?

 

Je suis content que çà marche sur AutoCAD 2006.

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

Lien vers le commentaire
Partager sur d’autres sites

sa y est j'ai compris

 

En fait gile, tu n'avais pas compris ma question

 

se sont les xref et images sans reference

et non avec un chemin invalide

 

les xref et images sans reference sont celles qui on ete supprimés manuelement

donc plus presente dans le dessin

mais presente dans le gestionnaire

 

le chemin invalide c'est la presence de l'xref dans le dessin mais autocad ne l'a pas trouvé

celles la generalement je les gardes (par exemple un logo que l'on ma pas fournis)

 

 

Lien vers le commentaire
Partager sur d’autres sites

Bonjour Gile

(vl-load-com) est bien chargé ,il est déclaré dans ta routine .J'ai encore fais des tests sur

autocad2000 et c'est bien la fonction "vla-get-Path" qui est mal interprètée dans cette version d'autocad .Je viens de remarquer que je me suis trompé dans le message du posté le 6/6/2006 à 20:14 ou je fais référence à "vla-detach " (cette dernière ne pose pas de problème)

J'essaie de trouver une solution à "vla-get-Path" en vlisp .Je manque de temps en ce moment

mais ca va venir....

 

 

Lien vers le commentaire
Partager sur d’autres sites

Pour Fraid

 

Au temps pour moi ! (deuxième fois)

 

J'avais effectivement mal compris la question.

 

Si pour les xref je vois bien ce que tu veux : purger la collection des xref qui n'ont plus de références dans le dessin (comme pour des blocs), pour les images raster, je ne vois pas. À ma connaissance (toute limitée), les images raster ne sont contenues dans aucune autre collection que les collections d'entités des espaces objet ou papier dans lesquelles elles sont insérées. Si une image raster est supprimée du dessin le lien avec le fichier source est aussi supprimé. Ceci explique peut-être ma confision. Si je me trompe, je te remercie d'éclairer ma lanterne.

 

Pour Purge_xref je mets ici une autre routine (la précédente semble intéresser sergeluc et peut-être d'autres). J'ai changer le nom pour éviter les confusions : xref_purge

 

;;; XREF_PURGE Purge les xrefs non référencées

(defun c:xref_purge
	    (/ AcDoc BlCol n xref lst lay l_lst)

 ;; Chargement des fonctions ActiveX

 (vl-load-com)

 ;; AcDoc : pointeur vers le document actif

 (setq AcDoc (vla-get-ActiveDocument (vlax-get-acad-object)))


 ;; Dévérouillage de tous les calques

 (repeat (setq n (vla-get-count (vla-get-Layers AcDoc)))
   (setq lay (vla-item (vla-get-Layers AcDoc) (setq n (1- n))))
   (if	(= :vlax-true
   (vla-get-lock lay)
)
     (progn
(vla-put-lock lay :vlax-false)
(setq l_lst (cons lay l_lst))
     )
   )
 )

 ;; Pour chaque nom de xref de la collection, on teste si une référence
 ;; est présente dans le dessin, si non la xref est détachée du dessin

 (vlax-for x (vla-get-Blocks AcDoc)
   (if	(= :vlax-true
   (vla-get-isXref x)
)
     (if (not
    (ssget "_X"
	   (list (cons 0 "INSERT") (cons 2 (vla-get-name x)))
    )
  )
(progn
  (princ
    (strcat "\La xref \"" (vla-get-name x) "\" a été purgée.")
  )
  (vla-detach x)
)
     )
   )
 )

 ;; Restauration de l'état des calques

 (if l_lst
   (mapcar '(lambda (x)
       (vla-put-lock x :vlax-true)
     )
    l_lst
   )
 )
 (princ)
)

 

 

Pour sergeluc,

 

le souci semble bien venir d'une histoire de compatibilité entre versions, je ne peux pas vraiment t'aider à le résoudre, je n'ai qu'AutoCAD 2007 sous la main.

 

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

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

Lien vers le commentaire
Partager sur d’autres sites

je ne peux pas vraiment t'aider à le résoudre, je n'ai qu'AutoCAD 2007 sous la main.

 

Je confirme le problème avec une 2000.

Ce n'est pas les 1er problèmes que je rencontre avec les fonctions Vlax surtout avec une 2000.

 

J'ai donc commencé a regarder ton lisp et sa coince bien a :

 

(setq path (vla-get-Path (vla-item (vla-get-blocks acdoc) x)))

 

Le (vla-get-Path avec une 2000 ne réagi que si le chemin de l'Xref est valide

Tout à fait le contraire de ce que la routine veut faire ;)

 

J'ai cherché un peu un autre moyen de trouver le chemin, mais pas encore trouvé :(

 

Vais-je trouver mon chemin? :)

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

Lien vers le commentaire
Partager sur d’autres sites

Pour sergeluc,

 

grace aux contributions de Bonuscad et Patrick_35, je fais une proposition pour remplacer l'expressin (mapcar ...) qui teste et supprime les xrefs.

 

Çà devrait marcher avec toutes les versions (pas testé).

 

(mapcar
   '(lambda (x)
      (if (	 (if (not
       (open (vla-get-Path (vla-item (vla-get-blocks acdoc) x))
	     "r"
       )
     )
   (vla-detach (vla-item (vla-get-Blocks AcDoc) x))
 )
 (if (vl-catch-all-error-p
       (vl-catch-all-apply
	 'vla-get-Path
	  [surligneur](list[/surligneur] (vla-item (vla-get-blocks acdoc) x) [surligneur])[/surligneur]
       )
     )
   (vla-detach (vla-item (vla-get-Blocks AcDoc) x))
 )
      )
    )
   lst
 ) 

 

[surligneur]correction[/surligneur]

 

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

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

Lien vers le commentaire
Partager sur d’autres sites

merci gile

 

la purge des xref marche impeccable

 

parcontre savoir ou sont "stocké" les images effacées manuellement et toujours presente dans le gestionnaire c'est autre chose

 

elles sont forcement quelque part

 

cela m'arrive souvent d'envoyer des plans en oubliant de détaché les images effacées

(pour des detail de façades par exemples)

 

c'est etrange que personne ne c'est déjà posée la question :casstet:

Lien vers le commentaire
Partager sur d’autres sites

Pour Fraid,

 

Désolé ...

 

J'ai beau chercher, je ne trouve pas où sont "stockées" ces images éffacées (pour le LISP il faut bien pouvoir comparer le "stock" avec les références toujours insérées dans le dessin), je ne trouve pas non plus d'autre moyen de les détacher que le menu contextuel du gestionnaire (pas de commande ni de fonction LISP ou Vlisp)

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

Lien vers le commentaire
Partager sur d’autres sites

Merci,

 

Je ne comprends pas tout dans le lien que tu donnes (anglais oblige), et il ne semble pas directement lié avec ce qui nous préoccupe ici.

 

D'après ce que j'ai pu comprendre, AcadRasterImage serait le nom de la classe VBA pour les images raster, et ImageFile c'est le chemin du fichier lié (comme Path pour les xrefs).

 

Mon souci, c'est que d'après l'aide (ActiveX and VBA Reference) il me semble qu'on ne puisse pas accéder aux images autrement que par une sélection (dans les espaces papier et objet, dans les blocs) et qu'il n'est pas spécifié non plus de méthode pour les détacher (seulement delete).

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

Lien vers le commentaire
Partager sur d’autres sites

D'après ce que j'ai pu comprendre, une image serait considéré comme un bloc, suivant le même schéma qu'un xref et si on est capable de trouver le chemin de l'image, on peut logiquement penser que l'on peut la manipuler et donc l'enlever. Reste à trouver la bonne procédure

 

@+

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

bonjour Gile

Et pourtant il y a une erreur !

J'avais oublié de mettre l'argument pour (vl-catch-all-apply 'vla-get-Path ...) sous forme de liste.

Désolé je l'avais vu et corrigée ,j'ai complètement oublié de le signaler....dans la précipitation.

c'est pas sérieux de ma part ,je serai plus vigilant a l'avenir .

 

Lien vers le commentaire
Partager sur d’autres sites

Gile

je n'ai pas suivi le sujet des images mais il y a eu ce post

http://www.cadxp.com/modules.php?op=modload&name=XForum&file=viewthread&tid=3940#pid12328

de bruno_l .

 

J'ai trouvé ceci dans mes archives ,j'espère ne pas etre à coté du sujet :

;; ! ***************************************************************************
;; ! IM_GetImagesLst
;; ! ***************************************************************************
;; ! Function : Returns the list of all images attached to the current drawing
;; ! Arguments: 'none'
;; ! Returns  : The attached images are returned as a list of path and image file nalist IMAGE file name wil complete path
;; ! Action   :
;; ! Updated  : March 3, 2000
;; ! e-mail   : rakesh.rao@4d-technologies.com
;; ! Web      : www.4d-technologies.com
;; ! ****************************************************************************

(defun IM_GetImagesLst( / ImgLst _ImgLst ename )
(setq ImgLst (dictsearch (namedobjdict) "ACAD_IMAGE_DICT"))
(if ImgLst
(progn
(setq ImgLst (LI_mitem 350 ImgLst))
(if ImgLst
(progn
	(setq _ImgLst '())
	(foreach ename ImgLst
		(setq _ImgLst (cons (LI_item 1 (entget ename)) _ImgLst))
	)
	(setq ImgLst (reverse _ImgLst))
))
))
ImgLst
)

[Edité le 10/6/2006 par sergeluc]

;avec ceci

 
(defun LI_mitem( Code entl / Lst itm )
(setq Lst '())
(foreach itm entl
(if (= (car itm) Code)
	(setq Lst (cons (cdr itm) Lst))
)
)
(if Lst (reverse Lst) nil)
)

[Edité le 10/6/2006 par sergeluc]

 

Pour ceux qui ne connaisse pas ce site :www.4d-technologies.com

Il y a de belles routines....

 

[Edité le 10/6/2006 par sergeluc]

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é