lisp to check if the filter group exist

lisp to check if the filter group exist

S_S_SS
Advocate Advocate
692 Views
9 Replies
Message 1 of 10

lisp to check if the filter group exist

S_S_SS
Advocate
Advocate

Hello every one 
I search for a lisp code to check 
if the filter group with name "formwork" exist make a list of the layers inside this filter group 
ifnot exist make a list of the layers in the DWG 

i've made this trial the issue is about the filter group 

(defun c:GetLayerList ()
  (setq layerList '()) ; Initialize an empty list for layers
  (setq layerTable (vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))) ; Get the Layers collection
  
  ; Try to find the "Formwork" filter group
  (setq filterGroupExists nil)
  (setq formworkLayers '())
  
  ; Check if a group filter exists  
  (vl-cmdf "_.-LAYER" "_FILTER" "_Edit" "Formwork" "_List" "_exit" "")
  
  
  (if (= (getvar "CMDNAMES") "LAYER")
    (progn
      (setq filterGroupExists T)
      (vl-cmdf "_List")
      (while (> (getvar "CMDACTIVE") 0)
        (command "")
      )
      ; Collect layers from the "Formwork" filter (assuming output goes to command history)
      (setq formworkLayers (read (vl-string-trim "\n" (getvar "CMDLINE"))))
    )
  )
  
  ; If the group exists, use its layers; otherwise, get all layers
  (if filterGroupExists
    (setq layerList formworkLayers)
    (vlax-for layer layerTable
      (setq layerList (cons (vla-get-name layer) layerList)) ; Add layer names to the list
    )
  )

  ; Return the layer list
  layerList
)

 

and see the attached dwg 
thanks in advance 


 

0 Likes
Accepted solutions (1)
693 Views
9 Replies
Replies (9)
Message 2 of 10

ВeekeeCZ
Consultant
Consultant

Here's your starting point...

 

(defun :LayerFilterList (typ / obj dict item ent def N LayerITEMS Layerobj Layernams lst)

  ;; typ: properties/group/group
  (setq typ (cond ((= typ "properties")	"ACLYLAYERFILTER")
                  ((= typ "group") 	"ACLYLAYERGROUP")
                  ((= typ "both")	"ACLYLAYERFILTER,ACLYLAYERGROUP")
                  ))
  (if (and (setq obj (vla-get-layers (vla-get-activedocument (vlax-get-acad-object))))
	   (= (vla-get-hasextensiondictionary obj) :vlax-true)
	   (setq obj (vla-GetExtensionDictionary obj))
	   (not (vl-catch-all-error-p
		  (setq dict (vl-catch-all-apply 'vla-item (list obj "AcLyDictionary"))))))
    (vlax-for itm dict
      (if (and (setq ent (vlax-vla-object->ename itm))
	       (setq def (entget ent))
	       (= (type (cdr (assoc 1 def))) 'STR)
	       (wcmatch (strcase (cdr (assoc 1 def))) typ)
	       (= (type (setq name (cdr (assoc 300 def)))) 'STR)
	     )
        (setq lst (cons name lst)))))
  lst)

 

Message 3 of 10

cadffm
Consultant
Consultant

Hint: Posting issue:

cadffm_0-1736500604822.png

 

Additional information for others: It's for Top-Level Filters only (not for nested filters)

 
 

 

 

Sebastian

Message 4 of 10

Sea-Haven
Mentor
Mentor

Did a google and found some code just rearranged so only look for existing layer Filter. Thanks to PBE & Gile

 

 

 

; Original code get or import layer filters by PBE
; shortened to just check does layer filter exist Jan 2025

;;; GetItem (gile)
;; Returns the item vla-object if found in the collection
;;;
;;; Arguments
;;; col: a collection (vla-object)
;;; name: the object name (string) or its index (integer)
;;;
;;; Return: the vla-object or nil

(defun GetItem (col name / obj)
  (vl-catch-all-apply
    (function (lambda () (setq obj (vla-item col name))))
  )
  obj
)

(setq *acdoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
(setq layerDict
     (vla-getExtensionDictionary (vla-get-Layers *acdoc*))
)
(setq filterlist '())
(setq layerFilters (GetItem layerDict "ACAD_LAYERFILTERS"))
(vlax-for f layerFilters
(setq filterList (cons (vla-get-Name f) filterList))
)
(if (member "Formwork" filterlist)
  (alert "found")
  (alert "not found")
)

 

 

Message 5 of 10

ВeekeeCZ
Consultant
Consultant

@cadffm wrote:

Hint: Posting issue:

cadffm_0-1736500604822.png

 

Additional information for others: It's for Top-Level Filters only (not for nested filters)

 

 


 

Thanks - that must have been autocorrect spelling... wtf!?.

 

This one work with nested filter too... but it's not adjusted to work with groups.

 

 

(defun :LayerFilterList (/ :SubFilterList)
  
  ; sub returns list of main filter and sub filters right behind
  (defun :SubFilterList (dict / ent lst)
    (foreach ent (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 350)) dict))
      (setq lst (append lst
			(cons ent (if (assoc 360 (entget ent))
				    (:SubFilterList (entget (cdr (assoc 360 (entget (cdr (assoc 360 (entget ent)))))))))))))
    lst)
  
  (mapcar '(lambda (x) (cdr (assoc 300 (entget x))))
	  (:SubFilterList (dictsearch
			    (vlax-vla-object->ename
			      (vla-getextensiondictionary
				(vla-get-layers
				  (vla-get-activedocument
				    (vlax-get-acad-object)))))
			    "ACLYDICTIONARY")

 

Message 6 of 10

Moshe-A
Mentor
Mentor
Accepted solution

@S_S_SS  hi,

 

This one is based on mr Lee Mac (LM:grouplayerfilters) function.

 

enjoy

Moshe

 

 

 

 

(defun ContentOfLayerGroup (lgName)
   (   (lambda ( foo ) (foo (entget (cdr (assoc 330 (entget (tblobjname "layer" "0")))))))
       (lambda ( enx / flag dic itm rtn)
           (and (setq dic (cdr (assoc 360 (member '(102 . "{ACAD_XDICTIONARY") enx))))
                (setq dic (cdr (assoc -1  (dictsearch dic "aclydictionary"))))
                (while (and
			 (not flag)
			 (setq itm (dictnext dic (not itm)))
		       )
                    (if (and
			  (= "AcLyLayerGroup" (cdr (assoc 1 itm)))
			  (eq (strcase (cdr (assoc 300 itm))) (strcase lgName))
			)
		      (setq rtn
			     (vl-remove-if
			      'not
		              (mapcar
			        (function
			          (lambda (e)
			            (if (= (car e) 330)
			              (cdr (assoc 2 (entget (cdr e))))
                                    )
		                  )
			        )
  		                (cdr (member (assoc 300 itm) itm))
		              ); mapcar
		             ); vl-remove-if
		      flag t); setq
                    ); if
                ); while
           ); and
	 rtn
       ); lambda
   ); wrap list
); MA:ContentOfLayerGroup


(defun c:GetLayerList (/ layfltr tbl lst)

 (if (setq layfltr (ContentOfLayerGroup "formwork"))
  (princ layfltr)
  (progn
   (while (setq tbl (tblnext "layer" (not tbl)))  
    (setq lst (cons (cdr (assoc '2 tbl)) lst))
   )
   (princ lst)
  ); progn
 ); if

 (princ)
)

 

 

 

 

Message 7 of 10

S_S_SS
Advocate
Advocate
Thanks sir
this works correctly
0 Likes
Message 8 of 10

S_S_SS
Advocate
Advocate
Hello sir
I need additional issue
I need to make the arrangement of the layers is as the ID arrangement of the layers in the AutoCAD
it change this arrangement and this makes incorrect things with my general code
0 Likes
Message 9 of 10

Moshe-A
Mentor
Mentor

@S_S_SS  hi,

 

if by saying 'arrangement of the layers' you mean sorting then you can do something like this:

 

(vl-sort layfltr '<) ; for Ascending Sort

or

(vl-sort layfltr '>) ; for Decending Sort

 

where layfltr is the list returned from (ContentOfLayerGroup) function

 

Moshe

 

 

Message 10 of 10

S_S_SS
Advocate
Advocate
thanks it works correctly
0 Likes