Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Collect empty blocks inserted in the dwg.

9 REPLIES 9
Reply
Message 1 of 10
mdhutchinson
403 Views, 9 Replies

Collect empty blocks inserted in the dwg.

The code below collects empty blocks with the intent to delete them.

However, it appears that if an Xref is currently 'unloaded' it apparrently collects that too. I could probably just test to see if the block is an Xref and avoid it... but how could I modify this to check if it is loaded and still empty? 

 

(defun NullBlocks (/ block *thisdwg* block nullblocks)
 (setq *thisdwg* (vla-get-activedocument (vlax-get-acad-object)))
 (vlax-for block (vla-get-blocks *thisdwg*) ;iterate block table
  (vla-get-Name block)
  (if (= 0 (vla-get-count block))
   (setq nullblocks (cons (vla-get-name block) nullblocks))
  )
 )
 nullblocks
)

9 REPLIES 9
Message 2 of 10
Kent1Cooper
in reply to: mdhutchinson


@mdhutchinson wrote:

The code below collects empty blocks .... if an Xref is currently 'unloaded' it apparrently collects that too. I could probably just test to see if the block is an Xref and avoid it... but how could I modify this to check if it is loaded and still empty? 

....


I don't see any difference between the VLA Properties for Xref's that are loaded or not, but I do in the entity data returned by (entget (tblobjname "block" "YourXrefName")).  If I Attach an Xref [Attachment method], while it's loaded, there's an entry like this:

(70 . 36)

but after I unload it, there are these:

(70 . 4) (71 . 1)

The 71-code entry is not present when it's loaded.

 

For an Overlay Xref, when it's loaded, it's:

(70 . 44)

and when it's unloaded, they're:

(70 . 12) (71 . 1)

 

So the presence of the 32 bit in the (assoc 70) value, which you can check for with (logand), indicates that it's loaded.  But since the 71-code exists at all only for an unloaded one, I would think you could, a little more simply, just check for whether anything is returned by:
(assoc 71 (entget (tblobjname "block" "YourXrefName")))

If that returns nil, it should be loaded, and you can check whether it's empty.  If that returns anything, or at least if it returns (71 . 1), it should be unloaded.  But I wouldn't guarantee that other complications might not result in some other 71-code value, so you might need to experiment.  I have a listing of DXF codes for Block table entries, and it explains the bit-code values for the 70-code entry [it says 32 means it's "resolved"], but it doesn't list a 71-code entry at all, so I could't say whether that might have other possible values.  Presumably if it might, there would be other binary bits representing something or other, so you might need to use (logand) on that, checking for the 1 bit, just to be sure.

Kent Cooper, AIA
Message 3 of 10
pbejse
in reply to: mdhutchinson


@mdhutchinson wrote:

The code below collects empty blocks with the intent to delete them.

However, it appears that if an Xref is currently 'unloaded' it apparrently collects that too. I could probably just test to see if the block is an Xref and avoid it... but how could I modify this to check if it is loaded and still empty? 

 

 


(defun NullBlocks (/ block *thisdwg* block nullblocks)
 (setq *thisdwg* (vla-get-activedocument (vlax-get-acad-object)))
 (vlax-for block (vla-get-blocks *thisdwg*) ;iterate block table
 (vla-get-Name block)
(if (and (= 0 (vla-get-count block))
   (eq (vla-get-IsXref block) :vlax-false))
   (setq nullblocks (cons (vla-get-name block) nullblocks))
  ) 
 )
nullblocks
)

 

HTH

 

Message 4 of 10
mdhutchinson
in reply to: pbejse

Thanks!

This seems close - I have added this to the routine... however, I ONLY wanted to avoid the xref if it is currently 'Unloaded'.

As a side note: I discovered the code is getting the empty blocks that are within the xref too... or blocks that are xref dependant...  This is fine.

 

Is there a way to tell if the xref is 'Unloaded' ?

Message 5 of 10
Kent1Cooper
in reply to: mdhutchinson


@mdhutchinson wrote:

... however, I ONLY wanted to avoid the xref if it is currently 'Unloaded'.

.... 

Is there a way to tell if the xref is 'Unloaded' ?


Carrying on with elements from my first Reply, something like this, perhaps [untested]:

 

(defun NullBlocks (/ *thisdwg* block bname bdata nullblocks)
  (setq *thisdwg* (vla-get-activedocument (vlax-get-acad-object)))
  (vlax-for block (vla-get-blocks *thisdwg*); iterate block table
    (setq
      bname (vla-get-name block)
      bdata (tblsearch "block" bname)
    ); setq
    (if
      (and
        (= 0 (vla-get-count block)); no elements in definition
        (if (assoc 1 bdata); it's an Xref
          (= (logand 32 (cdr (assoc 70 bdata))) 32); then -- T if loaded, nil if unloaded
          T ; else -- it's a regular Block
        ); if
      ); and
      (setq nullblocks (cons bname nullblocks))
    ); if
  ); vlax-for
  nullblocks
); defun

Kent Cooper, AIA
Message 6 of 10
pbejse
in reply to: mdhutchinson


@mdhutchinson wrote:

Thanks!

This seems close - I have added this to the routine... however, I ONLY wanted to avoid the xref if it is currently 'Unloaded'.

As a side note: I discovered the code is getting the empty blocks that are within the xref too... or blocks that are xref dependant...  This is fine.

 

Is there a way to tell if the xref is 'Unloaded' ?


(defun NullBlocks (/ block *thisdwg* block nullblocks bn)
  (setq *thisdwg* (vla-get-activedocument (vlax-get-acad-object)))
  (vlax-for block (vla-get-blocks *thisdwg*) ;iterate block table
    (setq bn (vla-get-Name block))
    (if	(and (= 0 (vla-get-count block))
	     (not (vl-some '(lambda (o)
			      (vl-string-search o bn)
			    )
			   '("Space" "|")
		  )
	     )
	     (eq (vla-get-IsXref block) :vlax-false)
	)
      (setq nullblocks (cons bn nullblocks))
    )
  )
  nullblocks
)

 

