AfraLisp Blog

The AutoLisp/Visual Lisp/VBA Resource Website

AfraLisp Blog

Home Newsletter Utter Rubbish Coding Tips AutoCAD Tips Contact Downloads WAUN

Attributes and Dialog Boxes

You can find the VBA equivalent to this application here.

When you want to edit attributes in AutoCAD most of us use the "Attedit" command. Firstly, we must select the attribute we would like to edit. Then the "Edit Attribute" dialogue box appears which allows us to add or change the values of our attribute. Personally, I think this dialogue leaves a lot to be desired. You cannot customise it in any way, and it displays all attributes whether you want them or not. As well, if you have a lot of attributes you need to page your way through numerous dialogues before reaching the attribute you want to edit.

In this tutorial we are going to have a look at extracting attribute data from a block, displaying the data in a custom dialogue box, and then updating the attribute data on exit.
Right, what do we need to do?

1.    Find the block containing the attribute data. (Why select it when we can get AutoCAD to find it for us.)

2.    Extract the attribute data and display it in a dialogue box.

3.    Allow the user to change the data if he so wishes.

4.    Update the attribute data with the new information entered into the dialogue box.

O.K. fire up AutoCAD and open the drawing Attab.dwg.

Alright, I admit that it's not much of a title block, but it's enough to give you the general idea.

Now, at the command prompt type (load "Addat") and then enter.
Now, type "Addat" and press enter again.

This dialogue should appear :

Change some of the data and then press the "OK" button.
The title block data should be updated. Clever hey?

You can expand on this routine as much as you like using the following coding as a template.
Hint : You don't have to display all the attribute data stored in a block. Only display what you want the user to modify. As well, you can split your data over multiple dialogue boxes. eg. One for title block, one for revisions, one for reference drawings, etc. All the data though is contained in one attribute.

Here's the coding, DCL code first :


attab : dialog {
        label = "Drawing Title Block";

      : edit_box {
        label = "&Drawing Number";
        key = "eb1";
        edit_width = 30;
      }

      : edit_box {
        label = "&Revision";
        key = "eb2";
        edit_width = 30;
      }

      : edit_box {
        label = "Drawn &By";
        key = "eb3";
        edit_width = 30;
      }

      : edit_box {
        label = "D&ate";
        key = "eb4";
        edit_width = 30;
       }

      : edit_box {
        label = "&Title";
        key = "eb5";
        edit_width = 30;
       }

     ok_cancel ;

     :text_part {
         label = "AfraLisp - http://www.afralisp.com";
      }

     
     }

And now the AutoLisp coding with plenty of in-line comments to assist you :

;CODING STARTS HERE
;
;All Tutorials and Code are provided "as-is" for purposes of instruction and
;utility and may be used by anyone for any purpose entirely at their own risk.
;Please respect the intellectual rights of others.
;All material provided here is unsupported and without warranty of any kind.
;No responsibility will be taken for any direct or indirect consequences
;resulting from or associated with the use of these Tutorials or Code.
;*******************************************************************************
;			AfraLisp
;		http://www.afralisp.com
;	 	 afralisp@afralisp.com
;	   	 afralisp@mweb.com.na
;*******************************************************************************
;This application will extract attributes from a block and display them in a
;dialog box. The attributes will then be updated. Attab.dcl and Attab.dwg are
;required and must be within the AutoCAD search path.
;
;Usage : Open Attab.dwg then load and run Attab.lsp.
;*******************************************************************************

(prompt "\nATTAB Loaded....Type ATTAB to run.....")

