I had to change the text styles and width attributes of several blocks in Autocad. There was 10-30 blocks on each dwg and nearly 100 dgs and I could not be bothered to manually convert each block to the new standard.
https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/attribute-width-change/td-p/1525357
this link has a script to change all the blocks (title blocks and several electrical symbols) width to 1 and as a first pass it does what I want (failing due to bad ; error: bad argument type: lentityp nil Command:
which after changing it to manually select and just selecting the blocks I want fixes it). However I also need to change the test style from whatever it is to "Standard"
https://www.afralisp.net/reference/dxf-group-codes.php
after checking this link I found "Text style name" is code dxf 7
so I changed the script to the following.
(defun C:StandardFromDWGTEXT (/ ss sslen cnt blck ent entinfo)
(setq ss (ssget))
(setq cnt 0)
(setq sslen (sslength ss))
(while (< cnt sslen)
(setq blck (ssname ss cnt))
(setq ent (entnext blck))
(setq entinfo (entget ent))
(while
(and ent (= (cdr (assoc 0 entinfo)) "ATTRIB"))
(entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
;;; (entupd ent)
;;; (setq ent (entnext ent))
;;; (setq entinfo (entget ent))
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
(entupd ent)
(setq ent (entnext ent))
(setq entinfo (entget ent))
)
(setq cnt (1+ cnt))
)
(princ)
)
Now it only works with the lines I commented out (stops working with them but that also means it only changes text style not width too) and only changes the text style half the time. I managed to get through all the files by reloading auto-cad arbitrarily and sometimes when it didn't work (not working meaning nothing changes when I expect it to) opening the script in the visual lisp editor and hitting load active window fixes it. I'd put it beside me but in the interest of learning and because I've already had to change the standard twice there's a good chance I'll have to do this again I want to try and fix this.
Considering the script with just changing the width to 1 works 100% of the time I've decided the problem is not with adding this to the startup suite/opening it in the visual lisp editor but rather with my addition to the code itself. However the line I added to change the text style
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
doesn't seem different from the line to change the text width.
If anyone has any insight I'd appreciate it. I have experience with other programming languages but am a complete novice when it comes to Autolisp/lisp.
There are a few issues which could trip up your code:
(setq ss (ssget))
Without the filter list argument to permit only attributed blocks, your selection could include any entity type, meaning that the entnext
call will return nil
for any objects without subentities. This will consequently cause the entget
call to return the following error that you are witnessing:
error: bad argument type: lentityp nil
The solution is to include a filter list to only permit selection of attributed blocks:
(setq ss (ssget "_:L" '((0 . "INSERT") (66 . 1))))
The _:L
mode string also excludes entities on locked layers.
(setq sslen (sslength ss))
Without testing for a valid selection, the variable ss
could be nil
which will cause (sslength ss)
to return the error:
error: bad argument type: lselsetp nil
(entmod (subst (cons 41 1) (assoc 41 entinfo) entinfo))
(entmod (subst (cons 7 "Standard") (assoc 7 entinfo) entinfo))
Here, the second subst
expression is substituting DXF group 7 within the original DXF data list, not the DXF data which has been modified following the substitution of DXF group 41. This will have the result of reversing the modification to the width factor.
Implementing fixes for the above issues (and tweaking a few other things) might yield the following code:
(defun c:standardfromdwgtext ( / a i s x )
(if (setq s (ssget "_:L" '((0 . "INSERT") (66 . 1))))
(repeat (setq i (sslength s))
(setq i (1- i)
a (entnext (ssname s i))
x (entget a)
)
(while (= "ATTRIB" (cdr (assoc 0 x)))
(if (entmod (subst '(41 . 1.0) (assoc 41 x) (subst '(7 . "Standard") (assoc 7 x) x)))
(entupd a)
)
(setq a (entnext a)
x (entget a)
)
)
)
)
(princ)
)