Unloaded <---- linky 

 

HTH

 

Message 7 of 10
pbejse
in reply to: Kent1Cooper


@Kent1Cooper wrote:

@mdhutchinson wrote:

... however, I ONLY wanted to avoid the xref if it is currently 'Unloaded'.

.... 

Is there a way to tell if the xref is 'Unloaded' ?


Carrying on with elements from my first Reply, something like this, perhaps [untested]:

 

......
      (and
        (= 0 (vla-get-count block)); no elements in definition
        (if (assoc 1 bdata); it's an Xref
          (= (logand 32 (cdr (assoc 70 bdata))) 32); then -- T if loaded, nil if unloaded
          T ; else -- it's a regular Block
        ); if
.......
); defun


watch out for Xref dependent blocks.

(assoc 1 bdata) <- nil 

 

perhaps

....

(and
(= 0 (vla-get-count block)); no elements in definition
(setq flg (cdr (assoc 70 bdata)))
(zerop (boole 1 20 flg))
)

....

 

 

 

Message 8 of 10
Kent1Cooper
in reply to: pbejse


@pbejse wrote:
....

watch out for Xref dependent blocks.

(assoc 1 bdata) <- nil 

....


I think it should be OK as is [OP confirm?] -- to quote from the OP's Message 4:  "... the code is getting ... blocks that are xref dependant...  This is fine."

 

So my line for what to do if that test returns nil:

          T ; else -- it's a regular Block

could say:

          T ; else -- it's a regular Block, either defined in this drawing or Xref-dependent

and if it also passed the emptiness test, its name will be put in the nullblocks list.

Kent Cooper, AIA
Message 9 of 10
pbejse
in reply to: Kent1Cooper


@Kent1Cooper wrote:

@pbejse wrote:
....

watch out for Xref dependent blocks.

(assoc 1 bdata) <- nil 

....


I think it should be OK as is [OP confirm?] -- to quote from the OP's Message 4:  "... the code is getting ... blocks that are xref dependant...  This is fine."

 

So my line for what to do if that test returns nil:

          T ; else -- it's a regular Block

could say:

          T ; else -- it's a regular Block, either defined in this drawing or Xref-dependent

and if it also passed the emptiness test, its name will be put in the nullblocks list.


Good point. but Message 1 "... with the intent to delete them..." 

 

No need to filter nullblocks list if automating the intent to delete the blocks

 

 

 

Message 10 of 10
Kent1Cooper
in reply to: pbejse


@pbejse wrote:
..... but Message 1 "... with the intent to delete them..." 

 

No need to filter nullblocks list if automating the intent to delete the blocks 


I think some kind of filtering is needed because that they don't want to eliminate unloaded Xrefs.  I assume that's because they want to preserve their locations, scales, Layers, etc., and the ability to reload them without needing to attach/overlay them all over again.

 

But apparently, whether or not unloaded Xrefs actually contain anything, they are always interpreted as "empty" by the (vla-get-count) test, so without some kind of further check, it would put them in the list to eliminate.  They need a way to identify those probably-not-really-empty unloaded Xrefs, to distinguish them from really-empty ordinary Blocks and really-empty loaded Xrefs.  That distinction is to keep the routine from eliminating any unloaded Xrefs, even though they are considered "empty" Blocks, at least by the test that's being used.

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost