Jump to content

sorting by block attributes


Terry.T

Recommended Posts

Hi, 

I am a beginner and I had a problem about sorting.

I had many block with attributes "SORT_ORDER" and "NUMBER"

 

what i want to do is :

1. Select all block in a list

(setq lst1 (ssget "x" '((8 . "layer"))))

2. sort list by attributes "SORT_ORDER"

(no idea)

3.apply new number by lst1 form 001 to 100 into attributes (3 digit).

Because we need to change the number many many time but the number must in order.

 

such as

block format:("SORT_ORDER"== "NUMBER")

(1==001), (2== 002), (3== 003), (4== 004), (5== 005), (6== 006), (7== 007)

we want to del 3

(1== 001), (2==002), (4== 003), (5== 004), (6== 005), (7== 006)

and add back 3 and add 2.1 between b and c

(1== 001), (2== 002, (2.1== 003), (3== 004), (4== 005), (5== 006), (6== 007), (7== 008)

 

Thanks,

Link to comment
Share on other sites

5 hours ago, Terry.T said:

Hi, 

I am a beginner and I had a problem about sorting.

I had many block with attributes "SORT_ORDER" and "NUMBER"

 

what i want to do is :

1. Select all block in a list

(setq lst1 (ssget "x" '((8 . "layer"))))

2. sort list by attributes "SORT_ORDER"

(no idea)

3.apply new number by lst1 form 001 to 100 into attributes (3 digit).

Because we need to change the number many many time but the number must in order.

 

such as

block format:("SORT_ORDER"== "NUMBER")

(1==001), (2== 002), (3== 003), (4== 004), (5== 005), (6== 006), (7== 007)

we want to del 3

(1== 001), (2==002), (4== 003), (5== 004), (6== 005), (7== 006)

and add back 3 and add 2.1 between b and c

(1== 001), (2== 002, (2.1== 003), (3== 004), (4== 005), (5== 006), (6== 007), (7== 008)

 

Thanks,

 Attached drawing example

pls

Link to comment
Share on other sites

TEST-LSP FOR NUMBING2.dwg

thanks for the reply.

 

and here is what i am doing yesterday.

 

(defun C:nm ( / sel1 sel2 )

	(setq num 0)
	(setq lop 0)

	(setq sel1 (ssget "x" '((8 . "NUMBERING")))) 

	(foreach pp1 (ssnamex sel1)
	(setq num (1+ num))
	)			

	(foreach pp (ssnamex sel1)	
					(setq sel2 (ssname sel1 lop))			   
					(setq a (entnext sel2))
					(setq b (entnext a))
					(setq c (entget b))		
					(setq d (assoc 1 c))					
					(setq e (cdr d))			
					(setq num (1- num))
					(setq lop (1+ lop))
					(setq a1 (cons e a1))
	)	;foreach
	(vl-sort a1 '<)

);end defun

 

13 hours ago, hosneyalaa said:

 Attached drawing example

pls

 

i am not sure is it a right way to sort the block.

 

Thanks.

 

Link to comment
Share on other sites

try this

(defun C:nm (/ ss i blk atts lst a1 P O)
  (vl-load-com)
  (setq ss (ssget '((0 . "INSERT") (8 . "NUMBERING"))))  ;only select blocks on numbering layer
  (repeat (setq i (sslength ss))
    (setq blk (vlax-ename->vla-object (ssname SS (setq i (1- i))))
          atts (vlax-safearray->list (vlax-variant-value (vla-getattributes blk)))
    )
    (foreach x atts
      (if (= (vla-get-tagstring x) "PORT_NUMBER")
        (setq P (vla-get-textstring x))
        (setq O (vla-get-textstring x))
      )
    )
    (setq lst (list P O)) ;create a mini list
    (setq a1 (append a1 (list lst))) ;join all mini lists into big list
  )  
  (vl-sort a1 '(lambda (x y) (< (car x) (car y)))) ;sort by first item in the mini list
)

3. I don't know what you mean.

 

Edited by mhupp
  • Like 1
Link to comment
Share on other sites

Another -

(defun c:pno ( / a c i l n p q s x )
    (if (setq s (ssget "_X" '((0 . "INSERT") (8 . "NUMBERING"))))
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      a (entnext (ssname s i))
                      x (entget a)
                )
                (while (and (= "ATTRIB" (cdr (assoc 0 x))) (not (and p n)))
                    (cond
                        (   (= "PORT_NUMBER" (cdr (assoc 2 x)))
                            (setq p a)
                        )
                        (   (= "SORT_ORDER" (cdr (assoc 2 x)))
                            (setq n (atoi (cdr (assoc 1 x))))
                        )
                    )
                    (setq a (entnext a)
                          x (entget  a)
                    )
                )
                (if (and p n)
                    (setq l (cons p l) p nil
                          q (cons n q) n nil
                    )
                )
            )
            (setq c 1)
            (foreach n (vl-sort-i q '<)
                (entmod (list (cons -1 (nth n l)) (cons 1 (padz (itoa c) 3))))
                (setq c (1+ c))
            )
        )
    )
    (princ)
)

(defun padz ( x n )
    (if (< (strlen x) n) (padz (strcat "0" x) n) x)
)

(princ)

 

  • Like 1
Link to comment
Share on other sites

12 hours ago, Lee Mac said:

Another -


(defun c:pno ( / a c i l n p q s x )
    (if (setq s (ssget "_X" '((0 . "INSERT") (8 . "NUMBERING"))))
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      a (entnext (ssname s i))
                      x (entget a)
                )
                (while (and (= "ATTRIB" (cdr (assoc 0 x))) (not (and p n)))
                    (cond
                        (   (= "PORT_NUMBER" (cdr (assoc 2 x)))
                            (setq p a)
                        )
                        (   (= "SORT_ORDER" (cdr (assoc 2 x)))
                            (setq n (atoi (cdr (assoc 1 x))))
                        )
                    )
                    (setq a (entnext a)
                          x (entget  a)
                    )
                )
                (if (and p n)
                    (setq l (cons p l) p nil
                          q (cons n q) n nil
                    )
                )
            )
            (setq c 1)
            (foreach n (vl-sort-i q '<)
                (entmod (list (cons -1 (nth n l)) (cons 1 (padz (itoa c) 3))))
                (setq c (1+ c))
            )
        )
    )
    (princ)
)

(defun padz ( x n )
    (if (< (strlen x) n) (padz (strcat "0" x) n) x)
)

(princ)

 

 

Amazing , that is what exactly i what. thank a lot.

 

Link to comment
Share on other sites

On 5/16/2021 at 9:24 PM, Lee Mac said:

Another -


(defun c:pno ( / a c i l n p q s x )

;-------------------NEW ADD-----------------------------------
	(princ "\nPlease pick a block to numbering: ")                  
			(setq a1 (car (entsel)))		
			(setq d1 (entget a1))		
			(setq e (assoc 8 d1))
;-------------------NEW ADD-----------------------------------


;   (if (setq s (ssget "_X" '((0 . "INSERT") (8 . "NUMBERING"))))
;	(if (setq s (ssget "_X" '((0 . "INSERT") , e)))
;	(if (setq s (ssget "_X" '((0 . "INSERT") (e) )))
	(if (setq s (ssget "_X" '((0 . "INSERT") e)))
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      a (entnext (ssname s i))
                      x (entget a)
                )
                (while (and (= "ATTRIB" (cdr (assoc 0 x))) (not (and p n)))
                    (cond
                        (   (= "PORT_NUMBER" (cdr (assoc 2 x)))
                            (setq p a)
                        )
                        (   (= "SORT_ORDER" (cdr (assoc 2 x)))
                            (setq n (atoi (cdr (assoc 1 x))))
                        )
                    )
                    (setq a (entnext a)
                          x (entget  a)
                    )
                )
                (if (and p n)
                    (setq l (cons p l) p nil
                          q (cons n q) n nil
                    )
                )
            )
            (setq c 1)
            (foreach n (vl-sort-i q '<)
                (entmod (list (cons -1 (nth n l)) (cons 1 (padz (itoa c) 3))))
                (setq c (1+ c))
            )
        )
    )
    (princ)
)

(defun padz ( x n )
    (if (< (strlen x) n) (padz (strcat "0" x) n) x)
)

(princ)

 

 

May i learn more about "ssget"

I am trying to let the computer know which layer i need and i set a value "E" to keep it,

is it possible, if i change the coding like this? (not working)

Link to comment
Share on other sites

The issue is that the ssget filter list is quoted as a literal list, and therefore the symbol 'e' will not be evaluated as a variable to yield the value it has been assigned, but will instead remain as a symbol. To better understand this behaviour, and how to alter the expression to evaluate the variable, you may wish to read my tutorial on The Apostrophe and the Quote Function.

  • Like 1
Link to comment
Share on other sites

On 5/24/2021 at 4:05 PM, Lee Mac said:

The issue is that the ssget filter list is quoted as a literal list, and therefore the symbol 'e' will not be evaluated as a variable to yield the value it has been assigned, but will instead remain as a symbol. To better understand this behaviour, and how to alter the expression to evaluate the variable, you may wish to read my tutorial on The Apostrophe and the Quote Function.

Thanks a lot about this 

 

i have update the app and it is works

(defun c:pno ( / a c i l n p q s x )

;-------------------NEW ADD-----------------------------------
	(princ "\nPlease pick a block to numbering: ")                  
			(setq a1 (car (entsel)))		
			(setq d1 (entget a1))		
;-------------------NEW ADD-----------------------------------

;-------------------change-------------------------------------
;   (if (setq s (ssget "_X" '((0 . "INSERT") (8 . "NUMBERING"))))
		(if (setq s (ssget "_X" (list '(0 . "INSERT") (assoc 8 d1))))
;-------------------change-------------------------------------
        (progn
            (repeat (setq i (sslength s))
                (setq i (1- i)
                      a (entnext (ssname s i))
                      x (entget a)
                )
                (while (and (= "ATTRIB" (cdr (assoc 0 x))) (not (and p n)))
                    (cond
                        (   (= "PORT_NUMBER" (cdr (assoc 2 x)))
                            (setq p a)
                        )
                        (   (= "SORT_ORDER" (cdr (assoc 2 x)))
                            (setq n (atoi (cdr (assoc 1 x))))
                        )
                    )
                    (setq a (entnext a)
                          x (entget  a)
                    )
                )
                (if (and p n)
                    (setq l (cons p l) p nil
                          q (cons n q) n nil
                    )
                )
            )
            (setq c 1)
            (foreach n (vl-sort-i q '<)
                (entmod (list (cons -1 (nth n l)) (cons 1 (padz (itoa c) 3))))
                (setq c (1+ c))
            )
        )
    )
    (princ)
)

(defun padz ( x n )
    (if (< (strlen x) n) (padz (strcat "0" x) n) x)
)

(princ)

 

Link to comment
Share on other sites

When in doubt I use all filters as cons this supports a variable by name and a value like "abc" or 1. Using '(( takes a little getting use to as per info by Lee.

 

(setq ss (ssget "X" (list (cons 0 "LWPOLYLINE")(cons 8 mylayer) (cons 70 1) )))

(setq ss (ssget "X" (list (cons 0 "LWPOLYLINE")(cons 8 "Design") (cons 70 isClosed) )))

 

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...