Jump to content

Return list in pairs


gsc

Recommended Posts

Hi,

 

I have a lisp function which returns a list of dynamic block properties:

 

(defun getdynprops ( blk / lst )
    (vl-load-com)
    (setq lst
        (mapcar '(lambda ( x ) (cons (vla-get-propertyname x) (vlax-get x 'value)))
            (vlax-invoke (vlax-ename->vla-object blk) 'getdynamicblockproperties)
        )
    )
)

 

Since my dynamic block only has a number of "polar stretch" parameter/actions , which exist of a Distance and an Angle property. The function returns a list like:

((<Angle1> . <Value>) (<Distance1> . <Value>) (<Angle2> . <Value>) (<Distance2> . <Value>) (<Angle3> . <Value>) (<Distance3> . <Value>) ... )

 

But my goal is to pair the Angle and Distance property in the list. e.g.

( ((<Angle1> . <Value>) (<Distance1> . <Value>)) ((<Angle2> . <Value>) (<Distance2> . <Value>)) ((<Angle3> . <Value>) (<Distance3> . <Value>)) ... )

 

How do I achieve this?

 

Link to comment
Share on other sites

Untested.

(defun getdynprops (blk / r)
  (mapcar '(lambda (x / l)
             (if l (setq r (cons (append l (cons (vla-get-propertyname x) (vlax-get x 'value))) r) l nil)
               (setq l (cons (vla-get-propertyname x) (vlax-get x 'value)))
               )
             )
          (vlax-invoke (vlax-ename->vla-object blk) 'getdynamicblockproperties)
          )
  r
  ) (vl-load-com)

 

Link to comment
Share on other sites

Here's another assuming that you have ALL matching Angle/Distance properties.

(defun getdynprops (blk)
  (mapcar '(lambda (x) (cons (vla-get-propertyname x) (vlax-get x 'value)))
	  (vlax-invoke (vlax-ename->vla-object blk) 'getdynamicblockproperties)
  )
)
(if (setq r (getdynprops (car (entsel))))
  (progn (setq r (vl-sort r '(lambda (r j) (< (car r) (car j)))))
	 (mapcar '(lambda (r j) (list r j)) r (member (nth (/ (length r) 2) r) r))
  )
)

 

Link to comment
Share on other sites

22 hours ago, Tharwat said:

Untested.


(defun getdynprops (blk / r)
  (mapcar '(lambda (x / l)
             (if l (setq r (cons (append l (cons (vla-get-propertyname x) (vlax-get x 'value))) r) l nil)
               (setq l (cons (vla-get-propertyname x) (vlax-get x 'value)))
               )
             )
          (vlax-invoke (vlax-ename->vla-object blk) 'getdynamicblockproperties)
          )
  r
  ) (vl-load-com)

 

This returns all NIL values

Link to comment
Share on other sites

15 hours ago, ronjonp said:

Here's another assuming that you have ALL matching Angle/Distance properties.


(defun getdynprops (blk)
  (mapcar '(lambda (x) (cons (vla-get-propertyname x) (vlax-get x 'value)))
	  (vlax-invoke (vlax-ename->vla-object blk) 'getdynamicblockproperties)
  )
)
(if (setq r (getdynprops (car (entsel))))
  (progn (setq r (vl-sort r '(lambda (r j) (< (car r) (car j)))))
	 (mapcar '(lambda (r j) (list r j)) r (member (nth (/ (length r) 2) r) r))
  )
)

 

 

For the IF part you could also use a Lee Mac sub function:
 

(defun group-n ( l n / r )
    (if l
        (cons
            (reverse (repeat n (setq r (cons (car l) r) l (cdr l)) r))
            (group-n l n)
        )
    )
)

 

Link to comment
Share on other sites

5 hours ago, gsc said:

 

For the IF part you could also use a Lee Mac sub function:
 


(defun group-n ( l n / r )
    (if l
        (cons
            (reverse (repeat n (setq r (cons (car l) r) l (cdr l)) r))
            (group-n l n)
        )
    )
)

 

The list still has to be sorted alphabetically and broken in two so not sure how that would work per your original example.

Edited by ronjonp
Link to comment
Share on other sites

The functions posted so far rely on a number of assumptions:

  • All dynamic block properties returned by the ActiveX getdynamicblockproperties method are either Angle or Distance parameters (in reality, there will also be many origin parameters)
  • There are equal numbers of Angle & Distance parameters, perfectly paired

As such, if you wanted to be certain that you were pairing a parameter named "Angle1" with a parameter named "Distance1" and so on, you may need to use somewhat uglier code such as the following:

(defun getdynprops ( blk / ang dis nme )
    (foreach  prp (reverse (vlax-invoke blk 'getdynamicblockproperties))
        (setq nme (strcase (vla-get-propertyname prp) t))
        (cond
            (   (wcmatch nme "angle#*")
                (setq ang (cons (cons nme (vlax-get prp 'value)) ang))
            )
            (   (wcmatch nme "distance#*")
                (setq dis (cons (cons nme (vlax-get prp 'value)) dis))
            )
        )
    )
    (vl-remove-if-not 'cadr
        (mapcar '(lambda ( a ) (list a (assoc (strcat "distance" (substr (car a) 6)) dis))) ang)
    )
)

 

  • Like 1
Link to comment
Share on other sites

9 hours ago, Lee Mac said:

The functions posted so far rely on a number of assumptions:

  • All dynamic block properties returned by the ActiveX getdynamicblockproperties method are either Angle or Distance parameters (in reality, there will also be many origin parameters)
  • There are equal numbers of Angle & Distance parameters, perfectly paired

As such, if you wanted to be certain that you were pairing a parameter named "Angle1" with a parameter named "Distance1" and so on, you may need to use somewhat uglier code such as the following:


(defun getdynprops ( blk / ang dis nme )
    (foreach  prp (reverse (vlax-invoke blk 'getdynamicblockproperties))
        (setq nme (strcase (vla-get-propertyname prp) t))
        (cond
            (   (wcmatch nme "angle#*")
                (setq ang (cons (cons nme (vlax-get prp 'value)) ang))
            )
            (   (wcmatch nme "distance#*")
                (setq dis (cons (cons nme (vlax-get prp 'value)) dis))
            )
        )
    )
    (vl-remove-if-not 'cadr
        (mapcar '(lambda ( a ) (list a (assoc (strcat "distance" (substr (car a) 6)) dis))) ang)
    )
)

 


Thanx man this is working, although I had to change the wcmatch search string "angle#*" and "distance#*" to "angle*" and "distance*", otherwise I got al nil values

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...