Results 1 to 3 of 3

Thread: My Sub Function only runs once...?

  1. #1
    Member
    Join Date
    2011-05
    Posts
    3
    Login to Give a bone
    0

    Default My Sub Function only runs once...?

    Greetings all,

    I am finishing up a long lisp routine that standardizes a Layout, Title Block and Revision Block, and I seem to stuck with the final icing on the cake, so to speak.

    (Also I can't seem to figure out how to properly post autolisp code, so forgive me if I posted my code improperly.... and I did search for how to do it properly.)

    Basically this routine adds a new Layout with said Title Block and one Rev Block (and a Viewport) properly configured. It swiches to the improper (old) Layout with same blocks, only the exisinting blocks are often filled in with good information.

    It then copies all the blocks from the existing (source) Layout, switches to the New Layout and pastes them at an offset 2 inches to the right because of our vertical title block. It then grabs all the Ent Names necessary to copy attributes.

    Then at the very end, where I modified a pretty standard lisp I've used for years and included it as my sub function. My first call to copy all the Attributes from the old Insert to the new title block Insert works like a charm, but the subsequent calls to copy Attributes from my 2 Rev Blocks don't work. The original COPYATTR.LSP has you select the old block, new block and works perfectly from the command prompt.

    (Maybe someone can point me to one that works from Ent Names, or I may just write my own, but I'm trying to get the project off my desk... full disclosure here: I've looked at it too long.)

    The messages print, indicating that the code ran, but the target Rev Blocks don't get the Source Rev Block attributes. What am I missing?

    And I know there's some junk in here still for troubleshooting, I'll clean it up.

    Thanks, Bill~

    Code:
      (copyattr SrcTbEname TargetTbEName)
      (princ "\nTitleBlock Attributes copied...\n")
      (copyattr SrcRevBlk1Ename TargetRevBlk1Ename)
      (princ "\nRevision Block 1 Attributes copied...\n")
      (cond ((= 3 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (princ "\nRevision Block 2 Attributes copied...\n")
            )
            ((= 4 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (copyattr SrcRevBlk3Ename TargetRevBlk3Ename)
            )
            ((= 5 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (copyattr SrcRevBlk3Ename TargetRevBlk3Ename)
              (copyattr SrcRevBlk4Ename TargetRevBlk4Ename)
            )
      ) ;cond
      (setvar "cmdecho" cmde)
      (setvar "attdia" attdia)
      (princ)
    ) ;defun
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;TIP1045B.LSP:  COPYATTR.LSP     Attribute Utilities     (C)1994, Robert L. Zipprich
    (defun copyattr (BLK1 BLK2 / BLK1 BLK2 DATA1 DATA2 BLKNAME INSPT BLKENT SWDATA)
      ; BLK1 is source block with attributes to copy
      ; Blk2 is new target block to get attributes from the original source block
      (setq EBLK1 BLK1)   ; to erase old block
      (setq DATA1 (entget BLK1))
      (setq DATA2 (entget BLK2))
    ;  (setq BLK2 TargetTbEname DATA2 TargetTbData)     ;primes the pump
    
    ;  (setq BLKNAME (cdr (assoc 2  (entget EBLK1)))
      (setq BLKNAME (cdr (assoc 2  (entget BLK1)))
         INSPT   (cdr (assoc 10 (entget BLK2)))
      )
      ;---------------
      (setq BLK1 (entnext BLK1) DATA1 (entget BLK1))     ;primes the pump
      (while (/= "SEQEND" (cdr (assoc 0 DATA1)))         ;steps from ent to ent in 1st blk
          (if (setq TAGNAME1 (cdr (assoc 2 DATA1)))      ;if ent is attrib
             (progn
                (setq SWDATA (cdr (assoc 1 DATA1)))       ;1st attrib value
                (setq BLKENT (entnext BLK2) DATA2 (entget BLKENT))  ;next ent in 2nd blk
                (while (/= "SEQEND" (cdr (assoc 0 DATA2)))
                   (if (eq TAGNAME1 (cdr (assoc 2 DATA2)))  ;if tags match
                      (progn
                         (Setq DATA2 (subst (cons 1 SWDATA) (assoc 1 DATA2) DATA2))
                         (entmod DATA2)             ;modifies 2nd attrib value
                         (setq BLKENT (entnext BLKENT) DATA2 (entget BLKENT)) ;set to next ent in 2nd blk
                      )
                      (setq BLKENT (entnext BLKENT) DATA2 (entget BLKENT)) ;set to next ent in 2nd blk
                   )
                )
                (setq BLK1 (entnext BLK1) DATA1 (entget BLK1)) ;set to next ent in 1st blk
             )
             (setq BLK1 (entnext BLK1) DATA1 (entget BLK1)) ;set to next ent in 1st blk
          )
      )
      (entmod (entget BLK2))
      (setq BLK1 nil Blk2 nil Data1 nil Data2 nil)
      (princ)
    ) ; end defun
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    
    
    Here's what I have done so far:
    
    (defun c:UPTB ()
      :
      :
        ; some amazing nice coding here
      :
      :
    
      (copyattr SrcTbEname TargetTbEName)
      (princ "\nTitleBlock Attributes copied...\n")
      (copyattr SrcRevBlk1Ename TargetRevBlk1Ename)
      (princ "\nRevision Block 1 Attributes copied...\n")
      (cond ((= 3 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (princ "\nRevision Block 2 Attributes copied...\n")
            )
            ((= 4 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (copyattr SrcRevBlk3Ename TargetRevBlk3Ename)
            )
            ((= 5 BlkCnt)
              (copyattr SrcRevBlk2Ename TargetRevBlk2Ename)
              (copyattr SrcRevBlk3Ename TargetRevBlk3Ename)
              (copyattr SrcRevBlk4Ename TargetRevBlk4Ename)
            )
      ) ;cond
      (setvar "cmdecho" cmde)
      (setvar "attdia" attdia)
      (princ)
    ) ;defun
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;TIP1045B.LSP:  COPYATTR.LSP     Attribute Utilities     (C)1994, Robert L. Zipprich
    (defun copyattr (BLK1 BLK2 / BLK1 BLK2 DATA1 DATA2 BLKNAME INSPT BLKENT SWDATA)
      ; BLK1 is source block with attributes to copy
      ; Blk2 is new target block to get attributes from the original source block
      (setq EBLK1 BLK1)   ; to erase old block
      (setq DATA1 (entget BLK1))
      (setq DATA2 (entget BLK2))
    ;  (setq BLK2 TargetTbEname DATA2 TargetTbData)     ;primes the pump
    
    ;  (setq BLKNAME (cdr (assoc 2  (entget EBLK1)))
      (setq BLKNAME (cdr (assoc 2  (entget BLK1)))
         INSPT   (cdr (assoc 10 (entget BLK2)))
      )
      ;---------------
      (setq BLK1 (entnext BLK1) DATA1 (entget BLK1))     ;primes the pump
      (while (/= "SEQEND" (cdr (assoc 0 DATA1)))         ;steps from ent to ent in 1st blk
          (if (setq TAGNAME1 (cdr (assoc 2 DATA1)))      ;if ent is attrib
             (progn
                (setq SWDATA (cdr (assoc 1 DATA1)))       ;1st attrib value
                (setq BLKENT (entnext BLK2) DATA2 (entget BLKENT))  ;next ent in 2nd blk
                (while (/= "SEQEND" (cdr (assoc 0 DATA2)))
                   (if (eq TAGNAME1 (cdr (assoc 2 DATA2)))  ;if tags match
                      (progn
                         (Setq DATA2 (subst (cons 1 SWDATA) (assoc 1 DATA2) DATA2))
                         (entmod DATA2)             ;modifies 2nd attrib value
                         (setq BLKENT (entnext BLKENT) DATA2 (entget BLKENT)) ;set to next ent in 2nd blk
                      )
                      (setq BLKENT (entnext BLKENT) DATA2 (entget BLKENT)) ;set to next ent in 2nd blk
                   )
                )
                (setq BLK1 (entnext BLK1) DATA1 (entget BLK1)) ;set to next ent in 1st blk
             )
             (setq BLK1 (entnext BLK1) DATA1 (entget BLK1)) ;set to next ent in 1st blk
          )
      )
      (entmod (entget BLK2))
      (setq BLK1 nil Blk2 nil Data1 nil Data2 nil)
      (princ)
    ) ; end defun
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    Last edited by rkmcswain; 2017-03-22 at 10:58 AM. Reason: Added [CODE] tags

  2. #2
    Certifiable AUGI Addict
    Join Date
    2001-03
    Location
    Tallahassee, FL USA
    Posts
    3,667
    Login to Give a bone
    0

    Default Re: My Sub Function only runs once...?

    You may want to edit that post, everything is duplicated and confusing.

    Ignoring that, I'd recommend keeping COPYATTR.LSP as a separate routine and simply loading it at the start of your's. I'd also assume COPYATTR.LSP isn't the problem.

    Without seeing the full code since it worked on the Title block, but not the Rev Blocks my guess would be that the block entity names were either incorrect or no longer in the drawing. Try replacing
    Code:
    (princ "\nRevision Block 1 Attributes copied...\n")
    with
    Code:
    (princ "\n(entget BLK1) = ")(princ (entget BLK1))(princ "\n(entget BLK2) = ")(princ (entget BLK2))
    to see if those are the Rev Blocks.

    No way to test without all the code, blocks, and drawings involved. You need to examine how you got those Rev Block entity names.

  3. #3
    Member
    Join Date
    2011-05
    Posts
    3
    Login to Give a bone
    0

    Default Re: My Sub Function only runs once...?

    Thanks Tom,

    I see what you mean. I pasted the code in there twice by mistake.... pretty fugly, sorry about that.

    I'm looking at the Rev Blocks in detail and I see that one of the Tag names is "Description1" and the other is "DESCRIPTION1" which of course are not equal and get skipped. But there are only 6 ATTRIBUTES in the Rev Block and the tag names are the same in each (other than the case).

    But upon a closer look, 5 of the 6 differ in case, so I think I found it myself. It's good to know your = EQ & EQUAL, although they are all case sensitive it seems, so I'll just do up a STRCASE in that function. Nothing like a good nights sleep to give you a fresh perspective!

    The old RevBlock definition prompted for values upon insert and I didn't want the user to have to do that, so I made the newer RevBloc with Presets so it doesn't prompt upon Insert. I think on our Acad 2017 all ATTDEF's are uppercase by default but you can go back and change them if you want to.

    As I mentioned, the original COPYATTR.LSP uses ENTSEL so that's not an option as I am building a function to completely update and automate the process with no user interaction.

    But having the mixed case in the new RevBlocks might be a good thing, as a way to check to see if it's the correct block. I knew it would be handing to tell a difference because they look and act almost identical. The main reason for creating a new standard was due to plotting issues with the wide PLINE overstepping the plot boundary by a whisker.

    I appreciate your comments about actually printing the (entget BLK1), but I have thoroughly been through all the logic and have convinced myself I've got that part correct. I tend to test that with issuing the COPY command at the Command Prompt and then feeding it !BLK1 !BLK2 and then canceling.

    I thought of including my blocks after I posted, but that got me thinking further and now I think I have the solution.

    Thanks again, B~

Similar Threads

  1. Get the element ids of conduit runs
    By mark.galba615743 in forum Dot Net API
    Replies: 1
    Last Post: 2014-05-13, 01:39 PM
  2. Home Runs
    By trythefly in forum Revit MEP - General
    Replies: 2
    Last Post: 2009-01-08, 07:35 PM
  3. pipe runs
    By mckenziewesley in forum Inventor - General
    Replies: 1
    Last Post: 2008-04-26, 03:36 AM
  4. Change the F1 function key to perform some other function
    By Spanky in forum AutoCAD Customization
    Replies: 7
    Last Post: 2007-11-28, 04:14 PM
  5. Help with Sub Function and calling it from main Function
    By avinash00002002 in forum VBA/COM Interop
    Replies: 1
    Last Post: 2006-06-21, 02:20 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •