AUTO UPDATE DYNAMIC BLOCK USER DEFINED PARAMETER AFTER GRIP STRETCH ACTION

AUTO UPDATE DYNAMIC BLOCK USER DEFINED PARAMETER AFTER GRIP STRETCH ACTION

brandonstephan
Participant Participant
764 Views
7 Replies
Message 1 of 8

AUTO UPDATE DYNAMIC BLOCK USER DEFINED PARAMETER AFTER GRIP STRETCH ACTION

brandonstephan
Participant
Participant

I am attempting to auto update a user defined parameter named "PN" that is accessible within the block reference (quick properties) after each of the available dynamic block parameters changes . Whether it is a grip stretch or selection from a dropdown populated by the block table. I have what I believe is a completed Visual LISP script but I cannot seem to get it to run. first issue is when I use the APPLOAD command and load the LISP file and add it to the Startup Suite, and restart AutoCAD, when I check the Loaded Applications the LISP file is greyed out. I have placed the file in the default location "C:\Program Files\Autodesk\AutoCAD 2024\Support\en-us" as it is already a trusted file location and support file search path. This tells me that either this action is not possible thru this type of LISP function or I improperly setup the script or are missing critical components. Below is the script. I have also attached a DWG file with the block included to help understand the purpose of this script. Thank you to all in advanced who are able to shed some light on this. fyi, ChatGPT helped me put this together so I am sure there is lots to refine. I am a novice at LISP file creation.

 

