Get list of parameters being used in block WITHOUT vla- vlax-

Get list of parameters being used in block WITHOUT vla- vlax-

CodeDing
Advisor Advisor
2,292 Views
5 Replies
Message 1 of 6

Get list of parameters being used in block WITHOUT vla- vlax-

CodeDing
Advisor
Advisor

Hello,

 

I'm trying to return a list of parameters (specifically point parameters, and their locations) when I select a block. and while I understand vla-vlax- functions are faster, I am trying to accomplish this in AutoLISP without them.

 

Can anyone describe or provide some code as to how I can accomplish this? I'm not an expert at managing DXF codes or searching dictionaries/Xrecords/tabels yet, but I do feel pretty competent if pointed in the right direction.

 

Example:

I have a block with a triangle. And within that block are point parameters with X / Y locations...

image.pngimage.png

 

...I would like to CHECK if this block has point parameters THEN get their locations if so. All without help of vla-vlax- functions.

 

Attached is a sample dwg.

 

...partial code:

(defun c:BGET ( / blkEnt blkName e)
;get block
(setq blkEnt (car (entsel "\nSelect Block: ")))
;(dumpallproperties blkEnt)
;store block name
(setq blkName (getpropertyvalue blkEnt "BlockTableRecord/Name"))
(setq e (tblobjname "BLOCK" blkName))

;;;; get list of parameters in block

(princ)
);defun

 

Best,

 

0 Likes
Accepted solutions (2)
2,293 Views
5 Replies
Replies (5)
Message 2 of 6

_gile
Consultant
Consultant

Hi,

 

(dumpallproperties blkEnt) shows you how to do:

Command: (getpropertyvalue blkEnt "AcDbDynBlockPropertyA1 X")
0.380249

Command: (getpropertyvalue blkEnt "AcDbDynBlockPropertyA1 Y")
-54.1079

Command: (getpropertyvalue blkEnt "AcDbDynBlockPropertyA2 X")
-26.6635

More generally, to get (or set) a dynamic block property: (strcat "AcDbDynBlockProperty" propertyName).

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 6

CodeDing
Advisor
Advisor

@_gile,

 

Thank you for the reply! I am actually familiar with the "getpropertyvalue" function, and I am sorry because I was not more specific in my original post.

 

TO BE MORE SPECIFIC:

I am trying to return the point parameter values if I do NOT know their names. 

I would like to search a block for point parameters, THEN return their names/values so that I can manipulate them even if they are different per block.

 

My apologies for not being more specific.

 

Best,

~DD

0 Likes
Message 4 of 6

_gile
Consultant
Consultant
Accepted solution

Sorry, I read to fast you question.

 

Here's a way:

