Author Topic: create selection set of block attribute value range.  (Read 10610 times)

0 Members and 1 Guest are viewing this topic.

Pad

  • Bull Frog
  • Posts: 342
create selection set of block attribute value range.
« on: February 14, 2012, 08:53:15 AM »
Hello

I'm in a bit of a pickle.
I've messed up the levels on a survey drawing with an incorrect target height.  So I need to select all the blocks in a drawing whose number attribute values range from 788 to 899.
Each number attribute value is unique in the drawing and are contained within several blocks (in this case they are all either in a 'pl' named block or a 'pd' named block).

I need to create a selection set of the blocks with this number range so I can then add a value to the 'level' attribute value of each of them.
Any help would be really appreciated.

Thanks
Pads

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: create selection set of block attribute value range.
« Reply #1 on: February 14, 2012, 09:31:10 AM »
I think you will have to iterate the database collection and extract attribute values of those named inserts
and build a selections set of those matching your target values.
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.

ronjonp

  • Needs a day job
  • Posts: 7531
Re: create selection set of block attribute value range.
« Reply #2 on: February 14, 2012, 09:31:54 AM »
One thing you could do is make a selset of all those blocks and use ATTOUT ... then manipulate that data in Excel and use ATTIN to update.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Pad

  • Bull Frog
  • Posts: 342
Re: create selection set of block attribute value range.
« Reply #3 on: February 14, 2012, 09:49:45 AM »
Thanks Guys

Carrying out the actual level adjustment is not a problem, all I'm after is a quick way of creating the selection set by the attribute range.

I've done a bit of searching, this one is nearly there http://www.cadtutor.net/forum/showthread.php?37654-Custom-block-selection-lisp
and this one
http://www.thecadforums.com/autocad-customization/28665-selection-attribute-value.html
I couldn't figure out how to call it.

I have just finished manually selecting each block so the urgency has gone,  it would be a really useful lisp to have though.

Thanks
P

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: create selection set of block attribute value range.
« Reply #4 on: February 14, 2012, 10:12:32 AM »
Think Lee's was close to what you wanted.
Here is a mod, not tested.
Code - Auto/Visual Lisp: [Select]
  1. (defun filter_set (blk tag lo hi / ss olst)
  2.   (if (setq ss (ssget "_X"
  3.                       (list (cons 0 "INSERT")
  4.                             (cons 2 blk)
  5.                             (cons 66 1)
  6.                       )
  7.                )
  8.       )
  9.     (progn
  10.       (foreach blk (mapcar 'vlax-ename->vla-object (mapcar 'cadr (ssnamex ss)))
  11.         (foreach att (vlax-safearray->list (vlax-variant-value (vla-getattributes blk)))
  12.           (if (and (eq tag (vla-get-tagstring att))
  13.                    (< lo (atof (vla-get-textstring att)) hi)
  14.               )
  15.             (setq olst (cons (vlax-vla-object->ename blk) olst))
  16.           )
  17.         )
  18.       )
  19.     )
  20.   )
  21.   (reverse olst)
  22. )
  23.  
  24. (defun c:test ()
  25.   (alert
  26.       (filter_set "test Block" "Elevation" 799. 805.)
  27.     )
  28.   )
  29.   (princ)
  30. )
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.

Pad

  • Bull Frog
  • Posts: 342
Re: create selection set of block attribute value range.
« Reply #5 on: February 14, 2012, 11:00:07 AM »
Thanks for having a look at this CAB.

If you do have a few minutes there seems to be a problem.

I have modified the calling routine to this:

Code - Auto/Visual Lisp: [Select]
  1.     (defun c:ssnum ()
  2.      (alert
  3.        (vl-princ-to-string
  4.          (filter_set "PL" "NO" 847. 850.)   ; block name, tag, range of values
  5.        )
  6.      )
  7. (sssetfirst nil ss) ;highlights ss
  8.      (princ)
  9.     )

but it seems to select all the PL blocks.
I have attached an extract from the drawing.
Is it easy add functionality to specify more than one block at a time?

thanks
P

Lee Mac

  • Seagull
  • Posts: 12925
  • London, England
Re: create selection set of block attribute value range.
« Reply #6 on: February 14, 2012, 11:12:09 AM »
Try this untested code, separate block names with commas:

