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

Block Name to VLA-object

14 REPLIES 14
SOLVED
Reply
Message 1 of 15
aqdam1978
7069 Views, 14 Replies

Block Name to VLA-object

Hi,

I need to get VLA-Object from block name.

here there is a code to get block name from VLA-Object:

  (vlax-get-property obj
    (if (vlax-property-available-p obj 'EffectiveName) 'EffectiveName 'Name)
  )

 but I need the inverse of this code exactly:

 

blockname(as a string)==>VLA-object

(defun GetVLA_BName (BName).......

 

so, does anybody know how can I do it?

 

Thanks

14 REPLIES 14
Message 2 of 15
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

 

 but I need the inverse of this code exactly:

 

blockname(as a string)==>VLA-object

(defun GetVLA_BName (BName).......

 

so, does anybody know how can I do it?

 

Thanks


Are you wanting the get a selection set by supplying the block name?

 

Message 3 of 15
hmsilva
in reply to: aqdam1978

aqdam,
if I understood you correctly
perhaps something like

 

;; usage (GetVLA_BName "test")
;; Given a block name will return as a VlaObject the 1st
;; element of a selection set, if one exists, otherwise
;; return nil.
(defun GetVLA_BName (BName / ss)
  (if (setq ss (ssget "_X" (list '(0 . "INSERT") (cons 2 BName))))
    (vlax-ename->vla-object (ssname ss 0)))
  )

 

Hope that helps

Henrique

EESignature

Message 4 of 15
Kent1Cooper
in reply to: aqdam1978


@aqdam1978 wrote:

....I need to get VLA-Object from block name.

.... 

blockname(as a string)==>VLA-object

(defun GetVLA_BName (BName).......


There are two possibilities here:

 

1.  A Block reference [or insertion] can be a VLA object, for example an insertion can be made into one by something like:
 

(setq BlkInsObj (vlax-ename->vla-object BlockInsertionEntityName)); [not the Block name]

 

Using something like hmsilva's routine will make one, but of course there can be more than one insertion of the same Block name.  That code will identify only the first one in the selection set, which if I remember right will be the last one inserted.  If you're looking for a particular one, you would need to do something like add additional filtering for Layer, and/or insertion point, and/or some other characteristic(s).  If you know there will be only one such Block in the drawing, then a routine like that should find it as is.

 

However, it might be more accurate to name that function MakeVLA_BName, because it will not "get" an existing VLA object if that's what you want to do, but will make one of an insertion of the Block.  If you already have such a VLA object made, and by "get" you mean that you want to find it, I'm not sure how you would go about it, except by somehow stepping through all VLA objects [if there's even a way to do so -- that's beyond my experience] and looking for one with the correct "Name" property.  Someone else probably knows some (vla...) function that will find it, if there is one.

 

2.  A Block's definition in the Block Table can be a VLA object, for example made into one by something like:

 

(setq BlkDefObj (vlax-ename->vla-object (tblobjname "block" BlockName)))

 

There will be only one Block definition of a given name in a drawing, no matter how many insertions there are of that Block name.  [But it is possible to assign a VLA object of the same Block definition to more than one variable....]  If you have already placed a Block definition as a VLA object into a variable with something like the above, and you want to find the name of that variable by giving the Block name, I'm not sure how you would go about that, either.  The Block name, oddly enough, is not among the VLA properties of the object made that way.

Kent Cooper, AIA
Message 5 of 15
aqdam1978
in reply to: Kent1Cooper

Hi Kent,

 

Thank you for your good information.

in my case there is a one block in every dwg file and its name is "TittleBlock".

I just want to change a value of a tag of an attribute!

 

(defun SetAttVal (obj tag value)
  (foreach a (vlax-invoke obj 'getattributes)
    (if (= (vlax-get a 'TagString) tag)
        (vlax-put a 'textstring value))))

 

BlockName: "TittleBlock"

 

(SetAttVal (vlax-ename->vla-object (tblobjname "block" "TittleBlock")) "REV" "Z")

 

----------------------------------------

But you pointed to good issue!, if there are more than one block and I want to change a tag of an attribute inside the ALL blocks, how can I do it?

 

Thanks

 

Message 6 of 15
hmsilva
in reply to: aqdam1978

aqdam,

try this

 

;;;Posted by Jeff Mishler
;;;Discussion Groups - Visual LISP, AutoLISP and General Customization
;;;06-24-2004
(defun edit_att	(blkname att_tag str)
  (vl-load-com)
  (ssget "x"
	 (list '(0 . "INSERT") (cons 2 blkname) '(66 . 1))
  )
  (vlax-for item (vla-get-activeselectionset
		   (vla-get-activedocument (vlax-get-acad-object))
		 )
    (foreach att (vlax-safearray->list
		   (vlax-variant-value (vla-getattributes item))
		 )
      (if (= att_tag (vla-get-tagstring att))
	(vla-put-textstring att str)
      )
    )
  )
)
;;; Usage: (edit_att "blockname" "tag of attribute to edit" "new text")
;;; is Case sensitive

 

Hope that helps,

 

Henrique

EESignature

Message 7 of 15
aqdam1978
in reply to: hmsilva

Thank you Henrique,

 

Abbas

 

Message 8 of 15
hmsilva
in reply to: aqdam1978

You're welcome, Abbas
Glad I could help

 

Henrique

EESignature

Message 9 of 15
pbejse
in reply to: hmsilva

With the introduction of DB you may still want the snip that check for EffectiveName 

To make it more generic:

 

(defun edit_att	(blkname att_tag str)
  (vl-load-com)
  (ssget "x"
	 (list '(0 . "INSERT") (cons 2 (strcat blkname ",`*U*")) '(66 . 1))
  )
  (vlax-for item (vla-get-activeselectionset
		   (vla-get-activedocument (vlax-get-acad-object))
		 )
    (if (eq (strcase blkname)
               (strcase (vla-get-effectivename item)))
    (foreach att (vlax-safearray->list
		   (vlax-variant-value (vla-getattributes item))
		 )
      (if (= (strcase att_tag) (vla-get-tagstring att))
	(vla-put-textstring att str)
      )
    )
      )
  )
)

 

HTH

 

Message 10 of 15
aqdam1978
in reply to: pbejse

With the introduction of DB you may still want the snip that check for EffectiveName 

To make it more generic:

 

 

 

Hi Pbejse,

Can you explain more  please? what does mean "DB"?

what is the advantages of this code vs previous code prepared by Henrique and Jeff Mishler?

 

Thanks,

 

Abbas

Message 11 of 15
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

 

Hi Pbejse,

Can you explain more  please? what does mean "DB"?

what is the advantages of this code vs previous code prepared by Henrique and Jeff Mishler?

 

Thanks,

 

Abbas


DB=Dynamic Blocks 

 

The block name of this type of blocks becomes anonymous names when dynamic properties are altered like so,

 

Block Name: "Stargate"
Anonymous Name: "*U8"

 

(edit_att "stargate" "tag of attribute to edit" "new text")

 

In this case, supplying the block name on sssget filter (cons 2 blname) will  only select the un-altered state of the block

and ignores the names of the "altetered" blocks

 

(list '(0 . "INSERT") (cons 2 (strcat blkname ",`*U*")) '(66 . 1))

 

By including the ",`*U*" wildcard, the anonymous names are included in the selection.

 

Now the need to check effectivename is warranted as the lfilter above selects ALL blocks with anonymous names. 

before processing the selected item.

 

(eq (strcase blkname) (strcase (vla-get-effectivename item)))

 

Not that everybody uses DB. BUT "better have and not need than need and not have"

 

Hope this is clear Abbas Smiley Happy

Message 12 of 15
aqdam1978
in reply to: pbejse

Hi Pbejse,

 

Thank you for your good guidance.

You are the best!

 

Thanks,

 

Abbas

Message 13 of 15
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

Hi Pbejse,

 

Thank you for your good guidance.

 

 Thanks,

 

Abbas


You are welcome Abbas, thats what we're here for.

 

Cheers

Message 14 of 15
aqdam1978
in reply to: pbejse

Hi Pbejse,

 

I customized your code because of my new needs! to:

 

(defun GetAttrVal (blkname att_tag / Val)
(if (and(/= blkname nil) (/= att_tag nil))
(progn  
  (vl-load-com)
  (ssget "x" (list '(0 . "INSERT") (cons 2 (strcat blkname ",`*U*")) '(66 . 1)))
  (vlax-for item (vla-get-activeselectionset
		   (vla-get-activedocument (vlax-get-acad-object))
		 )
    (if (eq (strcase blkname) (strcase (vla-get-effectivename item)))
		(foreach att (vlax-safearray->list (vlax-variant-value (vla-getattributes item)))
		  (if (= (strcase att_tag) (vla-get-tagstring att))	(setq Val (vla-get-textstring att)))
		);;foreach
    );;if
  )
);;progn
);;if/=
(if (= Val nil)(setq Val ""))
Val
)
;;; Usage: 
;;(GetAttrVal "blockname" "tag name")

 It works fine, but if I insert my block to another drawing as an XREF, block name changed to filename and it will be an XREF object. so, Is there any solution to get attribute values both in block and XREFed block?

 In other word, this lisp code can search inside of an XREF objects to find the "blkname" too?

 

 

Thanks,

 

Abbas

 

Message 15 of 15
pbejse
in reply to: aqdam1978


@aqdam1978 wrote:

Hi Pbejse,

  

It works fine, but if I insert my block to another drawing as an XREF, block name changed to filename and it will be an XREF object. so, Is there any solution to get attribute values both in block and XREFed block?

In other word, this lisp code can search inside of an XREF objects to find the "blkname" too?

  

Thanks,

 

Abbas

 


Yes, with ODBX

 

 

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

Post to forums  

Autodesk Design & Make Report

”Boost