(setq blkName (getpropertyvalue blkEnt "BlockTableRecord/Name"))
(setq block (entget (tblobjname "block" blkName)))
(setq blockRecord (entget (cdr (assoc 330 block))))
(setq xDictionary (entget (cdr (assoc 360 (member '(102 . "{ACAD_XDICTIONARY") blockRecord)))))
(setq enhancedBlock (entget (cdr (assoc 360 (member '(3 . "ACAD_ENHANCEDBLOCK") xDictionary)))))
(vl-remove
  nil
  (mapcar
    '(lambda (pair / elst)
       (setq elst (entget (cdr pair)))
       (if (wcmatch (cdr (assoc 0 elst)) "*PARAMETER")
	 (cons (cdr (assoc 0 elst)) (vl-remove-if-not '(lambda (x) (< 300 (car x) 309)) elst))
       )
     )
    (vl-remove-if-not
      '(lambda (x) (= (car x) 360))
      enhancedBlock
    )
  )
)

The last expressionallows to dump the dynamic parameters

With the block you provided, it returns the following list. Code 303 is what you're looking for with Point parameters but it may differ with other types of parameters (linear, visibility,...)

(("BLOCKPOINTPARAMETER"
   (301 . "DisplacementX")
   (302 . "DisplacementY")
   (303 . "A3")
   (304 . "")
 )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "A2")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "A1")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "B1")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "B2")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "B3")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "C1")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "C2")
    (304 . "")
  )
  ("BLOCKPOINTPARAMETER"
    (301 . "DisplacementX")
    (302 . "DisplacementY")
    (303 . "C3")
    (304 . "")
  )
)

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 5 of 6

CodeDing
Advisor
Advisor

@_gile,

 

I couldn't ask for more. Thank you for the help. This will get me in the right direction.

 

Best,

~DD

0 Likes
Message 6 of 6

_gile
Consultant
Consultant
Accepted solution

Here's a more generic and reliable implementation.

 

;; getDynBlockRecord
;; Returns the dynamic block record
;;
;; Argument
;; blockRef: Block reference
(defun getDynBlockRecord (blockRef / elst xDictionary blockRep repData blockRecord block)
  (if (= (cdr (assoc 0 (setq elst (entget blockRef)))) "INSERT")
    (if	(and (setq xDictionary (cdr (assoc 360 (member '(102 . "{ACAD_XDICTIONARY") elst))))
	     (setq blockRep (cdr (assoc 360 (member '(3 . "AcDbBlockRepresentation") (entget xDictionary)))))
	)
      (setq repData	(cdr (assoc 360 (member '(3 . "AcDbRepData") (entget blockRep))))
	    blockRecord	(entget (cdr (assoc 340 (entget repData))))
      )
      (setq block	(entget (tblobjname "block" (cdr (assoc 2 elst))))
	    blockRecord	(entget (cdr (assoc 330 block)))
      )
    )
  )
)


;; getDynPropParams
;; Returns a list of lists: one list for each dynamic parameter
;; (parameterType parameterName1 [parameterName2] [(valueNames ...)])
(defun getDynPropParams	(blockRecord / xDictionary enhancedBlock)
  (if (and (setq xDictionary (cdr (assoc 360 (member '(102 . "{ACAD_XDICTIONARY") blockRecord))))
	   (setq enhancedBlock (cdr (assoc 360 (member '(3 . "ACAD_ENHANCEDBLOCK") (entget xDictionary)))))
      )
    (vl-remove
      nil
      (mapcar
	'(lambda (pair / elst)
	   (setq elst  (entget (cdr pair))
		 param (cdr (assoc 0 elst))
	   )
	   (cond
	     ((= param "BLOCKPOINTPARAMETER")
	      (list param
		    (cdr (assoc 303 elst))
	      )
	     )
	     ((= param "BLOCKLINEARPARAMETER")
	      (list param
		    (cdr (assoc 305 elst))
	      )
	     )
	     ((= param "BLOCKPOLARPARAMETER")
	      (list param
		    (cdr (assoc 305 elst))
		    (cdr (assoc 307 elst))
	      )
	     )
	     ((= param "BLOCKXYPARAMETER")
	      (list param
		    (cdr (assoc 305 elst))
		    (cdr (assoc 306 elst))
	      )
	     )
	     ((= param "BLOCKROTATIONPARAMETER")
	      (list param
		    (cdr (assoc 305 elst))
	      )
	     )
	     ((= param "BLOCKFLIPPARAMETER")
	      (list param
		    (cdr (assoc 305 elst))
		    (list (cdr (assoc 307 elst)) (cdr (assoc 308 elst)))
	      )
	     )
	     ((= param "BLOCKVISIBILITYPARAMETER")
	      (list param
		    (cdr (assoc 301 elst))
		    (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 303 (car x))) elst))
	      )
	     )
	     ((= param "BLOCKLOOKUPPARAMETER")
	      (list param
		    (cdr (assoc 303 elst))
	      )
	     )
	   )
	 )
	(vl-remove-if-not
	  '(lambda (x) (= (car x) 360))
	  (entget enhancedBlock)
	)
      )
    )
  )
)

Using example:

(defun c:dumpDynParams (/ ent)
  (if (and (setq ent (car (entsel)))
	   (setq blockRec (getDynBlockRecord ent))
	   (setq params (getDynPropParams blockRec))
      )
    (foreach l params
      (terpri)
      (princ l)
    )
  )
  (princ)
)


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub