Copy attribute

Copy attribute

scotth066
Explorer Explorer
1,610 Views
11 Replies
Message 1 of 12

Copy attribute

scotth066
Explorer
Explorer

I am fairly new to lisp writing.  I am needing help with a lisp routine.  Is there a way to select a block, store the value of a specific attribute, then insert a different block and apply the stored value into it's attribute?  

 

Here is what I am trying to accomplish.

 

It would prompt me to  select a "RMNAME" block, it would store the value of the attribute "room#". It would insert the block "DOOR_TAG" and place the stored "room#" value in the "doornum" attribute. Here's the catch. If there are multiple doors into one room, then it would add a prefix "a" or "b" and so on depending on how many doors there are.

 

See attached screen capture for multiple doors.

 

Thanks in advance!

0 Likes
Accepted solutions (3)
1,611 Views
11 Replies
Replies (11)
Message 2 of 12

Sea-Haven
Mentor
Mentor

No code but lots of ideas add door block attribute is  "Door", then use (chr X) a "A" is ascii code 65 so (strcat "Door" (chr x)) - "DoorA" so add 1 to x then (strcat "door" (chr x)) = "DoorB", I would use the select point for door attribute as the exit and reset x back to 65 for next room.

 

A good idea is provide a sample dwg having to create a dwg adds to solution time.

0 Likes
Message 3 of 12

pbejse
Mentor
Mentor

@scotth066 wrote:

...It would prompt me to  select a "RMNAME" block, it would store the value of the attribute "room#". It would insert the block "DOOR_TAG" and place the stored "room#" value in the "doornum" attribute. Here's the catch. If there are multiple doors into one room, then it would add a prefix "a" or "b" and so on depending on how many doors there are.


