View Full Version : Get a program to run after a block is inserted
ccowgill
2006-07-28, 08:53 PM
I would like a program to run after a block has been inserted by either the insert command, or pasted from the clip board. I would like to use this a way to start learning how to use reactors (as the help files dont seem to show specific examples) but I am open to any suggestions on other ways to accomplish this.
You would need to look at the command reactor
ccowgill
2006-07-28, 08:56 PM
could you give an example of the vlr-command-reactor, I looked at the help file, and I dont understand the information the command is looking for.
T.Willey
2006-07-28, 09:45 PM
Here is a real basic reactor program.
(if (not GlbReactorCommandEnded)
(setq GlbReactorCommandEnded (vlr-command-reactor "InsertReactor" '((:vlr-commandEnded . "InsertCommandReactor"))))
)
(defun InsertCommandReactor (React Lst)
(print React)
(print Lst)
)
This will print out the reactor, and the command name. All you have to do is test of the command name that you want the reactor to fire on. Just remember that you can't use "command" or ask for user input from a reactor. If you are a little more specific with what you want to do, people will be better able to help you.
You have to load both into a drawing to use.
ccowgill
2006-07-28, 10:00 PM
I have written a program that automattically fills in an attribute of our title block depending on if it is a cross section sheet or a plan & profile sheet. I would like it to automattically run as soon as someone has inserted the title block, they insert it by either insert, drag-n-drop, or by pasteclip.
T.Willey
2006-07-28, 11:14 PM
I have written a program that automattically fills in an attribute of our title block depending on if it is a cross section sheet or a plan & profile sheet. I would like it to automattically run as soon as someone has inserted the title block, they insert it by either insert, drag-n-drop, or by pasteclip.
Do each of thos comamnds, after you have copy/pasted or loaded the routine. Then you can see the comamnd name on the command line, quoted in a pair of parentathesis. Then you will know which commands to trap, and then see if the block name matches your title block, and if so, then run your command.
ccowgill
2006-09-12, 11:11 PM
I am still confused on how to get the program to run.
I have a list of the commands I want to trigger this program to run. I just dont know how to check to see if the object being inserted is the particular block
whenever the block called TBL14 is INSERT PASTECLIP or DROPGEOM,
I want this program to run:
(defun C:cav (/ adoc atts axss ss val)
(vl-load-com)
(setq adoc
(vla-get-activedocument
(vlax-get-acad-object)
)
)
(vla-endundomark adoc)
(vla-startundomark adoc)
(vla-zoomextents (vla-get-application adoc))
(setq filetype (getvar "dwgname"))
(if (setq ss (ssget "_X" (list (cons 0 "INSERT") (cons 2 "tbl14"))))
(progn
(setq axss (vla-get-activeselectionset adoc))
(vlax-for a axss
(progn
(setq atts (vlax-invoke a 'Getattributes))
(foreach at atts
(if (eq (vla-get-tagstring at) "PLANANDPROFILE")
(setq val (vla-get-textstring at))
)
)
(if (= (wcmatch filetype "RCp*") t)
;if file name is RCp*
(PROGN
(if
(= (wcmatch val "*LAN & PROFIL*") nil)
(progn
(setq val "PLAN & PROFILE")
(foreach at atts
(if (eq (vla-get-tagstring at) "PLANANDPROFILE")
(progn
(vla-put-textstring at val)
(vla-update at)
) ;end progn
) ;end if
) ;end foreach
) ;end progn
) ;end if
) ;END PROGN
) ;END IF
(if (= (wcmatch filetype "RC#*") t)
;if file name is RCp*
(PROGN
(if
(= (wcmatch val "*ROSS SECTION*") nil)
(progn
(setq val "CROSS SECTIONS")
(foreach at atts
(if (eq (vla-get-tagstring at) "PLANANDPROFILE")
(progn
(vla-put-textstring at val)
(vla-update at)
) ;end progn
) ;end if
) ;end foreach
) ;end progn
) ;end if
) ;END PROGN
) ;END IF
) ;end progn
(vla-update a)
)
)
)
(vla-clear axss)
(vla-delete axss)
(vlax-release-object axss)
(vla-regen adoc acallviewports)
(vla-endundomark adoc)
(princ)
)
T.Willey
2006-09-12, 11:51 PM
Here is your routine stripped down. Add a call to it (make sure it gets loaded) when the reactor fires.
(defun cav (/ filetype Ent EntData tmpList val)
(setq filetype (getvar "dwgname"))
(setq Ent (entlast))
(setq EntData (entget Ent))
(if
(and
(= (cdr (assoc 0 EntData)) "INSERT")
(= (strcase (cdr (assoc 2 EntData))) "TBL14")
(not
(foreach Att (vlax-invoke (vlax-ename->vla-object Ent) 'GetAttributes)
(if (= (vla-get-TagString Att) "PLANANDPROFILE")
(setq tmpList (cons Att (vla-get-TextString Att)))
)
)
)
)
(cond
((and
(= (wcmatch filetype "RCp*") t)
;if file name is RCp*
(= (wcmatch (cdr tmpList) "*LAN & PROFIL*") nil)
)
(setq val "PLAN & PROFILE")
)
((and
(= (wcmatch filetype "RC#*") t)
;if file name is RCp*
(= (wcmatch (cdr tmplist) "*ROSS SECTION*") nil)
)
(setq val "CROSS SECTIONS")
)
)
)
(if val
(progn
(vla-put-TextString (car tmpList) val)
(vla-Update (car tmpList))
)
)
)
kennet.sjoberg
2006-09-13, 08:55 AM
I would like a program to run after a block has been inserted by either the insert command, or pasted from the clip board. I would like to use this a way to start learning how to use reactors (as the help files dont seem to show specific examples) but I am open to any suggestions on other ways to accomplish this.
OK, here is my attempt :
;; Check if My_Insert_Command_Reactor is loaded in the task otherwise load it ( Do NOT load a reactor more than once )
(if (not My_Insert_Command_Reactor )
(setq My_Insert_Command_Reactor (vlr-command-reactor nil '((:vlr-commandEnded . My_Insert_Ending_Command ))) )
( ) ;; The reactor is already loaded
)
;;; Function used as Callbacks when the event fires / reactor triggers
(defun My_Insert_Ending_Command (In_ReactorName In_Command / )
(alert (car In_Command )) ;; <-- Remove this line, it shows all incomming command
;; Check if incomming command is Insert, Pasteclip or Dropgeom
(if
(or
(= (car In_Command ) "INSERT" )
(= (car In_Command ) "-INSERT" )
(= (car In_Command ) "PASTECLIP" )
(= (car In_Command ) "DROPGEOM" )
)
;; Then check if the last inserted object is TBL14
(if (= (cdr (assoc 2 (entget (entlast)))) "TBL14" )
(cav) ;; Run the already loaded function cav or c:cav
( ) ;; The last object was not TBL14
)
( ) ;; The last command was not INSERT, PASTECLIP or DROPGEOM
)
(princ)
)
;; This is a dummy function substitued for cav
(defun cav ( / )
(alert "Function cav is running" )
(princ)
)
;;; How to remove the Reactor :
(vlr-remove My_Insert_Command_Reactor )
;;; How to clear the place holder :
(setq My_Insert_Command_Reactor nil )
: ) Happy Computing !
kennet
peter
2006-09-13, 03:04 PM
I would like a program to run after a block has been inserted by either the insert command, or pasted from the clip board. I would like to use this a way to start learning how to use reactors (as the help files dont seem to show specific examples) but I am open to any suggestions on other ways to accomplish this.
I would recommend a acdbreactor in conjunction with a command ended reactor
(defun ACDBAppend (CALL CALLBACK / objSelection)
(setq objSelection (vlax-ename->vla-object (cadr CALLBACK)))
(if (and (= (vla-get-objectname
objSelection
)
"AcDbBlockReference")
't
)
(if lstAppendedBlocks
(setq lstAppendedBlocks (append lstAppendedBlocks (list (vla-get-effectivename objSelection))))
(setq lstAppendedBlocks (list (vla-get-effectivename objobjSelection)))
)
)
)
(defun ACDBCommand (CALL CALLBACK)
(if lstAppendedBlocks
(progn
(princ lstAppendedBlocks)
(setq lstAppendedBlocks nil)
)
)
)
(setq rxnAppend (vlr-acdb-reactor nil '((:vlr-objectAppended . ACDBAppend )))
rxnCommand (vlr-command-reactor nil '((:vlr-commandEnded . ACDBCommand)))
)
ccowgill
2006-09-13, 03:12 PM
What's the advantage of doing it your way Peter, over Kennet's?
I believe I am to the point in my lisp programing ability that I feel I need to start learning how to use reactors to open up a whole new range of programs that I can write. The more details provided as to why one code form works better than another, the more efficient I can make my programs.
I like Kennet's because I can use parts of it in other programs that I need reactors for.
j.f.moelee
2006-09-15, 11:28 AM
You can solve this by putting a diesel$ into your block.
Just like menu macros.
Diesel evaluates by loading in drawings.
Just like LISP.
It has one drawback: it evaluates constantly, so when the drawing is regenerated the expression is again evaluated.
But since you want to determine the status of the drawing, I don't think this will be a problem.
Below you see the entry in the help file concerning the diesel if statement.
$(if, expr, dotrue [, dofalse])
If expr is nonzero, it evaluates and returns dotrue. Otherwise, it evaluates and returns dofalse. Note that the branch not chosen by expr is not evaluated.
vBulletin® v3.6.7, Copyright ©2000-2009, Jelsoft Enterprises Ltd.