Create a block with attributes

Create a block with attributes

etilley327KA
Advocate Advocate
2,141 Views
13 Replies
Message 1 of 14

Create a block with attributes

etilley327KA
Advocate
Advocate

Im not having any luck on creating a block attribute similar to a carlson point. Im trying to create it where the overall name is insert, it has an attribute called Elev2 that holds the number given and a plus symbol as an attribute. Could someone show me how to write this?

 

(defun c:TEST (/ symName insertionPoint elev2Value point blkName)
  (setq symName "+")
  (setq insertionPoint (getpoint "\nSpecify insertion point: "))
  (setq elev2Value (getreal "\nEnter the ELEV2 value: "))
  (setq point (list
                  (cons 0 "INSERT")
                  (cons 2 "pntblk")
                  (cons 8 "-DRN")
                  (cons 10 insertionPoint)
                  (list (cons 0 "ATTRIB")
                        (cons 2 "SYMBOL")
                        (cons 10 insertionPoint)
                        (cons 40 1)
                        (cons 1 symName)
                  )
                  (list (cons 0 "ATTRIB")
                        (cons 2 "ELEV2")
                        (cons 10 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))
                        (cons 40 1)
                        (cons 1 (rtos elev2Value 2 2))
                  )
              )
  )
  (entmake point)
  (setq blkName (cdr (assoc 2 point)))
  (command "_.INSERT" blkName insertionPoint 1.0 1.0 0.0)
  (princ)
)
0 Likes
Accepted solutions (1)
2,142 Views
13 Replies
Replies (13)
Message 2 of 14

ВeekeeCZ
Consultant
Consultant

HERE is a great example for you from @CADaSchtroumpf 

 

You need to ENTMAKE the BLOCK+ATTDEF+ENDBLK definition first, then you can use INSERT command or ENTMAKE INSERT+ATTRIB reference. What you are doing now is creating a block reference by two different methods.

0 Likes
Message 3 of 14

paullimapa
Mentor
Mentor

You can take a look at my AOL app code and follow that entmake procedure.

I first call the function that creates the Text Style that I want my Attribute Definitions to use:

  (defun aol_make_style (aol_sty_name aol_sty_font aol_sty_height aol_sty_width)
     (entmake
      (list
       '(0 . "STYLE")
       '(100 . "AcDbSymbolTableRecord")
       '(100 . "AcDbTextStyleTableRecord")
        (cons 2 aol_sty_name) ;;Style name
       '(70 . 0) ;;Standard flag values (bit-coded values)
        (cons 40 aol_sty_height)
        (cons 41 aol_sty_width)
       '(50 . 0.0) ;;oblique angle 
       '(71 . 0) ;;text generation "0" normal text
       '(42 . 0) ;;last height used
        (cons 3 aol_sty_font) ;;font file name
       '(4 . "") ;;bigfont (blank for no)
       );end LIST
     );end entmake
     (princ)
  ) ; defun

Then I go through the following steps to create the Block with 2 Attributes:

    (entmake (list '(0 . "BLOCK") (cons 2 blkname) '(70 . 2) (cons 8 clayer) '(10 0 0 0)'(4 . "AOL Space Area"))) ;_ end of block