If theres nothing linking the doors to the RMNAME block, then you would have to select the RMNAME block then the  doors ( assuming it's a block ). 

 

Paste a drawing sample. 

 

 

0 Likes
Message 4 of 12

pbejse
Mentor
Mentor

@pbejse wrote:

....

If theres nothing linking the doors to the RMNAME block, then you would have to select the RMNAME block then the  doors ( assuming it's a block ). 
(defun c:demo ( / _some *spc suf roomtag RoomNum Doors drs mid dtag chn )
(defun _some (tag e)
  (vl-some '(lambda (at)
		    (if (eq tag (vla-get-tagstring at))
		      (list (Vla-get-textstring at) at)))
		    (vlax-invoke e 'GetAttributes))
  )
(setq *spc (vlax-get(vla-get-ActiveLayout
	       (vla-get-activedocument
                         (vlax-get-acad-object))) 'Block))
 (and
   (tblsearch "BLOCK" "DOOR_TAG")
    (while
		(setq suf "" roomtag
		       (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1) (2 . "`*U*,RMNAME"))))
		(eq "RMNAME" (vla-get-effectivename (setq de (vlax-ename->vla-object (ssname roomtag 0)))))
		(setq RoomNum (car (_some "ROOM#" de)))	    
		(setq Doors (ssget '((0 . "INSERT") (2 . "`*U*,DOOR"))))            	
		(repeat (sslength doors)
		  (setq drs (vlax-ename->vla-object (ssname doors 0)))
			(and
			(eq "DOOR" (vla-get-EffectiveName drs))
			(not (vla-getboundingbox drs 'll 'ur))
			(setq mid (mapcar (function (lambda (a b) (/ (+ a b) 2)))
		  			(vlax-safearray->list ll)(vlax-safearray->list ur)))
			(setq dtag (vlax-invoke *spc 'InsertBlock mid "DOOR_TAG" 1 1 1 0))
			(setq dtag (Cadr (_some "DOORNUM" dtag)))
			(not (vla-put-textstring dtag (strcat RoomNum suf)))
			(setq chn (if (eq "" suf) 97 (1+ chn)))
			(setq suf (chr chn))
			)
		  (ssdel (ssname doors 0) doors)
		  )
		)
   	)
  (princ)
    )

HTH

0 Likes
Message 5 of 12

scotth066
Explorer
Explorer

 

@pbejse Thanks for the reply.

 

I am wanting to prompt the user to "/n Select a RMNAME block", have it store the value of the "room#" attribute, then proceed straight into the insertion of the DOORNUM block.  The user would select an insertion point, default through the scale then have the routine insert the stored value into the "door#" attribute of the DOORNUM block.

 

See attached sample dwg

0 Likes
Message 6 of 12

Sea-Haven
Mentor
Mentor
Accepted solution

Try this it will do multi rooms, so pick a room fill in details, room name will appear pick door pick door Enter 

Pick new room can change room name numbers will increment auto.

You need the Multi getvals.lsp also.

screenshot323.png

 

 

; add room number and add door linked to room number
; By alanh Jan 2021

(defun c:roomname ( / rname r% rnum ans pt alpha suf)

(if (not AH:getvalsm)(load "Multi Getvals.lsp"))
(if (= rname nil)(setq rname " "))
(if (= r% nil)(setq r% " "))
(if (= rnum nil)(setq rnum 1))

(setq alpha 64 suf "")

(while (setq pt (getpoint "\nPick point for room name ENTER TO EXIT "))
    (setq ans (AH:getvalsm (list "Please enter" "Room  name" 12 11 rname "Room % " 12 11  r% "Room #" 11 10  (rtos rnum 2 0))))
    (setq rname (nth 0 ans)
      r% (nth 1 ans)
      rnum (atoi (nth 2 ans))
    )

    (command "-insert" "Rmname" pt 1 1 0 r% rname (rtos rnum 2 0))
    (while (setq pt (getpoint "\Pick point for door ENTER TO EXIT "))
       (command "-insert" "Door_tag" pt 1 1 0 (strcat (rtos rnum 2 0) suf))
       (setq suf (chr (setq alpha (+ alpha 1))))
    )
    (setq rnum (+ rnum 1))
    (setq alpha 64 suf "")
)

(princ)
)

 

 screenshot322.png

0 Likes
Message 7 of 12

pbejse
Mentor
Mentor
Accepted solution

@scotth066 wrote:

 

@pbejse Thanks for the reply.

 

I am wanting to prompt the user to "/n Select a RMNAME block", have it store the value of the "room#" ...


Here are two options:

1. Select the Rmname block and select the doors [ single/multiple selection ] as per first post.

(defun c:TaggerS ( / _some *spc suf roomtag RoomNum Doors drs mid dtag chn )
(defun _some (tag e)
  (vl-some '(lambda (at)
		    (if (eq tag (vla-get-tagstring at))
		      (list (Vla-get-textstring at) at)))
		    (vlax-invoke e 'GetAttributes))
  )
(setq *spc (vlax-get(vla-get-ActiveLayout
	       (vla-get-activedocument
                         (vlax-get-acad-object))) 'Block))
 (and
   (tblsearch "BLOCK" "DOOR_TAG")
    (while
	(and
		(setq suf "" roomtag
		       (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1) (2 . "`*U*,RMNAME"))))
		(eq "RMNAME" (strcase (vla-get-effectivename
			(setq de (vlax-ename->vla-object (ssname roomtag 0))))))
		(setq RoomNum (car (_some "ROOM#" de)))
		(princ "\nSelect Doors to tag:")
		(setq Doors (ssget '((0 . "INSERT") (2 . "`*U*,DOOR"))))
      		)            	
		(repeat (sslength doors)
		  (setq drs (vlax-ename->vla-object (ssname doors 0)))
			(and
			(eq "DOOR" (strcase (vla-get-EffectiveName drs)))
			(not (vla-getboundingbox drs 'll 'ur))
			(setq mid (mapcar (function (lambda (a b) (/ (+ a b) 2)))
		  			(vlax-safearray->list ll)(vlax-safearray->list ur)))
			(setq dtag (vlax-invoke *spc 'InsertBlock mid "DOOR_TAG" 1 1 1 0))
			(setq dtag (Cadr (_some "DOORNUM" dtag)))
			(not (vla-put-textstring dtag (strcat RoomNum suf)))
			(setq chn (if (eq "" suf) 97 (1+ chn)))
			(setq suf (chr chn))
			)
		  (ssdel (ssname doors 0) doors)
		  )
		)
   	)
  (princ)
    )

2. Select the Rmname block then proceed to insert the Door_tag on each pickpoint, as you requested

(defun c:Tagger ( / _some *spc suf roomtag RoomNum Doors drs mid dtag chn )
(defun _some (tag e)
  (vl-some '(lambda (at)
		    (if (eq tag (vla-get-tagstring at))
		      (list (Vla-get-textstring at) at)))
		    (vlax-invoke e 'GetAttributes))
  )
(setq *spc (vlax-get(vla-get-ActiveLayout
	       (vla-get-activedocument
                         (vlax-get-acad-object))) 'Block))
   
    (if
      (and
	(tblsearch "BLOCK" "DOOR_TAG")
	(setq suf "" roomtag
		       (ssget "_+.:S:E" '((0 . "INSERT") (66 . 1) (2 . "`*U*,RMNAME"))))
	(eq "RMNAME" (strcase (vla-get-effectivename
			(setq de (vlax-ename->vla-object (ssname roomtag 0))))))
	(setq RoomNum (car (_some "ROOM#" de)))
	(setq fp (vlax-get de 'Insertionpoint))
	
	)
      (while (setq pt (getpoint fp "\nPick point for Door tag"))
	(setq dtag (vlax-invoke *spc 'InsertBlock pt "DOOR_TAG" 1 1 1 0))
			(setq dtag (Cadr (_some "DOORNUM" dtag)))
			(not (vla-put-textstring dtag (strcat RoomNum suf)))
			(setq chn (if (eq "" suf) 97 (1+ chn)))
			(setq suf (chr chn))
			)
		  )
  (princ)
    )

HTH

 

Message 8 of 12

scotth066
Explorer
Explorer

@Sea-Haven  Thanks for the help.

 

It places the room name but when I pick point for door this is the error I get. 

Capture.PNG

0 Likes
Message 9 of 12

scotth066
Explorer
Explorer

@pbejse  Thanks for the help.

 

I have loaded both of your routines but when I type the commands nothing happens.  No errors, just nothing.

Capture.PNG

0 Likes
Message 10 of 12

scotth066
Explorer
Explorer

@Sea-Haven   I figured it out.

 

Thanks again for the help!

0 Likes
Message 11 of 12

scotth066
Explorer
Explorer

@pbejse   Thank you for the help!

 

These work!  My problem with both was that fact that the doornum block was not defined in the file I was testing in.

 

One more ask, is there a way to do away with the rubber band effect from the roomname block to where ever I am placing the doornum block?

 

Thanks!

0 Likes
Message 12 of 12

pbejse
Mentor
Mentor
Accepted solution

@scotth066 wrote:

One more ask, is there a way to do away with the rubber band effect from the roomname block to where ever I am placing the doornum block?

 

Thanks!


Change this

(setq pt (getpoint fp "\nPick point for Door tag"))

 to 

 

(setq pt (getpoint "\nPick point for Door tag"))

 

HTH