Lisp to Populate Title Block is populating the same value in all fields

Lisp to Populate Title Block is populating the same value in all fields

raceharder
Enthusiast Enthusiast
3,588 Views
45 Replies
Message 1 of 46

Lisp to Populate Title Block is populating the same value in all fields

raceharder
Enthusiast
Enthusiast

I have written this lisp to populate all fields on the title block using data from a text file.  The lisp is working, however every field is populated with the same piece of information.  I'm not sure where I have gone wrong and would appreciate any advice/direction that you all may have.

 

Here is the lisp:

 

(defun C:GVTBIN (/ unit)
  (PRINT "IN FTBIN")
  (setq unit "1A5")
  (GVTB UNIT)
)

(defun GVTB (UNIT / dwgnme homedir desclgth dwglen startpnt dwgnm len_dwgnm)
  (setq dwgnme (getvar "DWGNAME"))
  (setq homedir (getvar "DWGPREFIX"))

  (setq ttlfil (strcat homedir "GVOSStitleblk.txt"))
  (print "ttlfil is") (princ ttlfil)
  (setq f (open ttlfil "r"))
  (PRINT F)
  (print "dwgname is ") (print dwgnme)
  (print "homedir is ") (print homedir)

  (setq len_dwgnm 3) ;; char needed for last digits to get drawing num -- 3 usually
                     ;; 4 when you have an A, B or C in name      
  (setq desclgth (strlen DWGNME))
  (setq dwglen (- desclgth 3)) ; length without .dwg -- 4 digits
  (setq startpnt (- dwglen 3)) ; puts you at the start of the number part of drawing name    
  (setq DWGNM (substr DWGNME startpnt 2)) ;sheet number digits are usually 3

  (setq len_unit 8) ; puts you at the start of the number part of drawing name    
  (setq unit_stpnt (- dwglen (- len_unit 1 ))) ; puts you at the start of the number part of drawing name        

  ;; 12/2009 -- changed file name from the file name to just the last 8 digits with the .dwg extension
  (setq UNITNM (strcase (substr DWGNME unit_stpnt len_unit))) ;sheet number digits are usually 3

  (setq DWGNM (strcase (substr DWGNME startpnt len_dwgnm))) ;sheet number digits are usually 3
  (print "before strip dwgnm") (print DWGNM)

  (setq newv (read-line f))
  (PRINT newv)
  (PRINT F)
  (TAGFIND "Job_no" newv)
  (setq newv (read-line f))
  (TAGFIND "NAME_COMPANY" newv)
  (setq newv (read-line f))
  (TAGFIND "MAIN_IDENTIFIER" newv)
  (setq newv (read-line f))
  (TAGFIND "LOC_1" newv)
  (setq newv (read-line f))
  (TAGFIND "ADDRESS_1" newv)
  (setq newv (read-line f))
  (TAGFIND "ADDRESS_2" newv)
  (setq newv (read-line f))
  (TAGFIND "STRUTURE_1" newv)
  (setq newv (read-line f))
  (TAGFIND "RELEASE_1" newv)
  (setq newv (read-line f))
  (TAGFIND "RELEASE_2" newv)
  (setq newv (read-line f))
  (TAGFIND "CREATOR_1" newv)
  (setq newv (read-line f))
  (TAGFIND "CREATOR_2" newv)
  (setq newv (read-line f))
  (TAGFIND "CUSTOMER_CODE" newv)

  (print "before reading new variables and newv is ")(print newv)

  (close f)
)

