Jump to content

Can a lisp be used to force a value change of a specific tag?


Recommended Posts

Posted
The titleblock has a multitude of attributes with the same tag...

 

My employer's former titleblocks (for use with LDD 2006) had this same issue, and it was very frustrating.

 

Our solution...

 

Late last year (yeah, 3+ years we used the old stuff! :sick:), we re-created all of our titleblocks with *unique* attributes, deployed LDC 2009, and also rolled out .dst files which include custom properties (linked to the attributes) for use with SSM. :thumbsup:

  • Replies 51
  • Created
  • Last Reply

Top Posters In This Topic

  • Cat

    20

  • David Bethel

    12

  • BlackBox

    12

  • Lee Mac

    5

Top Posters In This Topic

Posted Images

Posted
That's ugly....

 

Is there any logic to the scenario? 1st tag is always the name, 2nd the date, 3rd the city etc?

 

Do you have the handle values? and their respective descriptions?

 

-David

 

David,

I think I've reached the end of the rainbow as far as being able to maintain their titleblock.

It seems these guys have no clue that "Text" exists. The handles are NOT consistent from drawing to drawing. The only consistency is the Prompt they used per revision.

 

I think I only have three options. Edit them manually, redine an edited titleblock or special explode them and run a script to revise the text.

 

there....I said it....THERE IS SUCH A THING AS "TEXT".

 

You know, we could really use an emoticon that pulls it's hair out or strikes a match and sets it's head on fire.

Posted
The handles are NOT consistent from drawing to drawing.

 

Did you expect them to be? Handles are uniquely generated by AutoCAD for each object and remain fixed for the lifetime of the object.

Posted

Just curious...

 

Do these like-named attributes have similar insertion points from drawing to drawing (i.e., the Titleblock is always inserted at 0, 0 in paperspace)..?

 

If not, are said attribute insertion points relative to the insertion point of the Titleblock...?

Posted
Did you expect them to be? Handles are uniquely generated by AutoCAD for each object and remain fixed for the lifetime of the object.

 

Actually, now that the fog has lifted....no....I don't expect them to be.

 

But honestly, after mucking about in these particular drawings for over a week I have developed a Rhett Butler attitude....."Frankly, my dear, I don't give a ........"

Posted

RenderMan, no....the folks that did these drawings evidently aren't familiar with the way things should be done.

This is what I'm dealing with. They were last done in ELCAD and may have started out in Promise-E, I'm not sure. I tried to attach a pdf, but the file was to large. They have everything but the kitchen sink embedded in these dwgs.

 

TB.jpg

Posted
The only consistency is the Prompt they used per revision.

 

Prompts are good enough.

 

The ATTDEFs and ATTRIButes can be deciphered as long as no one has (entmod) certain parts of the ATTRIB Def in the INSERT ( groups 7, 10, 11, 50, & 51 ) or actually deleted or added ATTRIBs via Autolisp.

 

As to the handles, I would have to check, but if the titleblock is part of the template file, they might be consistent.

 

-David

Posted
Prompts are good enough.

 

 

vla-get-promptstring, and vla-put-textstring, perhaps?

 

Example:

 

