Jump to content

Recommended Posts

Posted

Hello all,

 

I need a program that I'm writing to change a text value in a block automatically without having the user pick the block. The program will also need to later retreive data directly from that block attribute.

 

In another program I wrote, I managed to figure out how to get lisp change text in a block if a user selects the block, but I don't quite know how to tell lisp which block, and attribute within that block, to change without having the user make the selection. This program will always modify the same block, and there is only one of this particular block in the entire drawing.

 

Getting lisp to modify block information is a pain in the neck... can any of you help me in the right direction?

 

Thanks,

 

Joe

Posted

(setq SelSet (ssget "x" '((0 . "INSERT")(2 . "THEBLOCKNAME"))))

(setq EntName (ssname SelSet 0))

 

OK now you have the block insert to manipulate. You can step through attributes with 'entnext'

Posted

I'm not totally clear on what's going on in the code you've suggested... I know I probably sound like a total noob, but could you give me a little more detail?

 

Thanks,

 

joe

Posted

hi frostrap,

 

carlb suggested the use of ssget function, have a look at it at the command reference help, it's one way for you to bypass a user input. in the example he has given, if you included that in your code, it will be selecting all the block entities with that blockname. may be you need to post a sample of your lisp routine so the guys here can guide you more clearly.

Posted

Something like this function:

 

(defun Change_Attribute(Block Tag Value)
 (vl-load-com)
 (if
   (setq blSet(ssget "_X" (list '(0 . "INSERT")(cons 2 Block))))
   (progn
     (foreach bl (mapcar 'vlax-ename->vla-object
	   (vl-remove-if 'listp 
                    (mapcar 'cadr(ssnamex blSet))))
(setq atLst(vlax-safearray->list
	    (vlax-variant-value
	      (vla-GetAttributes bl))))
(foreach at atLst
  (if (=(vla-get-TagString at)(strcase Tag))
    (if(vl-catch-all-error-p
	 (vl-catch-all-apply 'vla-put-TextString
	  (list at Value)))
       nil
      ); end if
    ); end if
  ); end foreach
); end foreach
     ); end progn
   ); end if
 (princ)
 ); end of Change_Attribute

 

Test with block "My_Block" and attribute "My_Tag":

 

(Change_Attribute "My_Block" "My_Tag" "It's new attribute value")

  • 6 months later...
Posted
Something like this function:

 

(defun Change_Attribute(Block Tag Value)
 (vl-load-com)
 (if
   (setq blSet(ssget "_X" (list '(0 . "INSERT")(cons 2 Block))))
   (progn
     (foreach bl (mapcar 'vlax-ename->vla-object
          (vl-remove-if 'listp 
                    (mapcar 'cadr(ssnamex blSet))))
   (setq atLst(vlax-safearray->list
           (vlax-variant-value
             (vla-GetAttributes bl))))
   (foreach at atLst
     (if (=(vla-get-TagString at)(strcase Tag))
       (if(vl-catch-all-error-p
        (vl-catch-all-apply 'vla-put-TextString
         (list at Value)))
          nil
         ); end if
       ); end if
     ); end foreach
   ); end foreach
     ); end progn
   ); end if
 (princ)
 ); end of Change_Attribute

 

Test with block "My_Block" and attribute "My_Tag":

 

(Change_Attribute "My_Block" "My_Tag" "It's new attribute value")

 

ASMI,

Is it possible to modify this lisp so it will select all the "fixture tag" blocks with an attribute = A10, and change it to attribute = A11. What I'm trying to do is modify a existing fixture tag so all the A10 tags are change to A11.:wink:

Posted

Search here I under VBA I think I posted the code to do what you want can be run form a menu toolbar etc.

Posted

Use "Search" this forum for "attribute update" or block update there is numerous responses and answers here already for your question.

 

I try to always search first as the answer is already there.

Posted

For the life of me I cannot figure out how to use the VBA code posted here. Searching only finds VBA codes. Does anyone have a lisp that can replace existing block attributes with a new value.:(

Posted

In the attached BlkAttrib.lsp there are three functions that may help you out. GetBlkAttrib, PutBlkAttrib and the ChangeAll function which I also pasted below. Both GetBlkAttrib and PutBlkAttrib use an argument named BlkOrEntity which can be either the Block or entity name. Which ever is easier for you to work with. I also added the ChangeAll function for you to revise as needed. If you don't know the attribute TagName you can explode the block and then do an undo, and note the TagName for reference. There may other methods of doing this but it works for me.

 

Terry

; c:ChangeAll - Revise this function as needed.
; Note: Replace "[color=red]BlockName[/color]" with your block name, replace "[color=red]TagName[/color]" with your
; tag name, and replace "[color=red]Find[/color]" and "[color=red]Replace[/color]" with your attribute values.

(defun c:ChangeAll (/ Cnt# Ctab$ EntName^ Layout$ SS&)
 (setq Ctab$ (getvar "CTAB"))
 (foreach Layout$ (cons "Model" (layoutlist))
   (command "_LAYOUT" "_S" Layout$)
   (setq SS& (ssget "x" (list '(-4 . "<AND")'(2 . "[color=red]BlockName[/color]")
     (cons 410 (getvar "CTAB"))'(-4 . "AND>")))
   );setq
   (if SS&
     (progn
       (setq Cnt# 0)
       (repeat (sslength SS&)
         (setq EntName^ (ssname SS& Cnt#))
         (if (= (GetBlkAttrib EntName^ "[color=red]TagName[/color]") "[color=red]Find[/color]")
           (PutBlkAttrib EntName^ "[color=red]TagName[/color]" "[color=red]Replace[/color]")
         );if
         (setq Cnt# (1+ Cnt#))
       );repeat
     );progn
   );if
 );foreach
 (setvar "CTAB" Ctab$)
 (princ)
);defun c:ChangeAll

BlkAttrib.lsp

Posted

Thanks TerryCadd,

That's what I was looking for, but it seems like it only works for normal blocks. Is it possible to make it work for dynamic blocks?

Posted

JeepMaster,

I didn't know that about the dynamic blocks. What I just found out is that when you create a dynamic block the top level dxf entity list is referring to the block by it's new Anonymous Name, i.e. "*U25" and not by it's original Block Name, i.e. "TestBlock". But there's still hope! I ran a little function that looks deeper into the nesting of the top level dxf entity list, and I found all the information needed for the attributes. It just wasn't in the regular place.

Terry

Posted
JeepMaster,

I didn't know that about the dynamic blocks. What I just found out is that when you create a dynamic block the top level dxf entity list is referring to the block by it's new Anonymous Name, i.e. "*U25" and not by it's original Block Name, i.e. "TestBlock". But there's still hope! I ran a little function that looks deeper into the nesting of the top level dxf entity list, and I found all the information needed for the attributes. It just wasn't in the regular place.

Terry

So is it possible to make it work with dynamic blocks, or is it too much work? This lisp is out of my league, so I have no idea how to modify it to make it work for dynamic blocks. Please help. :(

Posted

Works with dynamic blocks.

 

(defun c:chatt(/ cAtt cBl cTag efNm sStr nLst fSet oVal fLst
       fStr actDoc atLst cFrom cTo mCnt sucCnt errCnt)

 (vl-load-com)

 (if
   (and
     (setq cAtt(nentsel "\nPick sample attribute > "))
     (= "ATTRIB"(cdr(assoc 0(entget(car cAtt)))))
     ); end and
   (progn
     (setq actDoc(vla-get-ActiveDocument
	    (vlax-get-acad-object))
    cBl(vla-ObjectIDtoObject actDoc
	 (vla-get-OwnerID
	   (setq cAtt
	     (vlax-ename->vla-object(car cAtt)))))
    cTag(vla-get-TagString cAtt)
    mCnt 0 sucCnt 0 errCnt 0
    ); end setq
     (if(vlax-property-available-p cBl 'EffectiveName)
(progn
  (setq fStr(vla-get-EffectiveName cBl)
	nLst(mapcar 'vla-get-Name
	       (vl-remove-if-not
	         (function(lambda(x)
		   (equal fStr(vla-get-EffectiveName x))))
	             (mapcar 'vlax-ename->vla-object
	               (vl-remove-if 'listp 
                                (mapcar 'cadr(ssnamex
		           (ssget "_X" '((0 . "INSERT")
			     (66 . 1)(2 . "`*U*,")))))))))
	); end setq
   (foreach n nLst
     (setq fStr(strcat "`" n "*," fStr))
     ); end foreach
  (setq fLst(list '(0 . "INSERT")(cons 2 fStr)))
  ); end progn
(setq fLst(list '(0 . "INSERT")(cons 2(vla-getName cBl))))
); end if
     (princ "\n<<< Select blocks >>> ")
     (if(setq fSet(ssget fLst))
(progn
  (princ(strcat "\n" (itoa(sslength fSet)) " block(s) found. "))
    (setq cFrom(getstring T
		 (strcat "\nChange from <"
			 (setq oVal(vla-get-TextString cAtt)) ">: ")))
  (if(= "" cFrom)(setq cFrom oVal))
  (if
    (and
      (setq cTo(getstring T "\nChange to: "))
      (/= "" cTo)
      ); end and
    (progn
     (vla-StartUndoMark actDoc)
     (foreach b(mapcar 'vlax-ename->vla-object
	               (vl-remove-if 'listp 
                                (mapcar 'cadr(ssnamex fSet))))
      (setq atLst(vlax-safearray->list
	    (vlax-variant-value
	      (vla-GetAttributes b))))
      (foreach at atLst
         (if(and
	       (equal(vla-get-TagString at)cTag)
	       (equal(vla-get-TextString at)cFrom)
	      ); end and
	   (progn
	    (setq mCnt(1+ mCnt))
            (if(vl-catch-all-error-p
	       (vl-catch-all-apply 'vla-put-TextString
	          (list at cTo)))
	       (setq errCnt(1+ errCnt))
	       (setq sucCnt(1+ sucCnt))
              ); end if
	    ); end progn
          ); end if
        ); end foreach
      ); end foreach
     (princ(strcat "\n" (itoa sucCnt) " of " (itoa mCnt)
		   " attributes chanded. "))
     (if(/= 0 errCnt)
       (princ(strcat(itoa errCnt) " were on locked layer! "))
       ); end if
     (vla-EndUndoMark actDoc)
     ); end progn
    ); end if
  ); end progn
); end if
     ); end progn
   (princ "\n<!> It isn't attribute <!> ")
   ); end if
 (princ)
 ); end of c:chatt

Posted
Works with dynamic blocks.

 

(defun c:chatt(/ cAtt cBl cTag efNm sStr nLst fSet oVal fLst
          fStr actDoc atLst cFrom cTo mCnt sucCnt errCnt)

 (vl-load-com)

 (if
   (and
     (setq cAtt(nentsel "\nPick sample attribute > "))
     (= "ATTRIB"(cdr(assoc 0(entget(car cAtt)))))
     ); end and
   (progn
     (setq actDoc(vla-get-ActiveDocument
           (vlax-get-acad-object))
       cBl(vla-ObjectIDtoObject actDoc
        (vla-get-OwnerID
          (setq cAtt
            (vlax-ename->vla-object(car cAtt)))))
       cTag(vla-get-TagString cAtt)
       mCnt 0 sucCnt 0 errCnt 0
       ); end setq
     (if(vlax-property-available-p cBl 'EffectiveName)
   (progn
     (setq fStr(vla-get-EffectiveName cBl)
       nLst(mapcar 'vla-get-Name
              (vl-remove-if-not
                (function(lambda(x)
              (equal fStr(vla-get-EffectiveName x))))
                    (mapcar 'vlax-ename->vla-object
                      (vl-remove-if 'listp 
                                (mapcar 'cadr(ssnamex
                      (ssget "_X" '((0 . "INSERT")
                    (66 . 1)(2 . "`*U*,")))))))))
       ); end setq
      (foreach n nLst
        (setq fStr(strcat "`" n "*," fStr))
        ); end foreach
     (setq fLst(list '(0 . "INSERT")(cons 2 fStr)))
     ); end progn
   (setq fLst(list '(0 . "INSERT")(cons 2(vla-getName cBl))))
   ); end if
     (princ "\n<<< Select blocks >>> ")
     (if(setq fSet(ssget fLst))
   (progn
     (princ(strcat "\n" (itoa(sslength fSet)) " block(s) found. "))
       (setq cFrom(getstring T
            (strcat "\nChange from <"
                (setq oVal(vla-get-TextString cAtt)) ">: ")))
     (if(= "" cFrom)(setq cFrom oVal))
     (if
       (and
         (setq cTo(getstring T "\nChange to: "))
         (/= "" cTo)
         ); end and
       (progn
        (vla-StartUndoMark actDoc)
        (foreach b(mapcar 'vlax-ename->vla-object
                      (vl-remove-if 'listp 
                                (mapcar 'cadr(ssnamex fSet))))
         (setq atLst(vlax-safearray->list
           (vlax-variant-value
             (vla-GetAttributes b))))
         (foreach at atLst
            (if(and
              (equal(vla-get-TagString at)cTag)
              (equal(vla-get-TextString at)cFrom)
             ); end and
          (progn
           (setq mCnt(1+ mCnt))
               (if(vl-catch-all-error-p
              (vl-catch-all-apply 'vla-put-TextString
                 (list at cTo)))
              (setq errCnt(1+ errCnt))
              (setq sucCnt(1+ sucCnt))
                 ); end if
           ); end progn
             ); end if
           ); end foreach
         ); end foreach
        (princ(strcat "\n" (itoa sucCnt) " of " (itoa mCnt)
              " attributes chanded. "))
        (if(/= 0 errCnt)
          (princ(strcat(itoa errCnt) " were on locked layer! "))
          ); end if
        (vla-EndUndoMark actDoc)
        ); end progn
       ); end if
     ); end progn
   ); end if
     ); end progn
   (princ "\n<!> It isn't attribute <!> ")
   ); end if
 (princ)
 ); end of c:chatt

THANK YOU ASMI again!:D It works great! How come you didn't put it in your website? This will save me so much time.

Posted
How come you didn't put it in your website?

 

This is fresh, created today.

 

Thank you for kind words.

Posted
This is fresh, created today.

 

Thank you for kind words.

In that case, thanks for creating the lisp for me. You've helped me so much in the pass, if you put a "donation" link on your site, I will donate.:thumbsup: Seriouly, for the work that you do for others here(for free), you deserve some credit.

Posted

> JeepMaster

 

In that case, thanks for creating the lisp for me.

 

I have written it because for me interestingly to solve this problem for dynamic blocks. It as solving of puzzles.

 

You've helped me so much in the pass, if you put a "donation" link on your site, I will donate. Seriouly, for the work that you do for others here(for free), you deserve some credit.

 

The page "Donate" exists, but probably the link to it is hardly noticeable (after each code). Now I have taken out it in the main menu. It is certanly not a way of earnings, but these some dollars can be estimated as an attention sign. Just as on incomes of clicks under advertisements it is possible to buy once a month ice-cream or a beer bottle. But to look that you has earned whole $ 2.50 for this month why that very pleasantly :D

 

There is more advanced version of CHATT.LSP, it highlights blocks with the necessary values of attributes: http://www.asmitools.com/Files/Lisps/Chatt.html

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...