(defun TAGFIND (tagname newv / tagname ss1 len count bn en el found attstr)
  (setq ss1 (ssget "X" '((2 . "Title Block GVOSS"))))
  (setq len (sslength ss1))
  (setq count 0)

  (repeat len
    (setq bn (ssname ss1 count)) ; Block Name
       (print bn)
    (print "")
    (setq en (entnext bn)) ; Entity Name
    (print en)
    (print "")
   
    (setq el (entget en)) ; Entity List
       (print el)
    (print "")

    (while (and (= "ATTRIB" (dxf 0 el))
                (/= "SEQEND" (dxf 0 el)))
      (if (= (dxf 2 el) (strcat tagname))
        (print tagname)
          (progn
            (print tagname)
            (setq attstr (dxf 1 el))
            (setq el (subst (cons 1 newv) (assoc 1 el) el))
            (entmod el) ; Modify List
            (entupd bn) ; Update Screen
            (setq found "yes") ; Found Tag?
          )
      )

      (setq en (entnext en)
            ;(while (and (entnext en) (/= "SEQEND" (dxf 0 el))))
            ;(print en) ; Add this line to print the entity handle
            el (entget en)
      )
    )

    (setq count (1+ count))
  )

  (if (/= found "yes")
      (princ "\nTag Not Found.")
  )
)

(defun dxf (code elist)
  (cdr (assoc code elist))
)
 
Thanks in advance for your help and please let me know if there is anything additionally you may need to help diagnose.
0 Likes
Accepted solutions (2)
3,589 Views
45 Replies
Replies (45)
Message 2 of 46

paullimapa
Mentor
Mentor

It would help if you can include sample dwg with that title block and "GVOSStitleblk.txt"


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 46

raceharder
Enthusiast
Enthusiast

Here are the samples you requested.

0 Likes
Message 4 of 46

paullimapa
Mentor
Mentor
Accepted solution

There were a few problems which prevented the attribute values from updating:

1. Wrong Block Name:

 

(setq ss1 (ssget "X" '((2 . "Title Block GVOSS"))))

 

Change to this:

 

(setq ss1 (ssget "X" '((2 . "GVOSSTITLEBLOCK"))))  ; title block name

 

2. Matching Attribute Tag Name:

 

(= (dxf 2 el) (strcat tagname))

 

Since there's a mixture of upper vs lower everything should be converted to uppercase to get a match:

 

(= (strcase (dxf 2 el)) (strcase tagname))

 

3. If match occurred you decided to princ instead of updating the value:

 

(print tagname)

 

This either should be commented out or placed after the progn:

 

          (progn ; then do the following when there's a match
            (print tagname)
            (setq attstr (dxf 1 el)) ; no need to get current attribute value
            (setq el (subst (cons 1 newv) (assoc 1 el) el))
            (entmod el) ; Modify List
            (entupd bn) ; Update Screen
            (setq found "yes") ; Found Tag?
          )
        (print tagname) ; this should be placed here if you want to see when no match

 

But after those are corrected now they update:

paullimapa_0-1715111560077.png

Also I'm not sure what you're doing with the part of the code where you're stripping down the drawing name since the test drawing name perhaps is named completely different:

 

  (setq dwgnme (getvar "DWGNAME"))
  (setq homedir (getvar "DWGPREFIX"))

  (setq ttlfil (strcat homedir "GVOSStitleblk.txt"))
  (print "ttlfil is") (princ ttlfil)
  (setq f (open ttlfil "r"))
  (PRINT F)
  (print "dwgname is ") (print dwgnme)
  (print "homedir is ") (print homedir)

  (setq len_dwgnm 3) ;; char needed for last digits to get drawing num -- 3 usually
                     ;; 4 when you have an A, B or C in name      
  (setq desclgth (strlen DWGNME))
  (setq dwglen (- desclgth 3)) ; length without .dwg -- 4 digits
  (setq startpnt (- dwglen 3)) ; puts you at the start of the number part of drawing name    
  (setq DWGNM (substr DWGNME startpnt 2)) ;sheet number digits are usually 3

  (setq len_unit  ; puts you at the start of the number part of drawing name    
  (setq unit_stpnt (- dwglen (- len_unit 1 ))) ; puts you at the start of the number part of drawing name        

  ;; 12/2009 -- changed file name from the file name to just the last 8 digits with the .dwg extension
  (setq UNITNM (strcase (substr DWGNME unit_stpnt len_unit))) ;sheet number digits are usually 3

  (setq DWGNM (strcase (substr DWGNME startpnt len_dwgnm))) ;sheet number digits are usually 3
  (print "before strip dwgnm") (print DWGNM)

 

Lastly, I moved your subfunctions dxf & TAGFIND under GVTB & GVTB under C:GVTBIN the main command so they're not separate and then can be localized within the main function. FYI: I typically list the localized functions and variables alphabetically so I know I'm not repeating the use of them:

(defun C:GVTBIN 
; localize functions and variables             
 (/  GVTB unit )
(defun GVTB 
; localize functions and variables alphabetically            
  (UNIT 
   /
   desclgth dwglen dwgnm dwgnme dxf f homedir len_dwgnm len_unit 
   newv startpnt TAGFIND ttlfil unit_stpnt UNITNM
  )
(defun dxf (code elist)
  (cdr (assoc code elist))
) ; defun dxf
(defun TAGFIND (tagname newv / ss1 len count bn en el found attstr)

See attached updated code.

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 5 of 46

raceharder
Enthusiast
Enthusiast

Thank you very much.   Works perfect. 

 

I am new to lisps and have just started working with them.  This was actually an adaptation of another lisp written by a coworker for a different application.  The stripping of the drawing name was to populate the page number in a block.   I appreciate that advice on organization and such.  

 

Thanks again for all your help.

0 Likes
Message 6 of 46

paullimapa
Mentor
Mentor

you're very welcome...this is a very good start in your steps to learn more how to code...just keep at it and look at various examples found on the web...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 46

Sea-Haven
Mentor
Mentor

Just a comment rather than using tag names if you organize the text file to match the attribute creation order, what you see when you edit attributes, and have a value for each attribute, you can just "getattributes" then "PUT" a new textstring into the attribute. 

 

But as you have a considerable number of attributes maybe look at the txt file as a csv file tagname,variable. Job_no,1234 

 

Thinking more as a global updater 1st line has block name. 

 

 

 

 

GVOSSTITLEBLOCK
Job_no,12345
NAME_COMPANY,FREDS
MAIN_IDENTIFIER,Isolate1

 

 

 

 

 

Can do code if you think is useful.

 

Then it can have 1-25 lines of values etc Make a csv file with all tag names and leave blank for do not change.

 

0 Likes
Message 8 of 46

raceharder
Enthusiast
Enthusiast
I appreciate the suggestion, however I think right now I need to better understand the code as written. I'm still learning so some of this doesn't make sense to me just yet. Maybe after I get a better grasp on what I am doing, I can look at streamlining some of these processes. Thank you again though for your suggestion.
0 Likes
Message 9 of 46

raceharder
Enthusiast
Enthusiast

I am having an issue with one of the fields that is being populated using this process.  Specifically the Loc_1 field.  The font height is too large to fit in the area designated for this field.  

 

So that you understand the entire process, we take the first sheet of the drawing set and manually update the title block.  We have a lisp that I have written that searches for the title block and then exports all the field values to a text file (GVOSStitleblock.txt).  We then run a script to replace the title block (Title Block GVOSS) with a new one (GVOSSTITLEBLOCK)  When we are manually updating the first page, we adjust all the text height's and width's so that everything fits in the designated spots.  We than run the lisp that you helped me with to update all the appropriate fields in the new title block (GVOSSTITLEBLOCK).

 

My problem is that the Loc_1 field is not retaining the height setting and does not fit in the designated area in the title block.  Is there a way to make it retain those settings?

 

Thank you in advance for your help.

 

Race

0 Likes
Message 10 of 46

paullimapa
Mentor
Mentor

Attribute heights are retained per block and any changes you should be able update each instance with the ATTSYNC command. Perhaps you can provide the code you're running to change the height so we can take a look what is not retained?


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 11 of 46

raceharder
Enthusiast
Enthusiast

I am not actually using code to change the text height.  It is just manually adjusted on the first drawing of the set to fit in the defined area.  Once we manually update the first page, the text height for this field is set to .086.  When we run the GVTBIN lisp to bring the data back into the new title block, the height for that field is now set to 0.096599409448819.  

 

I assumed that the height, width, font, etc would all be retained in the GVTBIN process.  

 

I guess that is why I shouldn't assume things.  LOL

0 Likes
Message 12 of 46

paullimapa
Mentor
Mentor

Since that height changes depending on the sheet name per project you may have to  include that value somewhere like in the first line of that text file you’re reading and then the code can make sure that height is changed to match


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 13 of 46

raceharder
Enthusiast
Enthusiast

I follow what you are saying there.  I will work on that and see if I can figure it out.  In the meantime, I have found that in the template files that we start with, the title blocks have different names.  Some are called "Title Block GVOSS" and some are called "Frame".  Is it possible to have the GVTBIN lisp look for either block and populate whichever it finds?  The blocks are identical, they just have different names.  If it is possible to make the code do this, I can eliminate a step in the process and make things a bit easier.  I'm just not sure if it is possible to do an "or" in lisp or not.  Thanks in advance for your help.

0 Likes
Message 14 of 46

paullimapa
Mentor
Mentor

yes just modify this line of code separating the block names with a comma for example:

(setq ss1 (ssget "X" '((2 . "GVOSSTITLEBLOCK,Frame"))))  ; title block name

This assumes the Attribute Tag names didn't change of course. 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 15 of 46

raceharder
Enthusiast
Enthusiast

Figures it would be something that easy!  LOL.  I was looking all over for the proper syntax and was way off on my guess.  

 

I do appreciate your time.  This worked and will make this whole process smoother and easier.  

 

Thank you very much for all your help.

 

Race

0 Likes
Message 16 of 46

paullimapa
Mentor
Mentor

once again glad to have helped...cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 17 of 46

Sea-Haven
Mentor
Mentor

As per suggestion about using a csv file but with multi possible block names.

 

 

GVOSSTITLEBLOCK,FRAME
Job_no,12345
NAME_COMPANY,FREDS
MAIN_IDENTIFIER,Isolate1

 

 

 

 

 Would just look at 1 st line and if (length newline) is more than 1 join the string back into multi block names. "GVOSSTITLEBLOCK,FRAME"  For use in the ssget.

0 Likes
Message 18 of 46

raceharder
Enthusiast
Enthusiast

Upon further testing and review, I did find that 2 of the fields had one name in Title Block GVOSS and a different name in FRAME.  The 2 fields are Loc_1 (called this in Title Block GVOSS and called Location in FRAME) and C_1 (called this in Title Block GVOSS and called Customer_Code in FRAME). 

 

Can you give me some suggestions on how to handle this?  

 

Your answers have been extremely helpful and I do appreciate all your help and time.

0 Likes
Message 19 of 46

paullimapa
Mentor
Mentor

Then just do the folllowing:

replace this line:

  (TAGFIND "LOC_1" newv)

with these:

  (TAGFIND "LOC_1" newv)
  (TAGFIND "Location" newv)

and replace this line:

  (TAGFIND "CUSTOMER_CODE" newv)

with these:

  (TAGFIND "CUSTOMER_CODE" newv)
  (TAGFIND "C_1" newv)

Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 20 of 46

raceharder
Enthusiast
Enthusiast

I apologize for more questions.

 

There are more differences in the tag names between the 2 blocks, so I think what I need to do is look at which title block is on the page and run the code containing the correct tag names for the block that is in the drawing.  I just don't know what the syntax for this would be.  Is it possible you could give me an example?

0 Likes