Jump to content

AutoLISP routine to modify block attributes.


Serabis

Recommended Posts

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 by Serabis
Link to comment
Share on other sites

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)

Link to comment
Share on other sites

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

 

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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by nod684
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by Serabis
Link to comment
Share on other sites

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