Jump to content

Sorting, recreating or something to sort inside table


Recommended Posts

Posted (edited)

HI,

I've moddified lisp found here

To make table of rebar lenghts ( TABELAZPRETOW.lsp lisp in attachment).

 

The lisp is creating table, but the thing is, that it is giving values propably base on it creation (newest first). So for expamle if i delete rebar in the middle and create new one, it is going on start of the table. Want it to create table form lef/right (right/left) oraz from up/down (down/up).

 

Thought that it could be done by just asking user how to sort, like multiradiobuttons and search by X or Y values of points. But maybe there is some way to recreate objects or something like that, what would rearrange objects form left/right, down/up?

 

It will be easier way, becouse sometimes I must make table few times and If it will ask user all the time to choose up/down, left/right it would be annoying/

 

Attached sample dwg and images

image.thumb.png.75a94e22cee833faf08f469d54b3c931.png

 

image.thumb.png.25e5db658ab5e897ba296cad366e0bce.png

 

 

 

 

 

 

TABELAZPRETOW.lsp sorting.dwg

image.png

image.png

Edited by zwonko
Posted (edited)

The easiest is to sort say on length.

(setq s (ssget '((0 . "LWPOLYLINE") (-4 . "=") (8 . "BZ_P_roz")))) ok now make a list of the rebar properties say by length then sort on length. Ps dont need -4 as  layer correct filter. ((120)(2400)(1586).....

 

Same again but make list with (X Y length) so could do sort on X for vertical bars and sort Y for Horizontal bars need choice. ((x y len) (123.45 56.7 1234)..... or sort on length.

 

replace 

(while (setq e (vlax-ename->vla-object(ssname s (setq r (1+ r)))))

 

(foreach val lst ;reading the length in the list so (X Y len) use  (nth 2 val)

 

(vla-settext objtable Y 1 (rtos (round (nth 2 val) 5) 2 0))

Edited by BIGAL
  • Thanks 1
Posted (edited)

Not that great at making tables so used @confutatis code from this post.

Will ask to select polylines then what side you want to start from. sort according to answer and then ask for point to create table. seemed small so i had to scale it up by 10. isn't quite like your table so maybe confutais can come in and fix that part.

 

Updated code pulled from lisp attached. also added numbering of lines to double check for correct lengths.

 

(defun C:AddLengthTable (/ ss poly ent lst side lenlst pt objtable index c)
  (vl-load-com)
  (if (setq SS (ssget '((0 . "*POLYLINE"))))
    (foreach poly (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq ent (entget poly))
      (setq lst (cons (list (cdr (assoc 10 ent)) (cdr (assoc -1 ent))) lst)) ;build list with point and entity name
    )
  )
  (initget "Left Right Top Bottom")
  (setq side
    (cond
      ((getkword "\nStarting Side? [Left,Right,Top,Bottom]: ")) ( "Left")
    )
  )
  (if lst
    (progn
      (cond 
        ((= "Left" side)
            (setq lst (vl-sort lst '(lambda (r j) (> (caar r) (caar j)))))
        )
        ((= "Right" side)
            (setq lst (vl-sort lst '(lambda (r j) (< (caar r) (caar j)))))
        )
        ((= "Top" side)
            (setq lst (vl-sort lst '(lambda (r j) (< (cadr (car r)) (cadr (car j))))))
        )
        ((= "Bottom" side)
            (setq lst (vl-sort lst '(lambda (r j) (> (cadr (car r)) (cadr (car j))))))
        )
      )
      (setq c (Length lst))
      (foreach ent lst
        (setq lenlst (cons (vla-get-length (vlax-ename->vla-object (cadr ent))) lenlst))
        (entmake (list (cons 0 "TEXT")
                       (cons 10 (car ent))
                       (cons 40 40)
                       (cons 1 (itoa c))
                 )
        )
        (setq c (1- c))
      )
      (setq pt (getpoint "\nSelect point insertion table: ")
            objtable (vla-AddTable (vla-get-modelspace (vla-get-ActiveDocument (vlax-get-acad-object))) (vlax-3d-Point pt) (+ 2 (sslength ss)) 2 60 270)
            index 1
            c 0
      )
      (vla-settext objtable 0 0 "Prêt nr X")
      (vla-SetCellTextHeight objtable 0 0 40)
      (vla-SetCellAlignment objtable 0 0 acMiddleCenter)
      (vla-setcolumnwidth objtable 0 120)   
      (vla-setcolumnwidth objtable 1 300)	
      (vla-settext objtable 1 0 "Lp.") 
      (vla-SetCellTextHeight objtable 1 0 40)
      (vla-SetCellAlignment objtable 1 0 acMiddleCenter)
      (vla-settext objtable 1 1 "D³ugoœæ") 
      (vla-SetCellTextHeight objtable 1 1 40)
      (vla-SetCellAlignment objtable 1 1 acMiddleCenter)
      (foreach elem lenlst
        (setq c (1+ c))
        (vla-SetText objtable (setq index (1+ index)) 0 c)
        (vla-SetCellTextHeight objtable index 0 40)
        (vla-SetCellAlignment objtable index 0 acMiddleCenter)
        (vla-SetText objtable index 1 (rtos elem 2 0))
        (vla-SetCellTextHeight objtable index 1 40)
        (vla-SetCellAlignment objtable index 1 acMiddleCenter)
      )
    )
  )
  (princ)
)

 

image.png.b097c95f5a218fdec3afdf89570d1395.png

Edited by mhupp
Update Code correct table.
  • Thanks 1
Posted

I left the code alone.

All I did was take the user selection (ssget) outside of the function.

I made an extra function that does the ssget selection, then sorts it according to a few options (which can be easily expanded).

You can sort from left to right for the vertical polylines (command rbrtab_x) , or from bottom to top for the horizontal ones (command rbrtab_y). 

Or sort by length which is what you want, I guess.  (command rbrtab). 

 

(vl-load-com)

(defun round ( value to )
   (setq to (abs to))
   (* to (fix (/ ((if (minusp value) - +) value (* to 0.5)) to)))    
)


;; I (Emmanuel Delay) just took the SSGET outside of the function, so as to sort the SS first 
(defun TABELAZPRETOW (s /  x y doc objtable numrows rowheight pt1 colwidth curspace)
;; Tharwat 26. 08. 2015 ;
;; mods by BIGAL 29.08.2015 now as table

(setq doc (vla-get-activedocument (vlax-get-acad-object)))
(setq curspace (vla-get-modelspace doc))
(setq pt1 (vlax-3d-point (getpoint "\nPick point for top left hand of table:  "))) 
;;(princ "\nSelect LWpolylines to export to a Table :")
;;(setq s (ssget '((0 . "LWPOLYLINE") (-4 . "=") (8 . "BZ_P_roz")))) ; tylko warstwa BZ_P_roz
(if (/= s nil)
   (progn
 ; now do table 
   (setq numrows (+ 2 (sslength s)))
   (setq numcolumns 2)
   (setq rowheight 60)   ; wysokosc wiersza
   (setq colwidth 270)	;szerokosc kolumny powinna byc rowna pierwszej + drugiej
   (setq objtable (vla-addtable curspace pt1 numrows numcolumns rowheight colwidth))
   (vla-settext objtable 0 0 "Prêt nr X")
   (vla-setcolumnwidth objtable 0 90)    ;szerokosc pierwszej kolumny
   (vla-setcolumnwidth objtable 1 180)	;szerokosc drugiej kolumny
   (vla-settext objtable 1 0 "Lp.") 
   (vla-settext objtable 1 1 "D³ugoœæ") ; aby byly polskie znaki kodowwanie w zapisanym pliku txt (lsp) musi byc ansi (widac w prawym dolnym rogu)
   (vla-SetTextHeight Objtable (+ acDataRow acHeaderRow acTitleRow) 40)	;wysokosc tekstu
   (vla-SetAlignment Objtable acDataRow acMiddleCenter)

   (setq x 1)
   (SETQ Y 2)
   (setq r -1)
   ;((lambda (r / e)
        (while (setq e (vlax-ename->vla-object(ssname s (setq r (1+ r)))))
        (vla-settext objtable Y 0 (rtos x 2 0))  ; dokladnosc numeracji Lp.  
        (vla-settext objtable Y 1 (rtos (round (vla-get-length e) 5) 2 0))   ; 2 i 0 to dzisietny i dokladnosc, dalej mozna równiez zkonwertowaæ jednostki. Tutaj mm na mm. to 5 za e wskazuje do jakiej liczby zaokraglamy. korzystajac z zdefiniowanej funkcji round
        (setq x (1+ x ))
        (setq y (1+ Y ))
 ); while
    ; )) ;lambda
     )   ;progn
   (alert "You have not picked any plines run again")
   )     ; if      
 (princ)

) ; defun


;; @param sortby: l/x/y (Length/X/Y)
(defun TABELAZPRETOW_prep (sortby / s s2 i ent xlist ylist lengthlist ip len sortindexes)

   ;; user selects the polylines
  (princ "\nSelect LWpolylines to export to a Table : ")
  (setq s (ssget (list (cons 0  "LWPOLYLINE") (cons 8 "BZ_P_roz")))) ; tylko warstwa BZ_P_roz
  
  ;;  Now we sort.  We make a list of just the x and a list of the y values.
  (setq i 0)
  (setq xlist (list))
  (setq ylist (list))
  (setq lengthlist (list))
  (repeat (sslength s)
    (princ "\n")
	(setq ent (ssname s i))
	(setq ip (vlax-curve-getendpoint (vlax-ename->vla-object ent)))
	(setq len (vla-get-length (vlax-ename->vla-object ent)))
	
	(setq xlist (append xlist (list (nth 0 ip))))
	(setq ylist (append ylist (list (nth 1 ip))))
	(setq lengthlist (append lengthlist (list len)))
	
	(setq i (+ i 1))
  )
  
  ;; Now sort the data by length, or X or Y value.  Whatever you need.
  ;; (vl-sort-i) returns the indexes instead of returning the values
  ;; you can easily add option.  For example from big to small ...  
  (if (= sortby "l")
    (setq sortindexes (vl-sort-i lengthlist '<))
  )
  (if (= sortby "x")
    (setq sortindexes (vl-sort-i xlist '<))
  )
  (if (= sortby "y")
    (setq sortindexes (vl-sort-i ylist '<))
  )

  ;; now we make a new list of items, sorted by whatever we picked
  (setq s2 (ssadd))
  (setq i 0)
  (repeat (sslength s)
	(ssadd (ssname s (nth i sortindexes)) s2)
    (setq i (+ i 1))
  )
  ;; and we pass s2 to the function instead of s
  (TABELAZPRETOW s2)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; sorted by x
(defun c:rbrtab_x ()
  (TABELAZPRETOW_prep "x")
) 

;; sorted by y
(defun c:rbrtab_y ()
  (TABELAZPRETOW_prep "y")
) 

;; sorted by length
(defun c:rbrtab ()
  (TABELAZPRETOW_prep "l")
)

 

 

  • Like 1
Posted (edited)

WoW!!!!

 

thanks @mhupp and @Emmanuel Delay; both lisp works well !!!!

@Emmanuel Delay, actually I've want rtab_x and rtab_y :) It is better for " on site" to be up/down left/right

@mhupp You did great Job. It is also numbering rebars. I will try to add to ask user to get firstly number of rebar; like for expample "4" and then it will number it like 4.1, 4.2, 4.3 etc. Also need to add round of the lenght.

Guys! You did work for me! actually I thougt I will do this myself just with Your help, but the job is done!!!

Thank You so much!

 

 

Edited by zwonko
  • Like 1
  • Thanks 1

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