Jump to content

Replace user specified value in any attribute with lisp


Recommended Posts

Posted

Hello gang,

 

I'm looking for a simple lisp to replace "ABCD" with "EFGH" where "ABCD" resides as a value in multiple different attributes of a block. In other words, there are attributes with different tag names but have the same attribute value "ABCD", and I want to find all instances of these values and replace them without user input in a lisp I can run as a batch process on multiple drawings.

 

Thanks in advance for any assistance.

Posted (edited)

Command ASR

 

EDIT: I added ASRM function, that substitutes multiple instances of the "to be replaced string"

 

 

(vl-load-com)

;; Get Attribute Values  -  Lee Mac
;; Returns an association list of attributes present in the supplied block.
;; blk - [ent] Block (Insert) Entity Name
;; Returns: [lst] Association list of ((<tag> . <value>) ... )
;; http://www.lee-mac.com/attributefunctions.html#algetattributevaluerc
(defun LM:getattributevalues ( blk / enx )
    (if (and (setq blk (entnext blk)) (= "ATTRIB" (cdr (assoc 0 (setq enx (entget blk))))))
        (cons
            (cons
                (cdr (assoc 2 enx))
                (cdr (assoc 1 (reverse enx)))
            )
            (LM:getattributevalues blk)
        )
    )
)

;; Set Attribute Value  -  Lee Mac
;; Sets the value of the first attribute with the given tag found within the block, if present.
;; blk - [vla] VLA Block Reference Object
;; tag - [str] Attribute TagString
;; val - [str] Attribute Value
;; Returns: [str] Attribute value if successful, else nil.
(defun LM:vl-setattributevalue ( blk tag val )
    (setq tag (strcase tag))
    (vl-some
       '(lambda ( att )
            (if (= tag (strcase (vla-get-tagstring att)))
                (progn (vla-put-textstring att val) val)
            )
        )
        (vlax-invoke blk 'getattributes)
    )
)

;;;;;;;;;;;;;

;; ASR  for Attribute String Replace
(defun c:ASR ( / from to ss i atts blk a tag val newval)
  (setq from (getstring "\nString to be replaced: "))
  (setq to (getstring "\nString to replace to: "))
  ;;(setq from "AZERTY")
  ;;(setq to "QUERTY")
  (setq ss (ssget (list (cons 0 "INSERT") (cons 66 1))))
  (setq i 0)
  (repeat (sslength ss)
    (setq blk (ssname ss i))
    (setq atts (LM:getattributevalues blk))
    (foreach a atts
      (setq tag (car a))
      (setq val (cdr a))
      (if (vl-string-search from val ) (progn
        (setq newval (vl-string-subst to from val))
        ;; substitute the attribute
        (LM:vl-setattributevalue (vlax-ename->vla-object blk) tag newval)
      ))
    )
    (setq i (+ i 1))
  )
)

;; ASRM  for Attribute String Replace Multiple.
;; Same as ASR, except it changes multiple instances of the the "from" to "to"
(defun c:ASRM ( / from to ss i atts blk a tag val newval)
  (setq from (getstring "\nString to be replaced: "))
  (setq to (getstring "\nString to replace to: "))
  ;;(setq from "AZERTY")
  ;;(setq to "QUERTY")
  (setq ss (ssget (list (cons 0 "INSERT") (cons 66 1))))
  (setq i 0)
  (repeat (sslength ss)
    (setq blk (ssname ss i))
    (setq atts (LM:getattributevalues blk))
    (foreach a atts
      (setq tag (car a))
      (setq val (cdr a))
      (while (vl-string-search from val ) (progn
        (setq newval (vl-string-subst to from val))
        ;; substitute the attribute
        (LM:vl-setattributevalue (vlax-ename->vla-object blk) tag newval)
		(setq val newval)
      ))
    )
    (setq i (+ i 1))
  )
)
Edited by Emmanuel Delay
Posted (edited)

Agree with Lee great answer, for current drawing no code required just use FIND.

Edited by BIGAL
Posted

Thank you all for the replies.

 

The above solutions by Lee Mac would work, as the string I want to replace is found as a value within multiple block attributes, each with different tag names, but the text string to change is always the same value. So I think that part is already solved, easily.

 

I want to be able to do this as a batch process on multiple drawings (no user input or interface required) where I can hard code in the text string changes or run them in a script. 

Posted

That said, could I just hard code it in?

;; ASR  for Attribute String Replace
(defun c:ASR ( / from to ss i atts blk a tag val newval)
  (setq from "AZERTY")
  (setq to "QUERTY")

Posted

You will need to make sure that you have the lisp loaded can do this via Appload and add to startup suite.

 

Your script would be something like this, not tested.

 

Open dwg1 (c:asr) close "Y"

Open dwg2 (c:asr) close "Y"

 

 

Posted
On 1/15/2020 at 2:49 AM, Da Ballz said:

That said, could I just hard code it in?


;; ASR  for Attribute String Replace
(defun c:ASR ( / from to ss i atts blk a tag val newval)
  (setq from "AZERTY")
  (setq to "QUERTY")

 

 

With my code, yes, you can hard code it

Posted

Like Emmanuel if preloaded.

 

(defun c:ASR (from to / ss i atts blk a tag val newval)
remove (setq from "AZERTY")
remove (setq to "QUERTY")


open dwg1 (c:asr "AZERTY" "QUERTY") close Y
open dwg2 (c:asr "AZERTY" "QUERTY") close Y
open dwg3 (c:asr "AZERTY" "QUERTY") close Y

 

  • Like 1
Posted

Thanks guys, this makes sense. I will create a script, call Emmanuel's lisp routine, then run the script code for each replacement I need. Perfect.

  • 2 years later...
Posted

thank you so much! it is great!!

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...