Serabis Posted October 10, 2012 Posted October 10, 2012 (edited) So, to give some background information, I have 0 experience with LISP programming, and am an intern at an engineering company. I really would love to score "brownie points" by automating an extremely boring and time consuming task. I have experience with other languages, and can work off of a good base. So here's what I would like the routine to accomplish: 1.) Figure out the name of the title block (the title block will be in the same location on each and every file) 2.) Use that name to modify 5 attribute values of that block (each title block has the same attribute tags: NAME, DRAWING_NUM, SN, DATE, DESIGNER) 3.) Save in a new location. So, for example, lets say the drawing I want to modify is at the location C:/USER/ME/, and is called drawing1.dwg. Lets say that it's title block is called "blanksheet", the routine then needs to modify the 5 attributes (NAME: DrawingName, DRAWING_NUM: 123456, SN: 000, DATE: 10 10 12, DESIGNER: Me) of the block "blanksheet". Then, after it modifies everything, saves it in the location C:/USER/YOU, and is called drawing2.dwg. I'm not even sure if this is doable within the bounds of AutoLISP, so any feedback is appreciated. Thanks in advance! Edited October 11, 2012 by Serabis Quote
nod684 Posted October 11, 2012 Posted October 11, 2012 Welcome to CAD Tutor! will this help? http://www.lee-mac.com/batte.html Quote
BIGAL Posted October 11, 2012 Posted October 11, 2012 Here is a VBA example & a VL-Lisp example to do what you want the VBA uses the attribute order & the VL uses attribute tag search. Public Sub issued_for_construction() ' This Updates the Issued for construction and sets rev 0 Dim SS As AcadSelectionSet Dim Count As Integer Dim FilterDXFCode(1) As Integer Dim FilterDXFVal(1) As Variant Dim attribs As Variant Dim BLOCK_NAME As String On Error Resume Next FilterDXFCode(0) = 0 FilterDXFVal(0) = "INSERT" FilterDXFCode(1) = 2 FilterDXFVal(1) = "DA1DRTXT" BLOCK_NAME = "DA1DRTXT" Set SS = ThisDrawing.SelectionSets.Add("issued") SS.Select acSelectionSetAll, , , FilterDXFCode, FilterDXFVal For Cntr = 0 To SS.Count - 1 attribs = SS.Item(Cntr).GetAttributes attribs(0).TextString = "ISSUED FOR CONSTRUCTION" attribs(3).TextString = "0" attribs(0).Update attribs(3).Update Next Cntr ThisDrawing.SelectionSets.Item("issued").Delete 'DO AGAIN FOR REVTABLE 'DATE 'Dim MyDate 'MyDate = Date Call DashDate FilterDXFCode(1) = 2 FilterDXFVal(1) = "REVTABLE" BLOCK_NAME = "REVTABLE" Set SS = ThisDrawing.SelectionSets.Add("revs") SS.Select acSelectionSetAll, , , FilterDXFCode, FilterDXFVal For Cntr = 0 To SS.Count - 1 attribs = SS.Item(Cntr).GetAttributes attribs(0).TextString = "0" attribs(1).TextString = DashDate attribs(2).TextString = "ISSUED FOR CONSTRUCTION" attribs(0).Update attribs(1).Update attribs(2).Update Next Cntr ThisDrawing.SelectionSets.Item("revs").Delete MsgBox "Drawing now changed to Issued for Construction" End Sub VL ; changes to issued for construction : thanks to lee mac for original code (vl-load-com) ; 1. Get current date in mm/dd/yy format. (defun ddmmyy (/ x today) (setvar "cmdecho" 0) (setq x (getvar "CDATE")) ; get current date (setq today ( rtos x 2 4)) ; convert to a string (setq date (strcat (substr today 7 2) "." (substr today 5 2) "." (substr today 3 2) )) ) (setq oldtag1 "DRAWING_STATUS") ;attribute tag name (setq newstr1 "ISSUED FOR CONSTRUCTION") (setq oldtag2 "REV_NO") ;attribute tag name (setq newstr2 "0") (setq ss1 (ssget "x" '((0 . "INSERT") (2 . "DA1DRTXT")))) (setq inc (sslength ss1)) (repeat inc (foreach att (vlax-invoke (vlax-ename->vla-object (ssname SS1 (setq inc (1- inc)) )) 'getattributes) (if (= oldtag1 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr1) ) ; end if (if (= oldtag2 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr2) ) ; end if ) ; end for ) ;end repeat (setq oldtag1 "REV-NO") (setq newstr1 "0") (ddmmyy) (setq oldtag2 "DATE") (setq newstr2 date) (setq oldtag3 "AMENDMENT") (setq newstr3 "ISSUED FOR CONSTRUCTION") (setq ss2 (ssget "x" '((0 . "INSERT") (2 . "REVTABLE")))) (setq inc (sslength ss2)) (repeat inc (foreach att (vlax-invoke (vlax-ename->vla-object (ssname ss2 (setq inc (1- inc)))) 'getattributes) (if (= oldtag1 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr1) ) (if (= oldtag2 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr2) ) (if (= oldtag3 (strcase (vla-get-tagstring att))) (vla-put-textstring att newstr3) ) ) ) (setq ss1 nil) ; (setq ss2 nil) (princ) Quote
Serabis Posted October 11, 2012 Author Posted October 11, 2012 Nod, thanks for the warm welcome! The program that Lee Mac developed worked amazingly, there are only a few problems with it though: 1) It doesn't give the option of saving to a new location, if someone uses this and messes up I dont want 100+ drawings to be messed up. 2) I'm developing this for easy use, and the people who will be using it probably don't even know the block name let alone its attribute tags. I really wish that I could see the code snippet that it generates to modify 1 drawing, then I could use that to create my own lisp file. But, I noticed its called the BATCH attribute editor, does this mean that it combines a Lisp routine (or multiple of them) and then uses a batch script to run each lisp routine? Because if this is the case, I might need to not only develop an AutoLISP routine, but also a batch file to run them. If that is NOT the case, can I have a single long LISP routine that has many "opens" and "saves" to modify mass amounts of drawings, kind of like a AutoCAD script file? Bigal, I will mess around with your supplied code today to see if I can answer some of my own questions. Thanks for the responses! Quote
Serabis Posted October 11, 2012 Author Posted October 11, 2012 Also, I am not sure if it helps out much, but instead of having to look up the block's name, each title block that I am looking to edit begins with the word sheet, so I bet there is a way of incorporating wild cards to make "finding" the block much easier. Quote
nod684 Posted October 12, 2012 Posted October 12, 2012 (edited) Nod, thanks for the warm welcome! The program that Lee Mac developed worked amazingly, there are only a few problems with it though:1) It doesn't give the option of saving to a new location, if someone uses this and messes up I dont want 100+ drawings to be messed up. 2) I'm developing this for easy use, and the people who will be using it probably don't even know the block name let alone its attribute tags. this routine is very much useful for me... what i do is that i temporarily save the files that i want to edit in a new folder then i changed from there so if something goes wrong (we cannot say) i still have my files for item number 2 of your query, there is a SELECT BLOCK option there so you don't need to know the name of the block, once you have the block selected, you can just double click it and enter your desired value. But, I noticed its called the BATCH attribute editor, does this mean that it combines a Lisp routine (or multiple of them) and then uses a batch script to run each lisp routine? Because if this is the case, I might need to not only develop an AutoLISP routine, but also a batch file to run them It is indeed a BATCH ATTRIBUTE EDITOR, i don't think it combines a lisp, not sure too if its using a script too.. but if you want to run your own lisp / script for multiple drawings, you can use Lee's Scriptwriter, found here : http://www.lee-mac.com/scriptwriter.html Edited October 12, 2012 by nod684 Quote
BIGAL Posted October 12, 2012 Posted October 12, 2012 You can write pretty simple script file to do what you want it would look something like this, the saves as lisp would be setting new target name based on existing drawing name. Open dwg1 (load "issued")(load "saveas") close Open dwg2 (load "issued")(load "saveas") close Or Open dwg1 (load "issued") saveas c:\\mydirectory\dwg1 close Open dwg2 (load "issued") saveas c:\\mydirectory\dwg2 close For sheet blocks something like (setq ss1 (ssget "x" (list (cons 0 "INSERT") (cons 2 "sheet*")))) then you could compare names to a list etc Quote
Lee Mac Posted October 12, 2012 Posted October 12, 2012 The program that Lee Mac developed worked amazingly Thank you Serabis. there are only a few problems with it though:1) It doesn't give the option of saving to a new location, if someone uses this and messes up I dont want 100+ drawings to be messed up. With any program of this nature in which numerous drawings are being modified automatically, I would always recommend that you operate on copies of drawings in case anything should go wrong. I have every confidence in my program, but couldn't offer any guarantees... 2) I'm developing this for easy use, and the people who will be using it probably don't even know the block name let alone its attribute tags. If you were to proceed with my program, there is the option to save the block & tag combinations to an external file (txt / csv), and subsequently load the attribute data in future use of the program - this way, the block & tag names would only need to be entered once, and the values could be modified from the dialog. But, I noticed its called the BATCH attribute editor, does this mean that it combines a Lisp routine (or multiple of them) and then uses a batch script to run each lisp routine? My program generates and runs an AutoCAD Script, which then calls an AutoLISP function to perform the necessary attribute modification on each drawing. Quote
Serabis Posted October 18, 2012 Author Posted October 18, 2012 (edited) Sorry for getting back to everyone so late, but I've been slightly busy. But a huge thanks to everyone! I was able to fashion a solution from your advice. To help anyone who might come across this thread, you can use the -attedit command to edit what you need to within a block. Combine this with an open, save, and close command, you got yourself a script file that opens a document, modifies it, saves it to a specified location, and then closes itself. To modify large amounts of drawings, I made a custom excel macro (using VBA) that loops to generate a script file based on the contents of certain cells. This can be done using 'Open "scriptfile.scr" For Output As #1' to open an output file, and then using 'Print #1, "text";' (the ; supresses a newline) to output a line of text to the file that you "opened". If you have anymore questions, I will check up on this thread so that I can answer them. Also, if you don't want to do any work at all, Lee Mac's Batch Attribute Editor is an amazing solution. Edited October 23, 2012 by Serabis Quote
BIGAL Posted October 19, 2012 Posted October 19, 2012 Writeline v's print #1 ? (setq fname "C://acadtemp//getval.dcl") (setq fo (open fname "w")) (write-line "ddgetval : dialog {" fo) Quote
Serabis Posted October 23, 2012 Author Posted October 23, 2012 Bigal, that piece code was for VBA in excel, not LISP. 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.