;       1=The default value ; 2 =Tag   ; 3 =Promt
    (entmake (list '(0 . "ATTDEF") (cons 8 clayer) '(10 0 0 0) '(70 . 0) '(3 . "Space Name") '(2 . "AOL-Space") '(1 . "SPACE NAME")
           (cons 40 htx) (cons 41 wdy) (cons 7 styname) '(11 0 0 0) '(72 . 1) '(74 . 2))
    )
    (entmake (list '(0 . "ATTDEF") (cons 8 clayer) '(10 0 -0.1864 0) '(70 . 0) '(3 . "Space Area") '(2 . "AOL-Area") '(1 . "Area:")
  	   (cons 40 htx) (cons 41 wdy) (cons 7 styname) '(11 0 -0.1864 0) '(72 . 1) '(74 . 2))
    ) 
    (entmake '((0 . "ENDBLK")) ) ;_ end of block with attdef

 


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

etilley327KA
Advocate
Advocate

I cant figure this out, how do I do this? I tried to follow the process Kent showed in the link. 

(defun c:TEST (/ insertionPoint elev2Value blkRef attr1 attr2 blkEnt blk)
 
  (setq insertionPoint (getpoint "\nSpecify insertion point: "))
  (setq elev2Value 2)

  (setq blkRef (entmake (list
                '(0 . "INSERT")
                (cons 2 "SRVPNOC")
                (cons 8 "-DRN")
                (cons 10 insertionPoint)
                (cons 41 0.8)
                (cons 42 0.8)
                (cons 43 0.8)
                (cons 44 0.0)
                (cons 45 0.0)
                (cons 50 0.0)
                (cons 66 1)
                (cons 100 "AcDbEntity")
              )))

(setq attr1 (entmake (list
              '(0 . "ATTRIB")
              (cons 8 "-DRNMARK")
              (cons 10 insertionPoint)
              (cons 41 0.8)
              (cons 1 "+")
              (cons 2 "MARK")
              (cons 7 "STANDARD")
              (cons 100 "AcDbAttribute")
              (cons 70 0)
              (cons 71 0)
              (cons 72 0)
            )))

(setq attr2 (entmake (list
              '(0 . "ATTRIB")
              (cons 8 "-DRNELEV")
              (cons 10 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))
              (cons 41 0.8)
              (cons 1 (rtos elev2Value 2 2))
              (cons 2 "ELEV2")
              (cons 7 "STANDARD")
              (cons 100 "AcDbAttribute")
              (cons 70 0)
              (cons 71 0)
              (cons 72 0)
            )))
 
  (setq blkEnt (list blkRef attr1 attr2 '(0 . "SEQEND")))
  (setq blk (entmake blkEnt))

)
0 Likes
Message 5 of 14

paullimapa
Mentor
Mentor

How come you didn’t follow my code?

Why are you using "ATTRIB"

Do you see that in my code or Kent’s?

And where is Kent’s example?


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

etilley327KA
Advocate
Advocate
I tried yours too and couldn't get it to work. The one from Kent was in the link in the first response.

MESSAGE 3 OF 5
Kent1Cooper
Consultant Kent1Cooper in reply to: copoljan
‎09-19-2011 07:37 AM
@Anonymous wrote:
....i want to insert blocks with attributes and I dont want to use (command "-insert" ... etc )

....

You would need to (entmake) the Block Insertion, and the Attribute(s), and the SEQEND finisher. Something like this seems to be enough information.



(entmake
(list
'(0 . "INSERT")
'(66 . 1); has attribute(s)
(cons 2 "YourBlockName")
(cons 10 YourInsertionPoint)
'(41 . 1.0); X
'(42 . 1.0); Y
'(43 . 1.0); Z
; (cons 50 YourRotation); if not default 0
); list
)



(entmake
(list
'(0 . "ATTRIB")
(cons 10 YourBaseLineLeftEnd);;;;; get from Attribute data within Block definition
(cons 40 YourHeight)
(1 . "YourTextContent")
; (cons 50 YourRotation); if not default 0
(cons 72 YourValue); part of justification
(cons 11 YourInsertionPoint);;;;; get from Attribute data within Block definition
(cons 2 "YOURTAG")
'(70 . 0); I don't know what, but necessary
(cons 73 YourValue); part of justification
)
)



(entmake '((0 . "SEQEND")))



You may be able to leave out the XYZ of the Block if they're all the default of 1 -- I didn't try it that way.



The tricky part seems to be establishing the insertion point for the Attribute(s). I haven't worked it out yet, but I think if you want them at their default locations in relation to the Block, you'd need to get into the Block definition with (tblobjname), and step through the Attribute definitions within that with (entnext), and get their insertion points relative to the Block's insertion point, then calculate values to put into (enmake) for the Attributes, presumably with (mapcar '+) adding the Attribute definition's insertion point [relative to the Block] to the Block's insertion point.

Kent Cooper, AIA

Let me try using your method again.
0 Likes
Message 7 of 14

etilley327KA
Advocate
Advocate

This way is not working either. 

(defun c:TEST (/ insertionPoint elev2Value blkRef attr1 attr2 blkEnt blk)
 
  (setq insertionPoint (getpoint "\nSpecify insertion point: "))
  (setq elev2Value 2)

  (entmake (list
               '(0 . "BLOCK")
                (cons 2 "SRVPNOC")
                (cons 8 "-DRN")
                (cons 10 insertionPoint)
                (cons 41 0.8)
                (cons 42 0.8)
                (cons 43 0.8)
                (cons 44 0.0)
                (cons 45 0.0)
                (cons 50 0.0)
                (cons 66 1)
                (cons 100 "AcDbEntity")
              ))

(entmake (list
             '(0 . "ATTDEF")
              (cons 8 "-DRNMARK")
              (cons 10 insertionPoint)
              (cons 41 0.8)
              (cons 1 "+")
              (cons 2 "MARK")
              (cons 7 "STANDARD")
              (cons 100 "AcDbAttribute")
              (cons 70 0)
              (cons 71 0)
              (cons 72 0)
            ))

(entmake (list
             '(0 . "ATTDEF")
              (cons 8 "-DRNELEV")
              (cons 10 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))
              (cons 41 0.8)
              (cons 1 (rtos elev2Value 2 2))
              (cons 2 "ELEV2")
              (cons 7 "STANDARD")
              (cons 100 "AcDbAttribute")
              (cons 70 0)
              (cons 71 0)
              (cons 72 0)
            ))
 
  (entmake '((0 . "ENDBLK")))
  (entmake '((0 . "INSERT")
             (2 . "MYBLOCK") ; Block name
             (8 . "0")       ; Layer (change as needed)
             (66 . 1)
             (10 insertionPoint) ; X, Y, Z insertion point
             (50 . 0)
             (41 . 1.0)
             (42 . 1.0)
             (43 . 1.0)))

)
0 Likes
Message 8 of 14

paullimapa
Mentor
Mentor
Accepted solution

To entmake the Block with Attributes that's when ATTDEF is used.

To Insert Block using entmake also that's when ATTRIB is used.

Since your code is embedded with the first Attrib Def a distance of 2 units from the second Attrib Def, this is how it looks when inserted into the drawing:

paullimapa_0-1695679787107.png

EmBlAt.lsp contains the entire entmake block, attrib def & entmake block insert process:

; EmBlAt entity make block with attributes and insert
(defun c:EmBlAt 
 (/ 
  blkname clayerb clayeri clayer1 clayer2 styname htx wdy 
  elev2Value insertionPoint
  sclx scly sclz
 )
  (setq
    blkname "SRVPNOC"           ; name of Block
    clayerb "-DRN"              ; defined block layer
    clayer1 "-DRNMARK"          ; attribute def #1 layer
    clayer2 "-DRNELEV"          ; attribute def #2 layer
    clayeri "-DRN"              ; inserted block layer preferably same as defined block
    styname "STANDARD"          ; text style
    htx 0.1563                  ; attribute def height
    wdy 0.8                     ; attribute def width
    elev2Value 2                ; attribute def #2 def value 
    sclx 1                      ; block insert x scale factor
    scly 1                      ; block insert y scale factor
    sclz 1                      ; block insert z scale factor
  )
  (setq insertionPoint (getpoint "\nSpecify insertion point: ")) 
    (entmake 
     (list 
       '(0 . "BLOCK") 
       (cons 2 blkname) ; block name
       '(70 . 2) 
       (cons 8 clayerb)  ; layer
       (cons 10 insertionPoint)  ; insertion point
       '(4 . "SRVPNOC Value")    ; comment
      )
    ) ; end of block
;       1=default value ; 2=Tag   ; 3=Prompt
    (entmake 
      (list 
        '(0 . "ATTDEF") 
        (cons 8 clayer1)          ; layer
        (cons 10 insertionPoint)  ; insertion point
        '(70 . 0)                 ; attribute flags
        '(3 . "+")                ; 3=Prompt
        '(2 . "MARK")             ; 2=Tag 
        '(1 . "+")                ; 1=default value
        (cons 40 htx)             ; height
        (cons 41 wdy)             ; width
        (cons 7 styname)          ; text style
        (cons 11 insertionPoint)  ; match insertion point            
        '(72 . 0)                 ; 0=10 as insertion point
      )
    )
    (entmake 
      (list 
        '(0 . "ATTDEF") 
        (cons 8 clayer2)                 ; layer
        (cons 10 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))   ; insertion point
        '(70 . 0)                        ; attribute flags
        '(3 . "Elevation Value")         ; 3=Prompt
        '(2 . "ELEV2")                   ; 2=Tag 
        (cons 1 (rtos elev2Value 2 2))   ; 1=default value
  	    (cons 40 htx)                    ; height
        (cons 41 wdy)                    ; width
        (cons 7 styname)                 ; text style 
        (cons 11 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0)) ; match insertion point
        '(72 . 0)                      ; 0=10 as insertion point
      )
    ) 
    (entmake '((0 . "ENDBLK")) )       ; end of block with attdef
  
  ; insert the block
    (entmake 
      (list 
        '(0 . "INSERT") 
        (cons 2 blkname)   ; block name
        (cons 8 clayeri)   ; layer 
        '(66 . 1)          ; has attributes
        (cons 10 insertionPoint) ; insertion point
        (cons 41 sclx)     ; x scale
        (cons 42 sclx)     ; y scale
        (cons 43 sclx)     ; z scale
      )
    ) ; begin insert Block
    ; attrib #1
    (entmake 
      (list 
        '(0 . "ATTRIB") 
        (cons 10 insertionPoint)   ; insertion point
        (cons 8 clayer1)           ; layer
        (cons 1 "+")               ; 1=default value
        '(2 . "MARK")              ; 2=Tag 
        (cons 40 htx)              ; height
        '(70 . 0)                  ; attribute flags
        (cons 41 wdy)              ; width
        (cons 7 styname)           ; text style
        (cons 11 insertionPoint)   ; match insertion point  
        '(72 . 0)                  ; 0=10 as insertion point 
      ) 
    )
    ; attrib #2
    (entmake 
      (list 
        '(0 . "ATTRIB") 
        (cons 10 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))   ; insertion point
        (cons 8 clayer2)                  ; layer
        (cons 1 (rtos elev2Value 2 2))    ; 1=default value
        '(2 . "ELEV2")                    ; 2=Tag 
        (cons 40 htx)                     ; height
        '(70 . 0)                         ; attribute flags
        (cons 41 wdy)                     ; width
        (cons 7 styname)                  ; text style 
        (cons 11 (list (+ (car insertionPoint) 2.0) (cadr insertionPoint) 0.0))   ; insertion point
        '(72 . 0)                         ; 0=10 as insertion point 
      )
    )
    (entmake '((0 . "SEQEND")))
  (princ) ; end insert block 
)

 


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

etilley327KA
Advocate
Advocate
Thank you so much, I was stuck on this all day.
0 Likes
Message 10 of 14

paullimapa
Mentor
Mentor

Glad to have helped. I would still suggest to not use Standard as the Text Style for the Attributes since that can easily be changed by the user and become different from one dwg to the next…cheers!!!


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

etilley327KA
Advocate
Advocate
If I wanted to add rotation to match the WCS for the whole block, where would I add that?
0 Likes
Message 12 of 14

paullimapa
Mentor
Mentor

That would be 50. Here’s a great online list of all the dxf codes for all objects in AutoCAD:

http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a04.htm


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

Kent1Cooper
Consultant
Consultant

@paullimapa wrote:

.... Here’s a great online list of all the dxf codes for all objects in AutoCAD....


Since that's from 2011, in case anything has changed or been added in 12 years, >here< is the current DXF Reference.  Mostly you would go a level further down and pick the Related Reference about ENTITIES, but in this case the one about BLOCKS is also likely to be relevant, and others at the link level are worth looking at.

Kent Cooper, AIA
Message 14 of 14

Sea-Haven
Mentor
Mentor

Another example code very similar asks do you want a circle or a square then put numbers or alpha's incrementing each time. You can skip the multi bit that is just for choices.

0 Likes