vl-some for objects in one object.

vl-some for objects in one object.

^_^clovis^_^
Advocate Advocate
604 Views
8 Replies
Message 1 of 9

vl-some for objects in one object.

^_^clovis^_^
Advocate
Advocate

Hello,

 

(setq allblocks(vla-get-blocks(vla-get-activedocument(vlax-get-acad-object))))

I'd like to know if like "vl-some" for list, there is a function to walk through the "allblocks" and break when the result is true?

 

Thanks

 

0 Likes
Accepted solutions (1)
605 Views
8 Replies
Replies (8)
Message 2 of 9

Moshe-A
Mentor
Mentor

@^_^clovis^_^  hi,

 

(vl-some) operate on list(s)

(vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))  ; return object container

these are two different things.

 

to iterate over container use:

 

(setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))

(vlax-for  AcDbBlkTblRec blocks

 ; do your job

 .......

 .......

 (vlax-release-object AcDbBlkTblRec) ; dispose memory

); vlax-for

 

or

 

(vlax-map-collection blocks 'woringfunc)

where workingfunc is a defined function who gets 1 argument which is an item (in turn) of the container

 

(defun workingfunc (AcDbBlkTblRec)

 ; do your job

  ......

  .....

); workingfunc

 

 

Moshe

 

 

 

 

 

 

 

to operate on 

 

0 Likes
Message 3 of 9

komondormrex
Mentor
Mentor
Accepted solution

hey,

there is no such function for collections, but you can do sort of looping like the following

(setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
 index 1 
) 
(while (and (not condition) (<= index (vla-get-count blocks))) 
 (get_condition_is_true_for_block (vla-item blocks (1- index)))
 (setq index (1+ index)) 
) 
 

 

Message 4 of 9

^_^clovis^_^
Advocate
Advocate

Thanks guys.

When I don't have too many blocks (vla-get-count allblocks < 100) in the dwg I do use vlax-for, otherwize I do use while.

I find vl-some more "elegant" and was wondering if some "vlx-some" existed to work on object container.

 

PS: vlax-map-collection is in my case pretty slow

Thanks again,

0 Likes
Message 5 of 9

Moshe-A
Mentor
Mentor

@^_^clovis^_^ ,

 

i do not think there is an elegant way to break (vlax-for) or (vlax-map-collection) the only way i can think of is (exit) but this send you to command line. maybe if you create a menu macro (or a script) where you call a function running (vlax-for) at exit continue your program?!

 

Moshe

 

0 Likes
Message 6 of 9

dbroad
Mentor
Mentor

It is impossible to make performance recommendations without knowing what your intent on processing block definitions is  and what result would be considered true.  Looping through 100 blocks should be quick if the processing of each block definition had reasonable logic.  For example, consider:

  • Each dimension has a block named *D . Skip these
  • Each layout is a block. If that is what you need to change there is a better way using (layoutlist)
  • Xrefs are blocks named *|*. Can't modify those.
  • Other unnamed blocks such as dynamic blocks *U00... Probably should skip those.

If you are trying to exclude any of those, then in the loop, filter those out first and then work what's left.

 

The block collection includes layouts also, each of which could have from none to thousands of objects.

 

Another way to process blocks is by using tblnext on the block table. To exit a while loop, you could use the exit function but should define an error handler first. The block table doesn't include layouts.

 

To exit a vlax-for loop early, you might put it inside a lambda function inside a vl-catch-all-apply and call the exit function in the loop.  Not very good approach IMO since it hides all kinds of logic errors.

 

I use (vlax-for blk blks (vlax-for i blk)) to process every entity in the drawing but dimensions and xrefs shoud be filtered out.

 

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 7 of 9

Rick_Tolleshaug_TSC
Advocate
Advocate

I realize this still processes every item in collection, but if you want to use 'vl-some' you could use Lee Mac's "Get All Items" to convert collection to a list first.

 

;; VLA-Collection: Get All Items  -  Lee Mac
;; Returns a list of all items in the supplied collection
;; col - [vla] VLA Collection Object

(defun LM:getallitems ( col / rtn )
    (vlax-for obj col (setq rtn (cons obj rtn)))
    (reverse rtn)
)

 

0 Likes
Message 8 of 9

^_^clovis^_^
Advocate
Advocate

Hello Rick,

I run the allBlocks just one time so it doesn't make much sense to make a list of blocks.

Thanks.

0 Likes
Message 9 of 9

Moshe-A
Mentor
Mentor

@^_^clovis^_^ 

 

You are totally right, one loop is enough, handle the record(s) needed and skip the rest. 💪

 

Moshe

 

0 Likes