(defun c:attab (/)

;first find all the blocks with attributes in the drawing
(setq ss1 (ssget "X" '((0 . "INSERT")(66 . 1))))

  ;if there are blocks
  (if ss1

    ;do the following
    (progn

      ;set up the counter
      (setq count 0
	    emax  (sslength ss1)
      )

      ;extract the block name
      (while (< count emax)

	(setq en   (ssname ss1 count)
	      ed   (entget en)
	      blkn (dxf 2 ed)
	)

	;check if it is our block
	(if (= "attab-info" blkn)

          	  ;if it is, switch off the counter
	  ;and set the found flag
	  (setq	count emax
		found T
	  )

	  ;it's not our block, increment the counter
	  ;and loop
	  (setq count (1+ count))

	);if

      );while

      ;if we find our block
      (if found

	;display the dialog
	(ddisplay)

	;cannot find our block
	(alert
	  "\nDrawing Sheet has No Attributes
            \n     Use Manual Edit"
	)

      );if

    );progn

    ;there are no blocks in the drawing
    (alert
      "\nIncorrect Drawing Sheet
      \n    Use Manual Edit"
    )

  );if

;finish clean	
(princ)

);defun

;;;**********************************************************

(defun ddisplay (/)

  	;load the dialog
  	(setq dcl_id (load_dialog "attab.dcl"))

  	;check it exists
  	(if (not (new_dialog "attab" dcl_id))

    	(exit)

  	);if

	;get the block entity data
	(setq edata (entget en))

	;get the first attribute entity list
	(setq edata (entget (entnext (dxf -1 edata))))

	;get the drawing number
	(setq eb1 (dxf 1 edata))

	;get the second attribute entity list
	(setq edata (entget (entnext (dxf -1 edata))))

	;get the revision
	(setq eb2 (dxf 1 edata))

	;get the third attribute entity list
	(setq edata (entget (entnext (dxf -1 edata))))

	;get the name
	(setq eb3 (dxf 1 edata))		

	;get the fourth attribute entity list
	(setq edata (entget (entnext (dxf -1 edata))))

	;get the date
	(setq eb4 (dxf 1 edata))		

	;get the fifth attribute entity list
	(setq edata (entget (entnext (dxf -1 edata))))

	;get the title
	(setq eb5 (dxf 1 edata))				


  ;put the info into the dialog
  (set_tile "eb1" eb1)
  (set_tile "eb2" eb2)
  (set_tile "eb3" eb3)
  (set_tile "eb4" eb4)
  (set_tile "eb5" eb5)

  ;set the focus to the drawing number
  (mode_tile "eb1" 2)

  ;if cancel selected exit
  (action_tile
    "cancel"
    "(done_dialog) (setq userclick nil)"
  )

  ;if OK selected, retrieve the tile values
  (action_tile
    "accept"
    (strcat
      "(progn (setq eb1a (get_tile \"eb1\"))"
      "(setq eb2a (get_tile \"eb2\"))"
      "(setq eb3a (get_tile \"eb3\"))"
      "(setq eb4a (get_tile \"eb4\"))"
      "(setq eb5a (get_tile \"eb5\"))"
     " (done_dialog)(setq userclick T))"
    )
  )

  ;start the dialog
  (start_dialog)

  ;unload the dialog
  (unload_dialog dcl_id)


  ;if OK was selected
  (if userclick

	(progn

  	  ;get the block entity data
	  (setq edata (entget en))

	  ;get the first attribute entity list
	  (setq edata (entget (entnext (dxf -1 edata))))

	  ;change the list with the new values, if any
	  (setq el (subst (cons 1 eb1a) (assoc 1 edata) edata))

	  ;update the attribute
	  (entmod el)

	  ;get the second attribute entity list
	  (setq edata (entget (entnext (dxf -1 edata))))

	  ;change the list with the new values, if any
	  (setq el (subst (cons 1 eb2a) (assoc 1 edata) edata))

	  ;update the attribute
	  (entmod el)

	  ;get the third attribute entity list
	  (setq edata (entget (entnext (dxf -1 edata))))

	  ;change the list with the new values, if any
	  (setq el (subst (cons 1 eb3a) (assoc 1 edata) edata))

	  ;update the attribute
	  (entmod el)

	  ;get the fourth attribute entity list
	  (setq edata (entget (entnext (dxf -1 edata))))

	  ;change the list with the new values, if any
	  (setq el (subst (cons 1 eb4a) (assoc 1 edata) edata))

	  ;update the attribute
	  (entmod el)

	  ;get the fifth attribute entity list
	  (setq edata (entget (entnext (dxf -1 edata))))

	  ;change the list with the new values, if any
	  (setq el (subst (cons 1 eb5a) (assoc 1 edata) edata))

	  ;update the attribute
	  (entmod el)

	  ;regen the drawing
          	 (command "REGEN")

	);progn

   );if

(princ)

);defun

;;;***********************************************************
	
(defun dxf (code elist)

  (cdr (assoc code elist))

);defun
;;;**********************************************************

;load clean
(princ)

;;;**********************************************************
;
;CODING ENDS HERE

Please note that there is no error checking in this routine and I have left all variables as global to assist you in checking their values whilst you are analyzing the code.


If you are too lazy to type, and don't know how to copy and paste, you can download the coding and sample drawing by very gently placing your cursor here and clicking once. "Ouch,  I did say gentle!!!!

 
The AutoLisp/Visual Lisp/VBA Resource Website

Copyright 1999-Perpetuity by AfraLisp

All rights reserved.
Information in this document is subject to change without notice.
Site created and maintained by Kenny Ramage

The AutoLisp/Visual Lisp/VBA Resource Website