Jump to content

Lisp routine to change attrbute tag value one at a time for hundreds of drawings


Recommended Posts

Posted

Hi, is there any lisp routine to change attribute tag value one at a time for hundreds of drawings. Say i want to change the attribute value revision "0" into revision "1" in the titleblock for hundreds of drawings withoutr opening them one by one.

 

your reply is higly appreciated, thanks.:(

Posted
Hi, is there any lisp routine to change attribute tag value one at a time for hundreds of drawings. Say i want to change the attribute value revision "0" into revision "1" in the titleblock for hundreds of drawings withoutr opening them one by one.

 

your reply is higly appreciated, thanks.:(

 

You could use ObjectDBX, however the only problem is that the drawing thumbnail is lost, and it has been known to shift the position of attributes when changing them.

 

So with all this in mind, perhaps a script might be better.

Posted
Hi, is there any lisp routine to change attribute tag value one at a time for hundreds of drawings. Say i want to change the attribute value revision "0" into revision "1" in the titleblock for hundreds of drawings withoutr opening them one by one.

 

your reply is higly appreciated, thanks.:(

with great assistance from leeMac this works excellent! it will perform it on drawings within the folder you designate and you can write the script to do what you want. if you need help with the script part of it send it along but i think you def want to start here.

http://www.cadtutor.net/forum/showthread.php?t=43585&page=3

Posted

Thanks for the plug Todd :D

 

One more thing - when you say "attribute tag values" I assume you mean the attribute values, and not the attribute tags themselves.

 

Here is a LISP that could get you going, you could call it in a script if you like:

 

(defun AttribChng (blk tag val / ss)
 (vl-load-com)
 (mapcar (function set) '(blk tag)
         (mapcar (function strcase) (list blk tag)))

 (setq *doc (cond (*doc) ((vla-get-ActiveDocument
                            (vlax-get-acad-object)))))

 (if (ssget "_X" (list '(0 . "INSERT") (cons 2 blk) '(66 . 1)))
   (progn
     (vlax-for obj (setq ss (vla-get-ActiveSelectionSet *doc))

       (foreach att (vlax-invoke obj 'GetAttributes)

         (if (eq (strcase (vla-get-TagString att)) tag)
           (vla-put-TextString att val))))

     (vla-delete ss))

   (princ "\n** No Blocks Found **"))

 (princ))




(defun c:test nil
 (AttribChng "titleblock" "revision" "1")
 (princ))

Posted

i test your lisp in a single drawing it worked perfect. how can use it in order for me not to open each drawing & run lisp on every drawing. also how can i put in in script? sorry i'm not quite good in lisp.

 

thanks leemac.:)

Posted

If you were to use my Script Writer, as todouble has linked, you would use the script line:

 

_.open *file* (load "C:\\Users\\The Courage Dog\\myLISP.lsp") (AttribChng "titleblock" "revision" "1") _.save _.close

 

Where the filepath is the location of the LISP file. If the LISP is in the support path, then just:

 

(load "myLISP.lsp")

 

Let me know how you get on :)

Posted
If you were to use my Script Writer, as todouble has linked, you would use the script line:

 

_.open *file* (load "C:\\Users\\The Courage Dog\\myLISP.lsp") (AttribChng "titleblock" "revision" "1") _.save _.close

 

Where the filepath is the location of the LISP file. If the LISP is in the support path, then just:

 

(load "myLISP.lsp")

 

Let me know how you get on :)

 

 

sorry i can't get what your instruction, can you explain me in a easy way please.....the idea is to use your lisp without opening each drawing and all the say hundreds of drawings will change certain attribute value....sorry again..

Posted

No need to be sorry, I shall explain a bit better :)

 

The idea is to write a script that can be run to alter the necessary attribute values in your drawings.

 

The usual way to do this is to write a line of the script for each drawing you want to process, for example the script may look like:

 

_.open "C:\Users\Lee Mac\Drawing1.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing2.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing3.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close

 

But to save the user from having to construct each line of the script in this way, I have written a LISP program to write the script for you.

 

