lfe011969 Posted October 7, 2010 Share Posted October 7, 2010 I have a program that inserts an Mtext string containing two fields that works great other than the fact the text within the string displays as the field code instead of the results obtained by the field. However, if I double click the Mtext after inserting it, the text changes to what it is supposed to. See below for a screenshot. I didn't double-click the text on the right so it shows the code. Is there a way to make the text display as it should other than to double click it? Lonnie insertSV.lsp Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Hi Lonnie, Entmake'ing Fields is pretty difficult, as you have to also entmake the extension dictionary of the text, mtext or attribute and then the ACAD_FIELD dictionary stored within that and the TEXT dictionary stored within that... Hence the workaround is to use vla-AddMText to create the MText Field. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 As a very rough mod to your code; (defun c:isv (/ pt1 pt1x pt1y zoneNUM zoneLTR mtstr) (vl-load-com) (and (progn (setq pt1 (getpoint "\nSpecify insertion point: ")) (setq pt1x (car pt1)) (setq pt1y (cadr pt1)) (cond ((<= pt1x 5)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone8>%"))) ((and (<= pt1x 10)(> pt1x 5)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone7>%")))) ((and (<= pt1x 15)(> pt1x 10)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone6>%")))) ((and (<= pt1x 20)(> pt1x 15)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone5>%")))) ((and (<= pt1x 25)(> pt1x 20)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone4>%")))) ((and (<= pt1x 30)(> pt1x 25)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone3>%")))) ((and (<= pt1x 35)(> pt1x 30)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone2>%")))) ((> pt1x 35)(setq zoneNUM (strcat "%<\\AcVar CustomDP.zone1>%"))) ) (cond ((<= pt1y 4.68)(setq zoneLTR "%<\\AcVar CustomDP.zonea>%")) ((and (<= pt1y 9.34)(> pt1y 4.68)(setq zoneLTR "%<\\AcVar CustomDP.zoneb>%"))) ((and (<= pt1y 14.00)(> pt1y 9.34)(setq zoneLTR "%<\\AcVar CustomDP.zonec>%"))) ((and (<= pt1y 18.66)(> pt1y 14.00)(setq zoneLTR "%<\\AcVar CustomDP.zoned>%"))) ((and (<= pt1y 23.32)(> pt1y 18.66)(setq zoneLTR "%<\\AcVar CustomDP.zonee>%"))) ((> pt1y 23.32)(setq zoneLTR "%<\\AcVar CustomDP.zonef>%")) ) (setq mtstr (strcat zoneNUM "-" zoneLTR)) ) (progn (setq mobj (vla-AddMText (vlax-get (vla-get-ActiveDocument (vlax-get-acad-object) ) (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace) ) (vlax-3D-point (trans pt1 1 0)) 0 mtstr ) ) (vla-put-layer mobj "TEXT") (vla-put-height mobj 0.188) (vla-put-stylename mobj "romans") (vla-put-attachmentpoint mobj acAttachmentpointmiddlecenter) ) ) ) Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Hi Lonnie, Entmake'ing Fields is pretty difficult, as you have to also entmake the extension dictionary of the text, mtext or attribute and then the ACAD_FIELD dictionary stored within that and the TEXT dictionary stored within that... Hence the workaround is to use vla-AddMText to create the MText Field. Oh I see. Though I've been using more and more VL commands in my programs, I'm still figuring out new ones so thanks for the suggestion. I will try out your code and post the results later. Thanks again. Lonnie Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Ok so I've completely changed gears Lee and I'm hoping your lisp super powers can fix my lisp . While working on my Mtext insertion routine I was also putting together a very similar routine that inserts a Block with Attributes. There had been a lot of talk on the board recently about Block Attribute Editing/Extraction/Replacing so I thought I'd try my hand at putting something together that way. The routine I came up with works as it should. The block gets inserted at a user defined point and based on the location of the block on the drawing, the 1 and only attribute of the block gets populated with the appropriate fields. However if that block gets moved to another location then the fields don't update so I've had to come up with another routine that will update all blocks. That's where I'm stuck. Here's my code: (defun c:bu(/ Att1Tag ss_blocks NumBlocks Count Ename Attname Att_Data Att_txt pt1 pt1x pt1y mtstr NewStr New_Attdata) (setq Att1Tag "SV") (setq ss_blocks (ssget "_X" '((0 . "INSERT")(2 . "SECT_VIEW")))) (setq NumBlocks (sslength ss_blocks)) (setq Count 0) (repeat NumBlocks (setq Ename (ssname ss_blocks Count)) (setq Attname Ename) (while (= "ATTRIB" (dxf 0 (setq Attname (entnext Attname)))) (if (= Att1Tag (dxf 2 Attname)) (progn (setq Att_Data (entget Attname)) (setq Att_txt (cdr (assoc 1 Att_Data))) (setq pt1 (assoc 10 Att_Data)) (setq pt1x (cadr pt)) (setq pt1y (caddr pt)) (cond ((<= pt1x 5)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone8>%"))) ((and (<= pt1x 10)(> pt1x 5)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone7>%")))) ((and (<= pt1x 15)(> pt1x 10)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone6>%")))) ((and (<= pt1x 20)(> pt1x 15)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone5>%")))) ((and (<= pt1x 25)(> pt1x 20)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone4>%")))) ((and (<= pt1x 30)(> pt1x 25)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone3>%")))) ((and (<= pt1x 35)(> pt1x 30)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone2>%")))) ((> pt1x 35)(setq zoneNUM (strcat "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zone1>%"))) ) (cond ((<= pt1y 4.68)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zonea>%")) ((and (<= pt1y 9.34)(> pt1y 4.68)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zoneb>%"))) ((and (<= pt1y 14.00)(> pt1y 9.34)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zonec>%"))) ((and (<= pt1y 18.66)(> pt1y 14.00)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zoned>%"))) ((and (<= pt1y 23.32)(> pt1y 18.66)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zonee>%"))) ((> pt1y 23.32)(setq zoneLTR "%<[url="file://\\AcVar"]\\AcVar[/url] CustomDP.zonef>%")) ) (setq mtstr (strcat zoneNUM "-" zoneLTR)) (setq NewStr mtstr) (setq New_Attdata (subst (cons 1 NewStr)(assoc 1 Att_data) Att_Data)) (entmod New_Attdata) (entupd (cdr (assoc 330 Att_Data))) ); progn ); if ); while (setq Count (1+ Count)) ); repeat (redraw att1 1) (princ) ) (defun dxf (code e) (cdr (assoc code (entget e))) ) All blocks called "SECT_VIEW" have the tag "SV" and they all get updated by this routine but only to the value calculated by the last block evaulated. I mean each block should have a different value based on where they are located on the drawing but instead they all have the value that is tied to the last block of the selection set (I believe). Where am I going wrong? Lonnie Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 (edited) Hi Lonnie, Again, you will have to approach the problem using VL, unless you create the dictionary objects for the Field. Perhaps something like this? (defun c:bu ( / *error* _StartUndo _EndUndo _2D _FieldString doc ss Att Block ) (vl-load-com) ;; © Lee Mac 2010 (setq Att "SV" Block "SECT_VIEW") (defun *error* ( msg ) (and doc (_EndUndo doc)) (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*") (princ (strcat "\n** Error: " msg " **"))) (princ) ) (defun _StartUndo ( doc ) (_EndUndo doc) (vla-StartUndoMark doc) ) (defun _EndUndo ( doc ) (if (= 8 (logand 8 (getvar 'UNDOCTL))) (vla-EndUndoMark doc) ) ) (defun _2D ( p ) (list (car p) (cadr p))) (defun _GetInsertion ( o ) (if (eq AcAlignmentLeft (vla-get-Alignment o)) (vlax-get o 'InsertionPoint) (vlax-get o 'TextAlignmentPoint) ) ) (defun _FieldString ( x y ) (strcat "%<\\AcVar CustomDP.zone" (cond ( (<= x 5.0) "8") ( (and (< 5.0 x) (<= x 10.0)) "7" ) ( (and (< 10.0 x) (<= x 15.0)) "6" ) ( (and (< 15.0 x) (<= x 20.0)) "5" ) ( (and (< 20.0 x) (<= x 25.0)) "4" ) ( (and (< 25.0 x) (<= x 30.0)) "3" ) ( (and (< 30.0 x) (<= x 35.0)) "2" ) ( "1" ) ) ">%-%<\\AcVar CustomDP.zone" (cond ( (<= y 4.68) "a" ) ( (and (<= y 9.34)(> y 4.68)) "b" ) ( (and (<= y 14.00)(> y 9.34)) "c" ) ( (and (<= y 18.66)(> y 14.00)) "d" ) ( (and (<= y 23.32)(> y 18.66)) "e" ) ( "f" ) ) ">%" ) ) (setq doc (vla-get-ActiveDocument (vlax-get-acad-object))) (if (ssget "_X" (list (cons 0 "INSERT") (cons 2 Block) (cons 66 1))) (progn (_StartUndo doc) (vlax-for obj (setq ss (vla-get-ActiveSelectionSet doc)) (mapcar (function (lambda ( attrib ) (if (eq Att (vla-get-TagString attrib)) (vla-put-TextString attrib (apply '_FieldString (_2D (_GetInsertion attrib) ) ) ) ) ) ) (vlax-invoke obj 'GetAttributes) ) ) (vla-delete ss) (_EndUndo doc) ) ) (princ) ) Completely Untested of course. Edited October 7, 2010 by Lee Mac Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Lee, I'm getting the following error: ** Error: bad argument type: VLA-OBJECT "SV" ** I tried looking at your code to figure out what's going on but I'm like a tourist in a foreign country having only a High School class as the basis for my understanding of the language Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 My fault - that's what I get for writing it too quick lol. Code updated Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 What did you change? I've been looking at it and I'm trying to figure out the ins and outs of it but I'm getting nowhere.... BTW, thanks a heap. It works great! Lonnie Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Oh I changed one line of your code to better reflect just how awesome you are: ;; © Lee "The Superman of LISP" Mac 2010 Lonnie Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Ahh sorry, I changed: (vla-put-TextString Att .. to (vla-put-TextString attrib ... Att was the attribute string, attrib was the attribute object Thanks for your compliments, I'm glad the code works If you have any questions about the code, just shout. Lee Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Oops! Just noticed I forgot to set the undo marks - code updated Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 So as I'm looking at your code, because you format your code so well, I had a revelation. I was using fields in the Mtext that's created but I really don't need fields do I since the whole value for the "SV" tag is being replaced? I just tried it out without using the fields and it still works. Again thanks for all the help you give out both consciously and otherwise. There is no one (other than Alan, David and maybe a couple of others) who can't learn from the code you post here. Lonnie Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Many thanks for yor kind words Lonnie, happy that I could help Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Lee, One more thing, how would I make the text underlined? Before when I was making Mtext with ENTMAKEX, all I had to do was put a "\L" in front of the string but that doesn't work this way. Lonnie Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Are we talking about the code dealing with the attributes? Quote Link to comment Share on other sites More sharing options...
lfe011969 Posted October 7, 2010 Author Share Posted October 7, 2010 Nevermind Lee I figured it out myself. Putting the %%U in front of the string did the trick. I was confusing my routines. That's what I get for changing directions in the middle of this thread . Lonnie Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted October 7, 2010 Share Posted October 7, 2010 Excellent Quote Link to comment Share on other sites More sharing options...
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.