(defun c:FOO  (/ eName blockObj blockName blockItem attPrompt)
 (vl-load-com)
 (if (and (setq eName (car (entsel "\n  >>  Select Attributed Title Block: ")))
          (setq blockObj (vlax-ename->vla-object eName))
          (= "[color=red]TitleBlockName[/color]" (setq blockName (vla-get-effectivename blockObj)))
          (setq blockItem (vla-item
                            (vla-get-blocks
                              (vla-get-activedocument
                                (vlax-get-acad-object)))
                            blockName))
          (= :vlax-true (vla-get-hasattributes blockObj)))
   (foreach attrib  (vlax-invoke blockObj 'GetAttributes)
     (vlax-for item  blockItem
       (if (= "AcDbAttributeDefinition" (vla-get-objectname item))
         (progn
           (if (= (vla-get-tagstring attrib)
                  (vla-get-tagstring item))
          (cond
            ((= "[color=red]Prompt1[/color]"
                (setq attPrompt (vla-get-promptstring item)))
               (vla-put-textstring attrib "[color=red]NewString1[/color]"))
            ((= "[color=red]Prompt2[/color]" attPrompt)
             (vla-put-textstring attrib "[color=red]NewString2[/color]"))
            ((= "[color=red]Prompt3[/color]" attPrompt)
             (vla-put-textstring attrib "[color=red]NewString3[/color]"))))))))
   (prompt "\n  <!> Invalid Selection  <!> "))
 (princ))

Posted

Thank you RenderMan. I'll give it a try.

Posted
Thank you RenderMan. I'll give it a try.

 

Well, I attempted to adapt the code, but apparently I've made an error somewhere along the line :shock: because it puts my intials - TAC - in all the values.

 

Can this be modified as to not require user input per drawing? Assuming I can get beyond the initial issue?

 

 
(defun c:chgpromptvalue  (/ eName blockObj blockName blockItem attPrompt)
 (vl-load-com)
 (if (and (setq eName (car (entsel "\n  >>  Select Attributed Title Block: ")))
          (setq blockObj (vlax-ename->vla-object eName))
          (= "FBSTP2_ANSI" (setq blockName (vla-get-effectivename blockObj)))
          (setq blockItem (vla-item
                            (vla-get-blocks
                              (vla-get-activedocument
                                (vlax-get-acad-object)))
                            blockName))
          (= :vlax-true (vla-get-hasattributes blockObj)))
   (foreach attrib  (vlax-invoke blockObj 'GetAttributes)
     (vlax-for item  blockItem
       (if (= "AcDbAttributeDefinition" (vla-get-objectname item))
         (progn
           (if (= (vla-get-tagstring attrib)
                  (vla-get-tagstring item))
          (cond
            ((= "C Status (display)"
                (setq attPrompt (vla-get-promptstring item)))
               (vla-put-textstring attrib "1"))
            ((= "C Revision (display)" attPrompt)
             (vla-put-textstring attrib "AS COMMISSIONED"))
            ((= "C Date (display)" attPrompt)
             (vla-put-textstring attrib "10-06-10"))
            ((= "C Name (display)" attPrompt)
             (vla-put-textstring attrib "TAC"))
            ((= "B Status (display)"
                (setq attPrompt (vla-get-promptstring item)))
               (vla-put-textstring attrib " "))
            ((= "B Revision (display)" attPrompt)
             (vla-put-textstring attrib " "))
            ((= "B Date (display)" attPrompt)
             (vla-put-textstring attrib " "))
            ((= "B Name (display)" attPrompt)
             (vla-put-textstring attrib " "))
            ((= "A Status (display)"
                (setq attPrompt (vla-get-promptstring item)))
               (vla-put-textstring attrib " "))
            ((= "A Revision (display)" attPrompt)
             (vla-put-textstring attrib " "))
            ((= "A Date (display)" attPrompt)
             (vla-put-textstring attrib " "))
            ((= "A Name (display)" attPrompt)
             (vla-put-textstring attrib " "))))))))
   (prompt "\n  <!> Invalid Selection  <!> "))
 (princ))

Posted
Well, I attempted to adapt the code, but apparently I've made an error somewhere along the line :shock: because it puts my intials - TAC - in all the values.

 

Can this be modified as to not require user input per drawing? Assuming I can get beyond the initial issue?

 

 

Perhaps this may be more to your liking (provided I've not overlooked something):

 

(defun c:chgpromptvalue  (/ ss)
 (vl-load-com)
 (if (setq ss (ssget "_x" '((0 . "INSERT") (2 . "FBSTP2_ANSI"))))
   ((lambda (i b / blockObj blockName blockItem attPrompt)
      (while (setq e (ssname ss (setq i (1+ i))))
        (if (and (setq blockObj (vlax-ename->vla-object e))
                 (setq blockName (vla-get-effectivename blockObj))
                 (setq blockItem (vla-item b blockName))
                 (= :vlax-true (vla-get-hasattributes blockObj)))
          (foreach attrib  (vlax-invoke blockObj 'GetAttributes)
            (vlax-for item  blockItem
              (if (and (= "AcDbAttributeDefinition"
                          (vla-get-objectname item))
                       (= (vla-get-tagstring attrib)
                          (vla-get-tagstring item)))
                (cond
                  ((= "C Status (display)"
                      (setq attPrompt (vla-get-promptstring item)))
                   (vla-put-textstring attrib "1"))
                  ((= "C Revision (display)" attPrompt)
                   (vla-put-textstring attrib "AS COMMISSIONED"))
                  ((= "C Date (display)" attPrompt)
                   (vla-put-textstring attrib "10-06-10"))
                  ((= "C Name (display)" attPrompt)
                   (vla-put-textstring attrib "TAC"))
                  ((= "B Status (display)"
                      (setq attPrompt (vla-get-promptstring item)))
                   (vla-put-textstring attrib " "))
                  ((= "B Revision (display)" attPrompt)
                   (vla-put-textstring attrib " "))
                  ((= "B Date (display)" attPrompt)
                   (vla-put-textstring attrib " "))
                  ((= "B Name (display)" attPrompt)
                   (vla-put-textstring attrib " "))
                  ((= "A Status (display)"
                      (setq attPrompt (vla-get-promptstring item)))
                   (vla-put-textstring attrib " "))
                  ((= "A Revision (display)" attPrompt)
                   (vla-put-textstring attrib " "))
                  ((= "A Date (display)" attPrompt)
                   (vla-put-textstring attrib " "))
                  ((= "A Name (display)" attPrompt)
                   (vla-put-textstring attrib " ")))))))))
     -1
     (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
   (prompt "\n  <!> Invalid Selection  <!> "))
 (princ))

Posted

Renderman,

I really appreciate all of your efforts, but it's still putting my initials in all of the values. I thought it might be because I had used a space for the values in all the tags relating to A and B, but I replaced the spaces with a "." and it still uses my initials for all the values. It may be an issue on my end with these particular drawings.

Posted

That's too bad.

 

It may be an issue on my end with these particular drawings.

 

 

*IF* you can post a DWG of just the title block itself (2007 format or older), then I'd be willing to take one more crack at it. Without a drawing to look at, I'm not sure I can help.

Posted
That's too bad.

 

 

 

 

*IF* you can post a DWG of just the title block itself (2007 format or older), then I'd be willing to take one more crack at it. Without a drawing to look at, I'm not sure I can help.

 

For better or worse, here's the titleblock. I appreciate you taking the time to have a look at it.

If it's too much of a pain, don't worry about it. I'll just blow them to kingdom come and be done with it.

TB.dwg

Posted

I've got the drawing, and I'll post back as soon as I can... This drawing is Sooooooooo Slllooooooooooooooooooooooooow! lol

Posted

I know....everytime I try to do anything with them, Autocad develops Dysentery.

Posted (edited)

Perhaps another way to code it Renderman - this should be much quicker:

 

(defun c:test ( / Block Attribs _MAssoc _dxf def l ss )
 ;; © Lee Mac 2010

 (setq Block "FBSTP2_ANSI")

 (setq Attribs ; Prompt . Value
   '(  
      ("C Status (display)"   . "1")
      ("C Revision (display)" . "AS COMMISSIONED")
      ("C Date (display)"     . "10-06-10")
      ("C Name (display)"     . "TAC")
    )
 )

 (defun _dxf ( key lst ) (cdr (assoc key lst)))

 (defun _Massoc ( key lst / r )
   (foreach x lst
     (if (eq key (car x))
       (setq r (cons (cdr x) r))
     )
   )
   (reverse r)
 )

 (if (setq def (tblobjname "BLOCK" Block))
   (while (setq def (entnext def))
     (if (eq "ATTDEF" (_dxf 0 (setq el (entget def))))
       (setq l (cons (cons (_dxf 2 el) (_dxf 3 el)) l))
     )
   )
 )

 (if (and l (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 Block) (cons 66 1)))))
   (
     (lambda ( i / e p v )
       (while (setq e (ssname ss (setq i (1+ i))))
         (while
           (not
             (eq "SEQEND"
               (_dxf 0
                 (entget
                   (setq e (entnext e))
                 )
               )
             )
           )
           (if (and (setq p (_Massoc (_dxf 2 (entget e)) l))
                    (progn
                      (while (and p (not (setq v (cdr (assoc (car p) Attribs)))))
                        (setq p (cdr p))
                      )
                      v
                    )
               )
             (entupd
               (cdr
                 (assoc -1
                   (entmod
                     (subst (cons 1 v)
                       (assoc 1 (entget e)) (entget e)
                     )
                   )
                 )
               )
             )
           )
         )
       )
     )
     -1
   )
 )

 (princ)
)

Completely untested however.

 

>> Cat: Be sure that the Attribute Prompt list at the top is absolutely correct.

Edited by Lee Mac
Posted

Unfortunately, this code does not succeed either, Lee. :(

 

Edit: While I see the elegence in your code, I still do not understand (at a glance) why my cond statement allows for multiple attribute definitions (each with a different PromptString!) to trigger the same expression.

 

Sidebar - What's up with the 'Edit' feature not including the spell check button!? Edits don't need spell check!?? lol

Posted
Unfortunately, this code does not succeed either, Lee. :(

 

Ahh no - course it won't needs a 'massoc' :oops:

Posted
Ahh no - course it won't needs a 'massoc' :oops:

 

Will this do the trick?

 

;;; Utility function to get multiple group code CDRs
(defun massoc (key alist / x nlist)
 (foreach x alist
   (if (eq key (car x))
     (setq nlist (cons (cdr x) nlist))
   )
 )
 (reverse nlist)
)

 

 

Edit: I've never heard of 'massoc' until I Googled it, so I'm not sure what to do with it (yet).

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