(defun c:ShowBlockDims ( / ent obj dynprops leg1 leg2 thick getprop msg)

(vl-load-com)

;; Ask user to select a block reference
(if (setq ent (car (entsel "\nSelect a dynamic block: ")))
(progn
(setq obj (vlax-ename->vla-object ent))

(if (and (= (vla-get-objectname obj) "AcDbBlockReference")
(vlax-property-available-p obj 'EffectiveName)
(wcmatch (strcase (vla-get-EffectiveName obj)) "CA"))

(progn
(setq dynprops (vlax-invoke obj 'GetDynamicBlockProperties))

;; Helper to get dynamic prop by name
(defun getprop (name)
(vl-some
(function (lambda (p)
(if (eq (strcase (vla-get-PropertyName p)) (strcase name))
p)))
dynprops))

;; Get values
(setq leg1 (vla-get-value (getprop "LEG 1")))
(setq leg2 (vla-get-value (getprop "LEG 2")))
(setq thick (vla-get-value (getprop "THICKNESS")))

;; Show popup
(setq msg (strcat
"LEG 1: " (rtos leg1 2 4) "\\n"
"LEG 2: " (rtos leg2 2 4) "\\n"
"THICKNESS: " (rtos thick 2 4)))
(alert msg)
)
(prompt "\n[!] Not a valid 'CA' dynamic block.")
)
)
(prompt "\n[!] No block selected.")
)
(princ)
)

 

0 Likes
Accepted solutions (1)
765 Views
7 Replies
Replies (7)
Message 2 of 8

Sea-Haven
Mentor
Mentor

This was probably the problem.

(setq leg1 (variant-value (vla-get-value (getprop "LEG 1"))))
(setq leg2 (variant-value (vla-get-value (getprop "LEG 2"))))
(setq thick (variant-value (vla-get-value (getprop "THICKNESS"))))

And can use, note the single "\n"

;; Show popup
(Alert (strcat
"LEG 1: " (rtos leg1 2 4) "\n"
"LEG 2: " (rtos leg2 2 4) "\n"
"THICKNESS: " (rtos thick 2 4))
)

 

0 Likes
Message 3 of 8

brandonstephan
Participant
Participant

Thank you for your suggestion this correction does allow me to view the values the block is currently set to. Now I am struggling with getting the lisp file to update the PN value based on the changes made to the block such as the grip stretch or thickness change. I am getting stuck in a loop trying to correct the issue. I have implemented a check to confirm the reactor is working but keep receiving this error. ; error: bad argument type: VLReactor: (:VLR-Object-Reactor #<VLR-Object-Reactor>) it seems the AutoCAD API does not have the action I am looking for. regardless, my ultimate goal is to automatically update the user defined parameter "PN" based on the changes made to the block, whether that is a grip stretch with 1/16" encriments, or changing the thickness from a drop down pulling values from the block table. Is this action possible with a lisp file?

(vl-load-com)

(defun UpdatePN (obj)
(if (and (= (vla-get-objectname obj) "AcDbBlockReference")
(vlax-property-available-p obj 'EffectiveName)
(wcmatch (strcase (vla-get-EffectiveName obj)) "CA"))
(progn
(setq dynprops (vlax-invoke obj 'GetDynamicBlockProperties))

;; Helper to get dynamic prop by name
(defun getprop (name)
(vl-some
(function (lambda (p)
(if (eq (strcase (vla-get-PropertyName p)) (strcase name))
p)))
dynprops))

;; Get current values
(setq leg1 (variant-value (vla-get-value (getprop "LEG 1"))))
(setq leg2 (variant-value (vla-get-value (getprop "LEG 2"))))
(setq thick (variant-value (vla-get-value (getprop "THICKNESS"))))

;; Convert to required PN format
(setq leg1str (itoa (fix (* leg1 100))))
(setq leg2str (itoa (fix (*leg2 100))))
(setq thickstr (itoa (fix (* thick 1000)))) ; 0.054 ? 54

;; Build PN string like "150CA150-54"
(setq pn (strcat leg1str "CA" leg2str "-" thickstr))

;; Set PN property
(setq pnprop (getprop "PN"))
(if pnprop
(vla-put-value pnprop pn))
)))

(defun My-Reactor-Callback (reactor objList / obj)
(foreach obj objList
(UpdatePN obj)))

(defun c:STARTCA ()
(startCAReactor)
(princ "\n[CA block reactor started.]")
)

(defun c:STOPCA ()
(stopCAReactor)
(princ "\n[CA block reactor stopped.]")
)

(defun c:CHECKCA ()
(checkCAReactor)
)

(defun startCAReactor ()
;; Remove existing reactor if running again
(stopCAReactor)

;; Add new reactor
(setq myReactor
(vlr-object-reactor
nil
'((:vlr-modified . My-Reactor-Callback))
"CA_Block_Update"
))
(princ "\n[CA block reactor started automatically.]")
)

(defun stopCAReactor ()
(if (setq oldReactors (vlr-reactors :vlr-object-reactor))
(foreach r oldReactors
(if (= (vlr-data r) "CA_Block_Update")
(vlr-remove r))))
)

(defun checkCAReactor ()
(setq found nil)
(if (setq reactors (vlr-reactors :vlr-object-reactor))
(foreach r reactors
(if (= (vlr-data r) "CA_Block_Update")
(setq found T))))
(if found
(princ "\n[CA block reactor is ACTIVE]")
(princ "\n[CA block reactor is NOT running]"))
)

;; Automatic startup on load
(startCAReactor)

(princ "\n[CA block PN updater loaded. Type STARTCA / STOPCA / CHECKCA for manual control.]")
(princ)

0 Likes
Message 4 of 8

brandonstephan
Participant
Participant

thank you for the suggestions, i accidentally replied to my enquiry so I am not sure if you saw my response. see my response below in a separate reply.

0 Likes
Message 5 of 8

Sea-Haven
Mentor
Mentor

Code may need to be like this. 

 

(vla-put-value pnprop pn))

(vlax-put pnprop 'Value pn)

 Use (vlax-dump-object pnprop) to see what is inside.

0 Likes
Message 6 of 8

brandonstephan
Participant
Participant

Thank you for the suggestion.  the change did not fix the issue. After further research I believe I have determined that a LISP script is not an appropriate method for what I am attempting to achieve. from my research it seems LISP script does not have the ability to capture changes that occur within a dynamic block and update a user defined parameter value after tha change without using a manual run command because it lacks the reactor type needed. It was suggested to me that I should be using a .NET or ARX plugin in order to capture the changes. Can you confirm if this is accurate?

0 Likes
Message 7 of 8

Sea-Haven
Mentor
Mentor
Accepted solution

I have limited knowledge about using a reactor, I just know that you can look at an individual object but that is the limit of my reactor knowledge.

 

One way maybe is use an attribute for PN you can use fields to get at the dynamic block properties. Set attribute to invisible.

 

Your leg1, you can join multiple fields into a string.

%<\AcObjProp.16.2 Object(%<\_ObjId 3104793968>%).Parameter(1).UpdatedDistance>%

 

SeaHaven_0-1746752906788.png

 

0 Likes
Message 8 of 8

brandonstephan
Participant
Participant

Thank you for the suggestion, I did consider going this route by producing a work around using fields and that might have been the best option to capture the value on change without having too rely on reactors thru a LISP script. I ended up switching my approach by going with a .dll with C# as I will need to implement this style across various dynamic blocks with a variety of conditions and it seems once I was able to establish the base code it seems much easier to manage with the C#.

0 Likes