(defun c:wScript (/ *error* Get_Subs Str-Break Str-Make DirDia

                   FILE FOLD FOLDER OFILE PATH SCRLINE SHELL STRLST)
 
 ;; Lee Mac  ~  11.01.10
 (vl-load-com)
 
 (setq *acad (cond (*acad) ((vlax-get-acad-object)))
       *doc  (cond (*doc)  ((vla-get-ActiveDocument *acad))))
 
 (or *def_opt* (setq *def_opt* "Yes"))
 

 (defun *error* (msg)
   (and ofile (close ofile))
   (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " msg " **")))
   (princ))

 (defun get_subs (folder / file)
   ;; CAB
   (mapcar
     (function
       (lambda (x) (setq file (strcat folder "\\" x))
                   (cons file (apply (function append) (get_subs file)))))
       (cddr (vl-directory-files folder nil -1))))

 
 (defun Str-Break (str del / pos lst)
   ;; Lee Mac  ~  27.05.09
 (while (setq pos  (vl-string-search del str))
   (setq lst (cons (substr str 1 pos) lst)
         str (substr str (+ pos 1 (strlen del)))))
 (reverse (cons str lst)))
 

 (defun Str-Make (lst del / str x)
   ;; Lee Mac  ~  29.12.09
   (setq str  (car lst))
   (foreach x (cdr lst) (setq str (strcat str del x)))
 str)
 

 (defun DirDia (msg dir flag)
   ;; Lee Mac  ~  07.06.09
   (setq Shell (vla-getInterfaceObject *acad "Shell.Application")
         Fold  (vlax-invoke-method Shell 'BrowseForFolder
                 (vla-get-HWND *acad) msg flag dir))
   (vlax-release-object Shell)

   (if Fold
     (progn
       (setq Path (vlax-get-property
                    (vlax-get-property Fold 'Self) 'Path))
       (vlax-release-object Fold)

       (and (= "\\" (substr Path (strlen Path)))
            (setq Path (substr Path 1 (1- (strlen Path)))))))
   
   Path)


 ;;  --=={  Main Function  }==--
 

 (prompt "\n<< Enter Script Operations, use *file* for the Filename >>")
 
 (cond (  (zerop (strlen (setq scrline (getstring t "\n>> Script: "))))

          (princ "\n*Cancel*"))

       (  (< (length (setq StrLst (Str-Break scrline "*file*"))) 2)

          (princ "\n** Delimiter *file* not found in Script String **"))

       (  (not (and (setq Path (DirDia "Select Directory of Files on Which to Operate..." nil 512))
                    
                    (not (initget "Yes No"))
                    (setq *def_opt*
                      (cond ((getkword (strcat "\nProcess SubDirectories? <" *def_opt* "> : ")))
                            (*def_opt*)))
                    
                    (setq file (getfiled "Create Script File" (cond (*load*) ("")) "scr" 1))))
        
          (princ "\n*Cancel*"))

       (t (setq *load* file ofile (open file "w"))

          (foreach filepath (apply (function append)
                                   (vl-remove 'nil
                                     (mapcar
                                       (function
                                         (lambda (Path)
                                           (mapcar
                                             (function
                                               (lambda (File)
                                                 (strcat Path "\\" File)))
                                             (vl-directory-files Path "*.dwg" 1))))
                                       (append (list Path)
                                               (apply (function append)
                                                      (if (= "YES" (strcase *def_opt*))
                                                        (Get_Subs Path)))))))

            (write-line (Str-Make strLst (strcat (chr 34) filepath (chr 34))) ofile))

          (setq ofile (close ofile))
          (princ "\n<< Script Written >>")))

 (princ))

 

This program will prompt for a script line, which is merely the first line of the script, but instead of putting the filepath of the drawing, you would use the *file* token.

 

Hence:

 

_.open *file* (load "C:\\mylisp.lsp) (c:mylisp) _.save _.close

 

The program will then prompt for a directory of drawings to process and whether you want to include sub-directories also.

 

After selecting a location to write the script to, the program will construct a script that can be run to perform the operations you have listed in the script-line.

 

 

With this in mind, we can write a script-line for your situation.

 

_.open *file* (load "C:\\Users\\mylisp.lsp") (AttribChng "titleblock" "revision" "1") _.save _.close

 

Where the "C:\\Users\\mylisp.lsp" refers to the location that your LISP file resides.

 

If the LISP file is in the ACAD support path, this can just be:

 

(load "mylisp.lsp")

 

Once the script is written, open a new drawing in ACAD and type "script" at the command line.

 

Select the script we have just written and the drawings will be processed.

 

I hope this clarifies things.

 

Lee

Posted

what a great explanation. I believe i can follow nowyour instruction.

you are a genious. many many thanks mr. leemac. you've answered very well to every thread i have posted. thanks again for your time.

i'll try your lisp& let you know for any more queries...:)

 

 

No need to be sorry, I shall explain a bit better :)

 

The idea is to write a script that can be run to alter the necessary attribute values in your drawings.

 

The usual way to do this is to write a line of the script for each drawing you want to process, for example the script may look like:

 

_.open "C:\Users\Lee Mac\Drawing1.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing2.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing3.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close

 

But to save the user from having to construct each line of the script in this way, I have written a LISP program to write the script for you.

 

(defun c:wScript (/ *error* Get_Subs Str-Break Str-Make DirDia

                   FILE FOLD FOLDER OFILE PATH SCRLINE SHELL STRLST)

 ;; Lee Mac  ~  11.01.10
 (vl-load-com)

 (setq *acad (cond (*acad) ((vlax-get-acad-object)))
       *doc  (cond (*doc)  ((vla-get-ActiveDocument *acad))))

 (or *def_opt* (setq *def_opt* "Yes"))


 (defun *error* (msg)
   (and ofile (close ofile))
   (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " msg " **")))
   (princ))

 (defun get_subs (folder / file)
   ;; CAB
   (mapcar
     (function
       (lambda (x) (setq file (strcat folder "\\" x))
                   (cons file (apply (function append) (get_subs file)))))
       (cddr (vl-directory-files folder nil -1))))


 (defun Str-Break (str del / pos lst)
   ;; Lee Mac  ~  27.05.09
 (while (setq pos  (vl-string-search del str))
   (setq lst (cons (substr str 1 pos) lst)
         str (substr str (+ pos 1 (strlen del)))))
 (reverse (cons str lst)))


 (defun Str-Make (lst del / str x)
   ;; Lee Mac  ~  29.12.09
   (setq str  (car lst))
   (foreach x (cdr lst) (setq str (strcat str del x)))
 str)


 (defun DirDia (msg dir flag)
   ;; Lee Mac  ~  07.06.09
   (setq Shell (vla-getInterfaceObject *acad "Shell.Application")
         Fold  (vlax-invoke-method Shell 'BrowseForFolder
                 (vla-get-HWND *acad) msg flag dir))
   (vlax-release-object Shell)

   (if Fold
     (progn
       (setq Path (vlax-get-property
                    (vlax-get-property Fold 'Self) 'Path))
       (vlax-release-object Fold)

       (and (= "\\" (substr Path (strlen Path)))
            (setq Path (substr Path 1 (1- (strlen Path)))))))

   Path)


 ;;  --=={  Main Function  }==--


 (prompt "\n<< Enter Script Operations, use *file* for the Filename >>")

 (cond (  (zerop (strlen (setq scrline (getstring t "\n>> Script: "))))

          (princ "\n*Cancel*"))

       (  (< (length (setq StrLst (Str-Break scrline "*file*"))) 2)

          (princ "\n** Delimiter *file* not found in Script String **"))

       (  (not (and (setq Path (DirDia "Select Directory of Files on Which to Operate..." nil 512))

                    (not (initget "Yes No"))
                    (setq *def_opt*
                      (cond ((getkword (strcat "\nProcess SubDirectories? <" *def_opt* "> : ")))
                            (*def_opt*)))

                    (setq file (getfiled "Create Script File" (cond (*load*) ("")) "scr" 1))))

          (princ "\n*Cancel*"))

       (t (setq *load* file ofile (open file "w"))

          (foreach filepath (apply (function append)
                                   (vl-remove 'nil
                                     (mapcar
                                       (function
                                         (lambda (Path)
                                           (mapcar
                                             (function
                                               (lambda (File)
                                                 (strcat Path "\\" File)))
                                             (vl-directory-files Path "*.dwg" 1))))
                                       (append (list Path)
                                               (apply (function append)
                                                      (if (= "YES" (strcase *def_opt*))
                                                        (Get_Subs Path)))))))

            (write-line (Str-Make strLst (strcat (chr 34) filepath (chr 34))) ofile))

          (setq ofile (close ofile))
          (princ "\n<< Script Written >>")))

 (princ))

 

This program will prompt for a script line, which is merely the first line of the script, but instead of putting the filepath of the drawing, you would use the *file* token.

 

Hence:

 

_.open *file* (load "C:\\mylisp.lsp) (c:mylisp) _.save _.close

 

The program will then prompt for a directory of drawings to process and whether you want to include sub-directories also.

 

After selecting a location to write the script to, the program will construct a script that can be run to perform the operations you have listed in the script-line.

 

 

With this in mind, we can write a script-line for your situation.

 

_.open *file* (load "C:\\Users\\mylisp.lsp") (AttribChng "titleblock" "revision" "1") _.save _.close

 

Where the "C:\\Users\\mylisp.lsp" refers to the location that your LISP file resides.

 

If the LISP file is in the ACAD support path, this can just be:

 

(load "mylisp.lsp")

 

Once the script is written, open a new drawing in ACAD and type "script" at the command line.

 

Select the script we have just written and the drawings will be processed.

 

I hope this clarifies things.

 

Lee

Posted
what a great explanation. I believe i can follow nowyour instruction.

you are a genious. many many thanks mr. leemac. you've answered very well to every thread i have posted. thanks again for your time.

i'll try your lisp& let you know for any more queries...:)

 

Thanks :) :)

Posted
No need to be sorry, I shall explain a bit better :)

 

The idea is to write a script that can be run to alter the necessary attribute values in your drawings.

 

The usual way to do this is to write a line of the script for each drawing you want to process, for example the script may look like:

 

_.open "C:\Users\Lee Mac\Drawing1.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing2.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close
_.open "C:\Users\Lee Mac\Drawing3.dwg" (load "C:\\mylisp.lsp") (c:mylisp) _.save _.close

 

But to save the user from having to construct each line of the script in this way, I have written a LISP program to write the script for you.

 

(defun c:wScript (/ *error* Get_Subs Str-Break Str-Make DirDia

                   FILE FOLD FOLDER OFILE PATH SCRLINE SHELL STRLST)

 ;; Lee Mac  ~  11.01.10
 (vl-load-com)

 (setq *acad (cond (*acad) ((vlax-get-acad-object)))
       *doc  (cond (*doc)  ((vla-get-ActiveDocument *acad))))

 (or *def_opt* (setq *def_opt* "Yes"))


 (defun *error* (msg)
   (and ofile (close ofile))
   (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
       (princ (strcat "\n** Error: " msg " **")))
   (princ))

 (defun get_subs (folder / file)
   ;; CAB
   (mapcar
     (function
       (lambda (x) (setq file (strcat folder "\\" x))
                   (cons file (apply (function append) (get_subs file)))))
       (cddr (vl-directory-files folder nil -1))))


 (defun Str-Break (str del / pos lst)
   ;; Lee Mac  ~  27.05.09
 (while (setq pos  (vl-string-search del str))
   (setq lst (cons (substr str 1 pos) lst)
         str (substr str (+ pos 1 (strlen del)))))
 (reverse (cons str lst)))


 (defun Str-Make (lst del / str x)
   ;; Lee Mac  ~  29.12.09
   (setq str  (car lst))
   (foreach x (cdr lst) (setq str (strcat str del x)))
 str)


 (defun DirDia (msg dir flag)
   ;; Lee Mac  ~  07.06.09
   (setq Shell (vla-getInterfaceObject *acad "Shell.Application")
         Fold  (vlax-invoke-method Shell 'BrowseForFolder
                 (vla-get-HWND *acad) msg flag dir))
   (vlax-release-object Shell)

   (if Fold
     (progn
       (setq Path (vlax-get-property
                    (vlax-get-property Fold 'Self) 'Path))
       (vlax-release-object Fold)

       (and (= "\\" (substr Path (strlen Path)))
            (setq Path (substr Path 1 (1- (strlen Path)))))))

   Path)


 ;;  --=={  Main Function  }==--


 (prompt "\n<< Enter Script Operations, use *file* for the Filename >>")

 (cond (  (zerop (strlen (setq scrline (getstring t "\n>> Script: "))))

          (princ "\n*Cancel*"))

       (  (< (length (setq StrLst (Str-Break scrline "*file*"))) 2)

          (princ "\n** Delimiter *file* not found in Script String **"))

       (  (not (and (setq Path (DirDia "Select Directory of Files on Which to Operate..." nil 512))

                    (not (initget "Yes No"))
                    (setq *def_opt*
                      (cond ((getkword (strcat "\nProcess SubDirectories? <" *def_opt* "> : ")))
                            (*def_opt*)))

                    (setq file (getfiled "Create Script File" (cond (*load*) ("")) "scr" 1))))

          (princ "\n*Cancel*"))

       (t (setq *load* file ofile (open file "w"))

          (foreach filepath (apply (function append)
                                   (vl-remove 'nil
                                     (mapcar
                                       (function
                                         (lambda (Path)
                                           (mapcar
                                             (function
                                               (lambda (File)
                                                 (strcat Path "\\" File)))
                                             (vl-directory-files Path "*.dwg" 1))))
                                       (append (list Path)
                                               (apply (function append)
                                                      (if (= "YES" (strcase *def_opt*))
                                                        (Get_Subs Path)))))))

            (write-line (Str-Make strLst (strcat (chr 34) filepath (chr 34))) ofile))

          (setq ofile (close ofile))
          (princ "\n<< Script Written >>")))

 (princ))

 

This program will prompt for a script line, which is merely the first line of the script, but instead of putting the filepath of the drawing, you would use the *file* token.

 

Hence:

 

_.open *file* (load "C:\\mylisp.lsp) (c:mylisp) _.save _.close

 

The program will then prompt for a directory of drawings to process and whether you want to include sub-directories also.

 

After selecting a location to write the script to, the program will construct a script that can be run to perform the operations you have listed in the script-line.

 

 

With this in mind, we can write a script-line for your situation.

 

_.open *file* (load "C:\\Users\\mylisp.lsp") (AttribChng "titleblock" "revision" "1") _.save _.close

 

Where the "C:\\Users\\mylisp.lsp" refers to the location that your LISP file resides.

 

If the LISP file is in the ACAD support path, this can just be:

 

(load "mylisp.lsp")

 

Once the script is written, open a new drawing in ACAD and type "script" at the command line.

 

Select the script we have just written and the drawings will be processed.

 

I hope this clarifies things.

 

Lee

 

 

Lee,

 

I did not know you made this program. It is outstanding. I just used it yesterday for sixty drawings to be purged, audited & bound. The script ran like clockwork. I only needed to change the save to qsave because it would have required answering prompts to overwrite the existing file. That program was easy and a pleasure to use.

 

Thanks for the share.

The Buzzard

Posted
Lee,

 

I did not know you made this program. It is outstanding. I just used it yesterday for sixty drawings to be purged, audited & bound. The script ran like clockwork. I only needed to change the save to qsave because it would have required answering prompts to overwrite the existing file. That program was easy and a pleasure to use.

 

Thanks for the share.

The Buzzard

 

You're very welcome Buzzard - I'm glad it could save you some time :)

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