The Courage Dog Posted January 26, 2010 Posted January 26, 2010 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. Quote
Lee Mac Posted January 26, 2010 Posted January 26, 2010 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. Quote
todouble22 Posted January 26, 2010 Posted January 26, 2010 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 Quote
Lee Mac Posted January 27, 2010 Posted January 27, 2010 Thanks for the plug Todd 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)) Quote
The Courage Dog Posted January 27, 2010 Author Posted January 27, 2010 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. Quote
Lee Mac Posted January 27, 2010 Posted January 27, 2010 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 Quote
The Courage Dog Posted January 27, 2010 Author Posted January 27, 2010 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.. Quote
Lee Mac Posted January 27, 2010 Posted January 27, 2010 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 Quote
The Courage Dog Posted January 28, 2010 Author Posted January 28, 2010 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 Quote
Lee Mac Posted January 28, 2010 Posted January 28, 2010 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 Quote
The Buzzard Posted January 28, 2010 Posted January 28, 2010 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 Quote
Lee Mac Posted January 28, 2010 Posted January 28, 2010 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 Quote
Recommended Posts
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.