Code - Auto/Visual Lisp: [Select]
  1. (defun _SelectBlockIfAttInRange ( blk tag lo hi / e i o s )
  2.    (setq
  3.        blk (strcase blk)
  4.        tag (strcase tag)
  5.    )
  6.    (if (setq s (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (cons 2 (strcat "`*U*," blk)))))
  7.        (repeat (setq i (sslength s))
  8.            (setq
  9.                e (ssname s (setq i (1- i)))
  10.                o (vlax-ename->vla-object e)
  11.            )
  12.            (cond
  13.                (   (or
  14.                        (and
  15.                            (vlax-property-available-p o 'effectivename)
  16.                            (not (wcmatch (strcase (vla-get-effectivename o)) blk))
  17.                        )
  18.                        (not (wcmatch (strcase (vla-get-name o)) blk))
  19.                    )
  20.                    (ssdel e s)
  21.                )
  22.                (   (not
  23.                        (vl-some
  24.                            (function
  25.                                (lambda ( a )
  26.                                    (and
  27.                                        (eq tag (strcase (vla-get-tagstring a)))
  28.                                        (< lo (atof (vla-get-textstring a)) hi)
  29.                                    )
  30.                                )
  31.                            )
  32.                            (vlax-invoke o 'getattributes)
  33.                        )
  34.                    )
  35.                    (ssdel e s)
  36.                )
  37.            )
  38.        )
  39.    )
  40.    (if (< 0 (sslength s))
  41.        s
  42.    )
  43. )
  44.  
  45. (defun c:test nil
  46.    (sssetfirst nil (_SelectBlockIfAttInRange "PL" "NO" 847. 850.))
  47.    (princ)
  48. )

( Edited: Added ability to select multiple blocks )

ronjonp

  • Needs a day job
  • Posts: 7531
Re: create selection set of block attribute value range.
« Reply #7 on: February 14, 2012, 11:28:13 AM »
And another (although Lee's will work with modified dynamic blocks if you have them):

Code: [Select]
(defun filter_set (blk tag lo hi / ss olst)
  (vl-load-com)
  (if (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 blk) (cons 66 1))))
    (foreach blk (mapcar 'cadr (ssnamex ss))
      (foreach att (vlax-invoke (vlax-ename->vla-object blk) 'getattributes)
(and (eq tag (vla-get-tagstring att))
     (not (<= lo (atof (vla-get-textstring att)) hi))
     (ssdel blk ss)
)
      )
    )
  )
  ss
)

(sssetfirst nil (filter_set "PL" "NO" 847. 850.)) ; block name, tag, range of values
;;Grabs all blocks that start with "P"
(sssetfirst nil (filter_set "P*" "NO" 847. 850.))
;;Grabs all blocks named "PL" "PD"
(sssetfirst nil (filter_set "PL,PD" "NO" 847. 850.))
« Last Edit: February 14, 2012, 03:41:01 PM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

Pad

  • Bull Frog
  • Posts: 342
Re: create selection set of block attribute value range.
« Reply #8 on: February 14, 2012, 11:53:21 AM »
Thank you very much they both work!

One thing to note is that the number range has to be one less and one more than that required.
This is going to be very useful cheers.

About time I sent the swamp another donation.
Cheers
P

Lee Mac

  • Seagull
  • Posts: 12925
  • London, England
Re: create selection set of block attribute value range.
« Reply #9 on: February 14, 2012, 12:24:31 PM »
One thing to note is that the number range has to be one less and one more than that required.

Just change the '<' to '<='   :-)

Pad

  • Bull Frog
  • Posts: 342
Re: create selection set of block attribute value range.
« Reply #10 on: February 14, 2012, 03:11:29 PM »
brill! :-) cheers

Here's my calling routine, somebody might find it useful:

Code - Auto/Visual Lisp: [Select]
  1.     (defun c:ssnum (/ num_l num_h)
  2.         (setq num_l (getreal "\nEnter minimum 'number' value: "))                       ;;Low number value
  3.         (setq num_h (getreal "\nEnter maximum 'number' value: "))                       ;;High number value
  4.                 (sssetfirst nil (_SelectBlockIfAttInRange "PL,PD" "NO" num_l. num_h.))  ;;Add block names seperated by ','
  5.       (princ)
  6.     )

thanks
P
« Last Edit: February 14, 2012, 03:30:23 PM by Pad »

Lee Mac

  • Seagull
  • Posts: 12925
  • London, England
Re: create selection set of block attribute value range.
« Reply #11 on: February 15, 2012, 05:06:04 AM »
I would suggest:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:ssnum ( / num_l num_h )
  2.     (if
  3.         (and
  4.             (setq num_l (getreal "\nEnter min value: "))
  5.             (setq num_h (getreal "\nEnter max value: "))
  6.         )
  7.         (sssetfirst nil (_SelectBlockIfAttInRange "PL,PD" "NO" num_l num_h))
  8.     )
  9.     (princ)
  10. )

Note in your code that 'num_l' and 'num_l.' are different variables, similarly for 'num_h' and 'num_h.'

kruuger

  • Swamp Rat
  • Posts: 637
Re: create selection set of block attribute value range.
« Reply #12 on: February 15, 2012, 08:56:57 AM »
maybe
Code - Auto/Visual Lisp: [Select]
  1.         (and
  2.             (setq num_l (getreal "\nEnter min value: "))
  3.             (setq num_h (getreal "\nEnter max value: "))
  4.             (< nul_l num_h)
  5.         )
omit unnecessary loop.
kruuger

Pad

  • Bull Frog
  • Posts: 342
Re: create selection set of block attribute value range.
« Reply #13 on: February 15, 2012, 10:01:21 AM »
ok thanks, i'll change it.

its a bit confusing as it seemed to work fine.

Code - Auto/Visual Lisp: [Select]
  1. Command: ssnum
  2.  
  3. Initializing...
  4. Enter minimum 'number' value: 100
  5.  
  6. Enter maximum 'number' value: 200
  7.  
  8.  
  9. Command: !num_l
  10. 100.0
  11.  
  12. Command: !num_l.
  13. 100.0
  14.  
  15. Command: !num_h
  16. 200.0
  17.  
  18. Command: !num_h.
  19. 200.0

ronjonp

  • Needs a day job
  • Posts: 7531
Re: create selection set of block attribute value range.
« Reply #14 on: February 15, 2012, 10:06:32 AM »
That is strange ... guess the dot is a stop point.

(setq a "test")
Command: !a
"test"
Command: !a.
"test"
Command: !a..
"test"
Command: !a...
"test"
Command: !a.b
"test"

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC