using autolisp prompt to populate dynamic block attribute

using autolisp prompt to populate dynamic block attribute

Anonymous
Not applicable
2,612 Views
22 Replies
Message 1 of 23

using autolisp prompt to populate dynamic block attribute

Anonymous
Not applicable

Below is my lisp program and attached is the sample dwg.

It works fine - but I can't figure out how to have the input information (How many Joists?, What size joists?, What is the piecemark?) to populate the dynamic block attributes - "Qty", "Size", "Mark" - respectively.

 

Is this possible?

any ideas?

 

;-------------------------------------------------------------------------------------;;;
;;; ;;;
;;; Joist Multiple function ;;;
;;; Description: Labels multiple joists and inserts "joist Multiple" block ;;;
;;; ;;;
;;;-------------------------------------------------------------------------------------;;;


(defun C:JM (/ p1 p2 qty size mark oldlayer oldsnap olddim)

;; Save Current Layer
;; Set Current Layer and Object Snap settings
(setq oldlayer (getvar "clayer")
oldsnap (getvar 'osmode)
olddim (getvar "dimstyle"))
(command "_dimstyle" "_r" "piecemarks")
(setvar "osmode" 640)
(command "clayer" "joist marks")

;; get poinTs & insert block
(setq p1 (getpoint "\nPick point: ")
p2 (getpoint "\nPick Second point: ")
qty (getreal "\nHow many joists?: ")
size (getstring "\nWhat size joists?: ")
mark (getstring "\nWhat is the piecemark?: "))

(setq str (strcat (rtos qty 2 0) "-" size "-" mark))

(command "dimaligned" p1 p2 "text" str "@0,0")

(command "_.insert" "joist multi" p1 "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")


;; Reset Layer, OS, and Dimstyle

(setvar "clayer" oldlayer)
(setvar "osmode" 233)
(command "_dimstyle" "_r" olddim)
(princ)
)

;;; End function ;

0 Likes
Accepted solutions (4)
2,613 Views
22 Replies
Replies (22)
Message 2 of 23

dbhunia
Advisor
Advisor

Add the below lines.......

 

............
(command "dimaligned" p1 p2 "text" str "@0,0")
(setvar 'attdia 0);;;Controls whether the INSERT command uses a dialog box for attribute value entry.
(command "_.insert" "joist multi" p1 "" "" "" "" qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")
(setvar 'attdia 1);;;Controls whether the INSERT command uses a dialog box for attribute value entry.
............

 

Also check >>This<< for System Variables

 

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 3 of 23

Anonymous
Not applicable

Thank you for your response.

 

I added the lines you suggested - but did not see any difference in the program.

The attributes (qty, mark, and size) did not get populated by the input portion of the program.

 

I saw the reference link you gave - but am unsure how to use them in the code.

I'm not very knowledgeable of lisp and only cobble things together in simple fashion.

0 Likes
Message 4 of 23

dbhunia
Advisor
Advisor
Accepted solution

Ok i think you need this.....

 

(defun C:JM (/ p1 p2 qty size mark oldlayer oldsnap olddim)

;; Save Current Layer
;; Set Current Layer and Object Snap settings
(setq oldlayer (getvar "clayer")
oldsnap (getvar 'osmode)
olddim (getvar "dimstyle"))
(command "_dimstyle" "_r" "piecemarks")
(setvar "osmode" 640)
(command "clayer" "joist marks")

;; get poinTs & insert block
(setq p1 (getpoint "\nPick point: ")
	p2 (getpoint p1 "\nPick Second point: ")
	qty (getreal "\nHow many joists?: ")
	size (getstring "\nWhat size joists?: ")
	mark (getstring "\nWhat is the piecemark?: ")
)
(setq str (strcat (rtos qty 2 0) "-" size "-" mark))

(command "dimaligned" p1 p2 "text" str "@0,0")
(setvar 'attdia 0)
(command "_.insert" "joist multi" p1 "" "" "" "" qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")
(setvar 'attdia 1)
(LM:setdynpropvalue (vlax-ename->vla-object (entlast)) "Distance1" (rtos (distance p1 p2) 2 0))
;; Reset Layer, OS, and Dimstyle
(setvar "clayer" oldlayer)
(setvar "osmode" 233)
(command "_dimstyle" "_r" olddim)
(princ)
)
(defun LM:getdynpropvalue ( blk prp )
    (setq prp (strcase prp))
    (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)
(defun LM:setdynpropvalue ( blk prp val ) (setq prp (strcase prp)) (vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (progn (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x)))) (cond (val) (t)) ) ) ) (vlax-invoke blk 'getdynamicblockproperties) ) )

Also check >>This<<

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 5 of 23

_gile
Consultant
Consultant
Accepted solution

Hi,

 

I'd rather set the ATTREQ sysvar to 0 so that the user is not prompted for the attribute and they can be set by code.

I used an (if ...) expression so that the code only executes if all the (get.. ) expression are not nil.

I wrapped the whole in (vl-catch-all-apply ...) expression to ensure the modified system variables are reset to their previous values.

I uses the setpropertyvalue fuction to set the attribute and dynamic property values.

 

;;;-------------------------------------------------------------------------------------;;;
;;; ;;;
;;; Joist Multiple function ;;;
;;; Description: Labels multiple joists and inserts "joist Multiple" block ;;;
;;; ;;;
;;;-------------------------------------------------------------------------------------;;;


(defun C:JM (/ oldlayer oldsnap oldattreq attempt)

  ;; Save Current Layer
  ;; Set Current Layer and Object Snap settings
  (setq	oldlayer  (getvar 'clayer)
	oldsnap	  (getvar 'osmode)
	oldattreq (getvar 'attreq)
  )
  (setq	attempt
	 (vl-catch-all-apply
	   '(lambda (/ p1 p2 qty size mark dimstyle)
	      (command "_.dimstyle" "_r" "piecemarks")
	      (setvar 'osmode 640)
	      (setvar 'clayer "joist marks")
	      (setvar 'attreq 0)

	      ;; get poinTs & insert block
	      (if
		(and
		  (setq p1 (getpoint "\nPick point: "))
		  (setq p2 (getpoint "\nPick Second point: "))
		  (setq qty (getint "\nHow many joists?: "))
		  (setq size (getstring "\nWhat size joists?: "))
		  (setq mark (getstring "\nWhat is the piecemark?: "))
		  (setq dimstyle (tblobjname "dimstyle" "piecemarks"))
		)
		 (progn
		   (setq str (strcat (rtos qty 2 0) "-" size "-" mark))
		   (command "_.dimaligned" p1 p2 "_text" str "@0,0")
		   (setpropertyvalue (entlast) "DimensionStyle" dimstyle)
		   (command "_.insert" "joist multi" p1 1. 1. 0.)
		   (setpropertyvalue (entlast) "QTY" (itoa qty))
		   (setpropertyvalue (entlast) "SIZE" size)
		   (setpropertyvalue (entlast) "MARK" mark)
		   (setpropertyvalue
		     (entlast)
		     "AcDbDynBlockPropertyDistance1"
		     (distance p1 p2)
		   )
		 )
	      )
	    )
	 )
  )

  ;; Reset Layer, OS, and Dimstyle

  (setvar 'clayer oldlayer)
  (setvar 'osmode oldsnap)
  (setvar 'attreq oldattreq)

  (if (vl-catch-all-error-p attempt)
    (prompt
      (strcat "\nError: " (vl-catch-all-error-message attempt))
    )
  )
  (princ)
)

;;; End function ;


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 6 of 23

Anonymous
Not applicable

Thank You!

it does work as needed.

It adds 2 new programs that need to be loaded - correct?

I also noticed it always defaults the block to horizontal.

Before - it allowed me to pick a point to allow its rotation during the function.

this isn't a major problem - I can rotate after insertion completed.

thanks again!

0 Likes
Message 7 of 23

Anonymous
Not applicable

Thank You!
it does work as needed.
amazing how 2 different approaches lead to the same result.

as I noted to dbhunia - 
I also noticed it always defaults the block to horizontal.
Before - it allowed me to pick a point to allow its rotation during the function.
this isn't a major problem - I can rotate after insertion completed.
thanks again!

 

 

0 Likes
Message 8 of 23

Anonymous
Not applicable

BTW - I'm going to have to research "VLA" ….you both lost me when you went to that.

 

thanks again

0 Likes
Message 9 of 23

dbhunia
Advisor
Advisor

ok check this.......

 

(defun C:JM (/ p1 p2 qty size mark oldlayer oldsnap olddim ang)

	(defun LM:getdynpropvalue ( blk prp )
		(setq prp (strcase prp))
		(vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
			(vlax-invoke blk 'getdynamicblockproperties)
		)
	)
	(defun LM:setdynpropvalue ( blk prp val )
	   (setq prp (strcase prp))
	   (vl-some
		  '(lambda ( x )
			   (if (= prp (strcase (vla-get-propertyname x)))
				   (progn
					   (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
					   (cond (val) (t))
				   )
			   )
		   )
		   (vlax-invoke blk 'getdynamicblockproperties)
	   )
	)
    (setq p1 (getpoint "\nPick point: ")
		p2 (getpoint p1 "\nPick Second point: ")
		qty (getreal "\nHow many joists?: ")
		size (getstring "\nWhat size joists?: ")
		mark (getstring "\nWhat is the piecemark?: ")
	)
	(if (and p1 p2 qty size mark)
		(progn
			(setq oldlayer (getvar "clayer")
				  oldsnap (getvar 'osmode)
				  olddim (getvar "dimstyle")
			)
			(setvar 'cmdecho 0)
			(setvar "osmode" 640)
			(command "_dimstyle" "_r" "piecemarks")
			(command "clayer" "joist marks")
			(setq str (strcat (rtos qty 2 0) "-" size "-" mark))
			(setq ang (/ (* (angle p1 p2) 180) pi))
			(command "dimaligned" p1 p2 "text" str "@0,0")
			(setvar 'attdia 0)
			(command "_.insert" "joist multi" "_none" p1 "" "" ang qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")
			(setvar 'attdia 1)
			(LM:setdynpropvalue (vlax-ename->vla-object (entlast)) "Distance1" (rtos (distance p1 p2) 2 0))
			(command "_dimstyle" "_r" olddim)
			(setvar "clayer" oldlayer)
			(setvar "osmode" oldsnap)
			(setvar 'cmdecho 1)
		)
	)
	(princ)
)

Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 10 of 23

Anonymous
Not applicable

Thanks again.

it places the block at the correct angle.

however - the span attribute is being populated by the qty input and it is prompting for the "slope" - which is the last attribute of the block.

I appreciate your time spent on this and will see if it is something I can figure out.

0 Likes
Message 11 of 23

dbhunia
Advisor
Advisor
Accepted solution

Hi @Anonymous .......

 

Replace the line...

(command "_.insert" "joist multi" "_none" p1 "" "" ang qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")

with

(command "_.insert" "joist multi" "_none" p1 "" "" ang "" qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")

 

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 12 of 23

Anonymous
Not applicable

perfect!!

thanks!!

now to sit down and understand the coding...

0 Likes
Message 13 of 23

_gile
Consultant
Consultant

@Anonymous wrote:

BTW - I'm going to have to research "VLA" ….you both lost me when you went to that.

 

thanks again


The code I posted does not use any "vla-" function, the "vl-" function are AutoLISP function (they run on AutoCAD MAC)

The 'vl-catch-all-' functions used in the code I posted are just a way of error handling to insure the sysvar are reset to their previous values. If you're not cumfortable with these functions, you can do the same by locally redefine the *error* function as shown in the below code (this version also rotate the block).

 

;;;-------------------------------------------------------------------------------------;;;
;;; ;;;
;;; Joist Multiple function ;;;
;;; Description: Labels multiple joists and inserts "joist Multiple" block ;;;
;;; ;;;
;;;-------------------------------------------------------------------------------------;;;


(defun C:JM (/ *error* oldlayer	oldsnap	oldattreq p1 p2	qty size mark
	     dimstyle)

  ;; locally redefinr the *error* function
  (defun *error* (msg)
    (and msg
	 (/= msg "Function cancelled")
	 (prompt (strcat "\nError: " msg))
    )
    (and oldlayer (setvar 'clayer oldlayer))
    (and oldsnap (setvar 'osmode oldsnap))
    (and oldattreq (setvar 'attreq oldattreq))
    (princ)
  )

  ;; Save Current Layer
  ;; Set Current Layer and Object Snap settings
  (setq	oldlayer  (getvar 'clayer)
	oldsnap	  (getvar 'osmode)
	oldattreq (getvar 'attreq)
  )
  (command "_.dimstyle" "_r" "piecemarks")
  (setvar 'osmode 640)
  (setvar 'clayer "joist marks")
  (setvar 'attreq 0)

  ;; get poinTs & insert block
  (if
    (and
      (setq p1 (getpoint "\nPick point: "))
      (setq p2 (getpoint p1 "\nPick Second point: "))
      (setq qty (getint "\nHow many joists?: "))
      (setq size (getstring "\nWhat size joists?: "))
      (setq mark (getstring "\nWhat is the piecemark?: "))
      (setq dimstyle (tblobjname "dimstyle" "piecemarks"))
    )
     (progn
       (setq str (strcat (rtos qty 2 0) "-" size "-" mark))
       (command "_.dimaligned" p1 p2 "_text" str "@0,0")
       (setpropertyvalue (entlast) "DimensionStyle" dimstyle)
       (command	"_.insert" "joist multi" p1 1. 1. (angtos (angle p1 p2) 2 16))
       (setpropertyvalue (entlast) "QTY" (itoa qty))
       (setpropertyvalue (entlast) "SIZE" size)
       (setpropertyvalue (entlast) "MARK" mark)
       (setpropertyvalue
	 (entlast)
	 "AcDbDynBlockPropertyDistance1"
	 (distance p1 p2)
       )
     )
  )

  ;; Reset Layer, OS, and Dimstyle

  (*error* nil)
)

;;; End function ;

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 23

Anonymous
Not applicable

well - that shows how much I don't know about lisp......

Thank you again!!

0 Likes
Message 15 of 23

Anonymous
Not applicable

Giles,

just FYI - the dimstyle is not reverting back to the "old dimstyle".

I'll see if I can't adjust.

I appreciate all you did!!

I think you helped me on some previous programs.

0 Likes
Message 16 of 23

Anonymous
Not applicable

dbhunia,

just FYI

the snap is not setting up at "640".

it initiates at the current osmode when picking the points.

I'll rearrange some lines.

 

Thank you for all your help!

0 Likes
Message 17 of 23

dbhunia
Advisor
Advisor

Hi @Anonymous ........ its my mistake

 

Try this.......

(defun C:JM (/ *error* p1 p2 qty size mark oldlayer oldsnap olddim ang)
	(defun *error* ( msg )
		(setvar "clayer" oldlayer)
		(setvar "osmode" oldsnap)
		(setvar 'attdia 1)
		(setvar 'cmdecho 1)
		(if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))
			(princ (strcat "\nOops an Error : " msg " occurred."))
		)
		(princ)
	)
	(defun LM:getdynpropvalue ( blk prp )
		(setq prp (strcase prp))
		(vl-some '(lambda ( x ) (if (= prp (strcase (vla-get-propertyname x))) (vlax-get x 'value)))
			(vlax-invoke blk 'getdynamicblockproperties)
		)
	)
	(defun LM:setdynpropvalue ( blk prp val )
	   (setq prp (strcase prp))
	   (vl-some
		  '(lambda ( x )
			   (if (= prp (strcase (vla-get-propertyname x)))
				   (progn
					   (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
					   (cond (val) (t))
				   )
			   )
		   )
		   (vlax-invoke blk 'getdynamicblockproperties)
	   )
	)
	(setq oldlayer (getvar "clayer")
		  oldsnap (getvar 'osmode)
		  olddim (getvar "dimstyle")
	)
	(setvar 'cmdecho 0)
	(setvar "osmode" 640)
	(setvar 'attdia 0)
        (setq p1 (getpoint "\nPick point: ")
		p2 (getpoint p1 "\nPick Second point: ")
		qty (getreal "\nHow many joists?: ")
		size (getstring "\nWhat size joists?: ")
		mark (getstring "\nWhat is the piecemark?: ")
	)
	(if (and p1 p2 qty size mark)
		(progn
			(command "_dimstyle" "_r" "piecemarks")
			(command "clayer" "joist marks")
			(setq str (strcat (rtos qty 2 0) "-" size "-" mark))
			(setq ang (/ (* (angle p1 p2) 180) pi))
			(command "dimaligned" p1 p2 "text" str "@0,0")
			(command "_.insert" "joist multi" "_none" p1 "" "" ang "" qty size mark "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "")
			(LM:setdynpropvalue (vlax-ename->vla-object (entlast)) "Distance1" (rtos (distance p1 p2) 2 0))
			(command "_dimstyle" "_r" olddim)
		)
	)
	(setvar "clayer" oldlayer)
	(setvar "osmode" oldsnap)
	(setvar 'attdia 1)
	(setvar 'cmdecho 1)
	(princ)
)

 


Debashis Bhunia
Co-Founder of Geometrifying Trigonometry(C)
________________________________________________
Walking is the First step of Running, Technique comes Next....
Message 18 of 23

Anonymous
Not applicable

I made that change but the osmode is still not changing to 640.

does the line that initiate the osmode setting need to be moved further up?

I'll look into more this weekend.

Thank you!

0 Likes
Message 19 of 23

_gile
Consultant
Consultant
Accepted solution

@Anonymous wrote:

Giles,

just FYI - the dimstyle is not reverting back to the "old dimstyle".

I'll see if I can't adjust.

I appreciate all you did!!

I think you helped me on some previous programs.


;;;-------------------------------------------------------------------------------------;;;
;;; ;;;
;;; Joist Multiple function ;;;
;;; Description: Labels multiple joists and inserts "joist Multiple" block ;;;
;;; ;;;
;;;-------------------------------------------------------------------------------------;;;


(defun C:JM (/ *error* oldlayer	oldsnap	oldattreq p1 p2	qty size mark
	     dimstyle)

  ;; locally redefine the *error* function
  (defun *error* (msg)
    (and msg
	 (/= msg "Function cancelled")
	 (prompt (strcat "\nError: " msg))
    )
    (and oldlayer (setvar 'clayer oldlayer))
    (and oldsnap (setvar 'osmode oldsnap))
    (and oldattreq (setvar 'attreq oldattreq))
    (princ)
  )

  ;; Save Current Layer
  ;; Set Current Layer and Object Snap settings
  (setq	oldlayer  (getvar 'clayer)
	oldsnap	  (getvar 'osmode)
	olddim    (getvar 'dimstyle)
	oldattreq (getvar 'attreq)
  )
  (command "_.dimstyle" "_r" "piecemarks")
  (setvar 'osmode 640)
  (setvar 'clayer "joist marks")
  (setvar 'attreq 0)

  ;; get poinTs & insert block
  (if
    (and
      (setq p1 (getpoint "\nPick point: "))
      (setq p2 (getpoint p1 "\nPick Second point: "))
      (setq qty (getint "\nHow many joists?: "))
      (setq size (getstring "\nWhat size joists?: "))
      (setq mark (getstring "\nWhat is the piecemark?: "))
    )
     (progn
       (setq str (strcat (rtos qty 2 0) "-" size "-" mark))
       (command "_dimstyle" "_r" "piecemarks")
       (command "_.dimaligned" p1 p2 "_text" str "@0,0")
       (command "_dimstyle" "_r" olddim)
       (command	"_.insert" "joist multi" p1 1. 1. (angtos (angle p1 p2) 0 16))
       (setpropertyvalue (entlast) "QTY" (itoa qty))
       (setpropertyvalue (entlast) "SIZE" size)
       (setpropertyvalue (entlast) "MARK" mark)
       (setpropertyvalue (entlast) "AcDbDynBlockPropertyDistance1" (distance p1 p2))
     )
  )

  ;; Reset Layer, OS, and Dimstyle

  (*error* nil)
)

;;; End function ;


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 20 of 23

Anonymous
Not applicable

Giles,

thanks again!

works great.

It does have this error message coming up at the end - "Error: ADS request error".

 

the only thing I did was to run "battman" to rearrange the order of the attributes.

 

0 Likes