Author Topic: Delete Item from a block  (Read 11740 times)

0 Members and 1 Guest are viewing this topic.

hudster

  • Gator
  • Posts: 2848
Delete Item from a block
« on: September 14, 2006, 10:06:57 AM »
How can I delete items nested in blocks without using refedit?

I need to delete some hatches and wipeouts from about 1600 blocks.

Cheers for any help
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Delete Item from a block
« Reply #1 on: September 14, 2006, 11:32:24 AM »
Here is one way.
Code: [Select]
(defun c:EraseObjectFromBlock (/ ActDoc BlkCol Sel Ent)
; Erase object selected from block, in block collection, so all blocks will update.

(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vla-EndUndoMark Actdoc)
(vla-StartUndoMark ActDoc)
(setq BlkCol (vla-get-Blocks ActDoc))
(setvar "errno" 0)
(while (not (equal (getvar "errno") 52))
 (if
  (and
   (setq Sel (nentsel "\n Select nested object to erase from block: "))
   (> (length Sel) 2)
   (not
    (vl-position
     nil
     (mapcar
      '(lambda (x / BlkName BlkObj)
       (setq BlkName (cdr (assoc 2 (entget x))))
       (and
        (not (vl-catch-all-error-p (setq BlkObj (vl-catch-all-apply 'vla-Item (list BlkCol Blkname)))))
        (= (vla-get-IsXref BlkObj) :vlax-false)
        (= (vla-get-IsLayout BlkObj) :vlax-false)
       )
      )
      (last Sel)
     )
    )
   )
   (/= (cdr (assoc 0 (entget (setq Ent (car Sel))))) "ATTRIB")
  )
  (progn
   (vla-Delete (vlax-ename->vla-object Ent))
   (vla-Regen ActDoc acActiveViewport)
  )
  (prompt "\n Object selected can not be erased with this command.")
 )
)
(vla-EndUndoMark ActDoc)
(princ)
)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

whdjr

  • Guest
Re: Delete Item from a block
« Reply #2 on: September 14, 2006, 04:34:34 PM »
Are there 1600 different blocks or just 1600 that need to be updated?
Are they all in one file or in differnt files? 

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #3 on: September 18, 2006, 03:41:18 AM »
each wall is an individual block, with a hatch and a wipeout in each one, I could explode them but I prefer to leave as much of the drawing unaltered as possible.

I want to be able to select an item, hatching for example, and then delete it from a selection set I've made.

Cheers for the lisp T.Willey, that does what i need it to do, but it's the long way, if that could be modified so that when I select an object in a block, say a hatch, it then deletes that hatch from all the blocks in the drawing, it would be perfect.
« Last Edit: September 18, 2006, 05:17:42 AM by Andy Hudson »
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

Arizona

  • Guest
Re: Delete Item from a block
« Reply #4 on: September 18, 2006, 06:31:21 AM »
What is unique/consistant about these hatch objects?
Are they a specific style, or on a specific layer?
Is there other hatching in the drawing?
Is this all in one block or many blocks?

Sorry for all the questions, I'm just trying to get a better idea of what you are doing... :-)

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #5 on: September 18, 2006, 07:14:11 AM »
Every wall is a block, consisting of two outside lines, two internal lines, 3 hatches and a wipeout.
Every wall is a unique block.
There is hatching in the windows as well, but not so much as in the walls.
The unique/consistent things about the hatches is that they are all on layer 0 and use the same hatch styles.
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

whdjr

  • Guest
Re: Delete Item from a block
« Reply #6 on: September 18, 2006, 08:52:21 AM »
When you say every wall is unique does that mean that you created the walls or they are like dynamic blocks where they an anonymous name?  Because even though DBs have an anonymous name they all still have an .effectivename'.

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #7 on: September 18, 2006, 09:19:45 AM »
It's an architects drawing, and every wall is called wall001, wall002 etc etc, for 1600 walls. The same with every entity on the drawing, toilet001, toilet002 etc etc.

He doesn't use autoCAD so it probably makes sense with his system, but looks nuts to me.
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

whdjr

  • Guest
Re: Delete Item from a block
« Reply #8 on: September 18, 2006, 09:41:41 AM »
If all these hatches are on the same layer you could try the ExpressTools command 'laydel',it deletes everything a selected layer and purges it from the dwg.  It says it works in blocks too.

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #9 on: September 18, 2006, 09:49:04 AM »
The hatches are all on the same layer as the walls, unfortunately.

Thanks for the help though.

I think it'll need a lisp to delete all the hatches from the drawing.
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Delete Item from a block
« Reply #10 on: September 18, 2006, 10:43:11 AM »
So collect all the wall blocks (ssget "x" '((2 . "WALL*")))
Loop through each block
Look at each entity for hatch with matching pattern, collect the ename
Delete the ename from the block

Sounds simple enough. :)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #11 on: September 19, 2006, 06:11:29 AM »
OK.

I could do the first bit, but you did that for me here, but the rest is a mystery.

can you give me a few pointers.
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Delete Item from a block
« Reply #12 on: September 20, 2006, 01:15:42 PM »
OK.

I could do the first bit, but you did that for me here, but the rest is a mystery.

can you give me a few pointers.
You wouldn't really do it the way Alan says.  You want to search the block definitions, and then delete the object for there.  I think it is easier to go the ActiveX route with this.  To step through the block collection for the current drawing you would do
Code: [Select]
(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for Blk (vla-get-Blocks ActDoc)
 ....
)
This is saying that you want to search all blocks in the block collection.

While you are searching the blocks collection, you want to search each blocks definition, so you would do that like
Code: [Select]
(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for Blk (vla-get-Blocks ActDoc)
 (if (wcmatch (strcase (vla-get-Name Blk)) "WALL*")
  (vlax-for Obj Blk
   ....
  )
 )
)
This is saying that you want to search all objects that make up the blocks definition if the name of the blocks starts with the characters "WALL".

Now you want to test the object to see if it is a wipeout or a hatch pattern, and if so delete them
Code: [Select]
(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for Blk (vla-get-Blocks ActDoc)
 (if (wcmatch (strcase (vla-get-Name Blk)) "WALL*")
  (vlax-for Obj Blk
   (if
    (or
     (= (vla-get-ObjectName Obj) "AcDbHatch")
     (= (vla-get-ObjectName Obj) "AcDbWipeout")
    )
    (vla-Delete Obj)
   )
  )
 )
)

Now you want to put that into a function you can call from the command line, so add a defun to it (whatever you like, you can change the name)
Code: [Select]
(defun c:CleanUpBlocks (/ ActDoc)

(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for Blk (vla-get-Blocks ActDoc)
 (if (wcmatch (strcase (vla-get-Name Blk)) "WALL*")
  (vlax-for Obj Blk
   (if
    (or
     (= (vla-get-ObjectName Obj) "AcDbHatch")
     (= (vla-get-ObjectName Obj) "AcDbWipeout")
    )
    (vla-Delete Obj)
   )
  )
 )
)
(princ)
)
To use ActiveX controls you have to have
Code: [Select]
(vl-load-com)Somewhere that will get loaded into Acad at least once per session (if loaded more that once no big deal).

Hope that makes sense.


Edit: I guess you would want to make sure that the blocks you are trying to search are not a layout or an xref, to do so the code would change to look like
Code: [Select]
(defun c:CleanUpBlocks (/ ActDoc)

(setq ActDoc (vla-get-ActiveDocument (vlax-get-Acad-Object)))
(vlax-for Blk (vla-get-Blocks ActDoc)
 (if
  (and
   (equal (vla-get-IsXref Obj) :vlax-false)
   (equal (vla-get-IsLayout Obj) :vlax-false)
   (wcmatch (strcase (vla-get-Name Blk)) "WALL*")
  )
  (vlax-for Obj Blk
   (if
    (or
     (= (vla-get-ObjectName Obj) "AcDbHatch")
     (= (vla-get-ObjectName Obj) "AcDbWipeout")
    )
    (vla-Delete Obj)
   )
  )
 )
)
(princ)
)
« Last Edit: September 20, 2006, 01:18:13 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Delete Item from a block
« Reply #13 on: September 20, 2006, 08:34:31 PM »
Tim,
I stand corrected, Nice example. :-)
Using plain lisp would be messy at best.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

hudster

  • Gator
  • Posts: 2848
Re: Delete Item from a block
« Reply #14 on: September 21, 2006, 07:28:36 AM »
When I try to run this lisp, i get an error message

; error: bad argument type: VLA-OBJECT nil

What am I doing wrong. I've typed in (vl-load-com) first but it makes no difference.
Revit BDS 2017, 2016, 2015, 2014, AutoCAD 2017, 2016, Navisworks 2017, 2016, BIM360 Glue