zams23 Posted April 16, 2020 Share Posted April 16, 2020 i have so many block attribute in my drawing, when i selection attribute and use attout. the result from txt file the list become not sequential. for example : I want the order to remain the same Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted April 16, 2020 Share Posted April 16, 2020 6 hours ago, zams23 said: i have so many block attribute in my drawing, when i selection attribute and use attout. the result from txt file the list become not sequential. for example : I want the order to remain the same it seems ATTOUT sorts 'Handles' in decreasing (Z-A) order. you can sort (A-Z) using EXCEL, select all excludes header (1st row) Quote Link to comment Share on other sites More sharing options...
zams23 Posted April 16, 2020 Author Share Posted April 16, 2020 thanks for your help, However, this method is not always accurate, because some rows handles are not ordered from (A-Z). like this attribute: and the result use sort by handle rows like this : Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted April 17, 2020 Share Posted April 17, 2020 3 hours ago, zams23 said: thanks for your help, However, this method is not always accurate, because some rows handles are not ordered from (A-Z). like this attribute: and the result use sort by handle rows like this : is your table just line object and not acTable ? then learn how to sort Y coordinates of insertion points from ssget (assoc 5 (enget en)) ; for handle (assoc 10 (enget en)) ; for coordinates eg: (setq lst '((123 456)(657 888)(-234 -89)(345 678))) (vl-sort lst ''((a b) (> (cadr a)(cadr b)) sorted descending Z-A of Y coordinates '((657 888) (345 678) (123 456) (-234 -89)) can try many useful library here: Attribute functions p/s: can you post sample DWG? Quote Link to comment Share on other sites More sharing options...
zams23 Posted April 17, 2020 Author Share Posted April 17, 2020 This i attached sample dwg,. SAMPLE.dwg Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 17, 2020 Share Posted April 17, 2020 (edited) Need one more question now the list is (x y ID and how many attributes) sort on y then same order, ok that's done. But what now csv file ? For anyone they are blocks including a border as part of block. Edited April 17, 2020 by BIGAL Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted April 17, 2020 Share Posted April 17, 2020 7 hours ago, BIGAL said: Need one more question now the list is (x y ID and how many attributes) sort on y then same order, ok that's done. But what now csv file ? For anyone they are blocks including a border as part of block. i just notice Bricscad does not have Express Tool?! no ATTOUT ? my attempt is not perfect, unlike ET can select all, i just filter block name selection, i.e: much easier all same tags output keep the output txt format same as ET does. ;; ATT:SORT - for Bricscad user ;; ;; <> : sort - '<' & '>' sign or mode ;; < is ascending/incremental (A-Z) ;; > is descending/decremental (Z-A) ;; i : sorting nth index , 4 is not used because block name all the same default 3 ;; (X Y Z HANDLE BLKNAME TAGNAME TAG1 TAG2 TAGx ) ;; (0 1 2 3 4 5 6 7 x ) ;; note: sorting may not work as expected other than 0 1 2 (XYZ) ;; bn : block name (string) ;; example : ;; (att:sort "ID" 3 < ) ; Blockname="ID" ,3=HANDLE , < =ascending/increment A-Z ;; (att:sort "BKL" 1 > ) ; Blockname="BKL" ,1=Y coordinate, > =descending/decrement Z-A ;; output: ;; returns list of attributes string ATTOUT format ;; (("HANDLE\tBLOCKNAME\tTAGNAME\tTAG1\tTAG2\t etc...") ("HANDLE\tBLOCKNAME\tTAGNAME\tTAG1\tTAG2\t etc.. " ) ) (vl-load-com) (defun att:sort ( bn i <> / ss ass tags l) ;hanhphuc 17.04.2020 (if (setq i (cond ((= i 4) 3)(i)) ; nth 4 is unused ss (ssget ":L" (list '(0 . "INSERT") (cons 2 bn ) '(66 . 1)))) (progn (vlax-for obj (setq ass (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object) ) ) ) (setq l (cons (append (vlax-get obj 'InsertionPoint) (list (vla-get-Handle obj)) (list (vla-get-name obj)) (mapcar '(lambda (x) (LM:vl-getattributevalue obj x)) (setq tags (mapcar 'vla-get-tagstring (vlax-invoke obj 'getattributes) ) ) ) ) l ) ) ) (vlax-release-object ass) (cons (apply 'strcat (vl-list* "HANDLE" "\tBLOCKNAME" (mapcar '(lambda (x) (strcat "\t" x)) tags) ) ) (mapcar '(lambda (x) (setq x (cdddr x)) (apply 'strcat (cons (strcat "'" (car x)) (mapcar '(lambda (x) (strcat "\t" x)) (cdr x)) ) ) ) (vl-sort l '(lambda (a b) (<> (nth i a) (nth i b)))) ) ) ) ) ) ;; Get Attribute Values - Lee Mac ;; Returns an association list of attributes present in the supplied block. ;; blk - [ent] Block (Insert) Entity Name ;; Returns: [lst] Association list of ((<tag> . <value>) ... ) (defun LM:vl-getattributevalue ( blk tag ) (setq tag (strcase tag)) (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att))) (vlax-invoke blk 'getattributes)) ) 7 hours ago, zams23 said: This i attached sample dwg,. SAMPLE.dwgUnavailable ok not AcTable object , much easier please read the header of routine of att:sort routine you can customize your sorting parameters, simply edit index (0 1 2 3 ...) or (< >) sign check in the example codes in C:ATTT, commented in side the code (att:sort bn 1 > ) ;;; here to adjust, (1) indicates sorting Y-coordinates, (>) Z-A (att:sort bn 0 < ) ;;; (0) indicates X-coordinates, (<) increment , but you need to rotate 90d to test (att:sort bn 5 < ) ;;This (5) indicates sorting TAGName , (4)=not in use BlockName all same, you can try 3,5,6 etc.. but can't promise example: Please test in your drawing command : ATTT Index for block name ? : 39 ;;key in index 39 is for your block name "ID" (defun c:attt (/ ss l ls f fn bn b) ;; put your error handle here (foreach x (reverse ((lambda (i / l) (while (setq b (tblnext "BLOCK" (not b))) (setq ls (cons (cons (setq i (1+ i)) (cdr (assoc 2 b)) ) ls ) ) ) ) -1 ) ) (terpri) (princ x) ) (textscr) (initget 5) (if (and (setq i (getint "\nIndex for block name? : ")) (< i (length ls)) (setq bn (cdr (assoc i ls))) (setq l (att:sort bn 1 >)) ;;; here to adjust, (1) indicates sorting Y-coordinates, (>) Z-A (setq fn (vl-filename-mktemp "att-" nil ".txt" ) ) (setq f (open fn "w")) ) (progn (foreach x l (write-line x f) ) (if f (close f) ) (vl-cmdf "_START" (strcat "EXCEL " fn)) ) (princ "\nInvalid block selections!") ) (princ) ) please test if work or error, i didn't test all Quote Link to comment Share on other sites More sharing options...
StevJ Posted April 17, 2020 Share Posted April 17, 2020 (edited) Try this ATOUT program and see if it's something you can modify to your needs. Works for me in Autocad 2014 and 2016 in windows 7 and 10 Creates an Excel file in your working folder and includes sort functions. Read the header and comments. Steve ATOUT.LSP Edited April 17, 2020 by StevJ 1 Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 18, 2020 Share Posted April 18, 2020 hanhphuc I would look at 'getattributes a bit closer as this does just that and in your code your doing it twice by using lee's method of getting by tag name there is no need for the OP's request. an example (setq lst '()) (setq ss (ssget (list (cons 0 "INSERT")))) (repeat (setq x (sslength ss)) (if (/= (setq atts (vlax-invoke (vlax-ename->vla-object (ssname SS (setq x (- x 1)))) 'getattributes)) null) (progn (setq lst2 '()) (foreach att atts (setq lst2 (cons (vla-get-textstring att) lst2)) ) (setq lst (cons lst2 lst)) ) ) ) (princ lst) 1 Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted April 18, 2020 Share Posted April 18, 2020 1 hour ago, BIGAL said: hanhphuc I would look at 'getattributes a bit closer as this does just that and in your code your doing it twice by using lee's method of getting by tag name there is no need for the OP's request. an example <code snippet> thanks for commenting, in fact i have my sub to populate attributes tag & value (setq l (hp:eat$ (car(entsel)) nil) ) ;(("NAME" . "G01") ("CO" . "-5.183333") ("CO2" . "119.415600") ("REMARKS" . "OLT 3753 - HARTACO INDAH")) (mapcar 'car l ) ;("NAME" "CO" "CO2" "REMARKS") (LM:vl-getattributevalue obj x) as courtesy, twice 'getattribute i admit, just pointing direction for OP here: 22 hours ago, hanhphuc said: can try many useful library here: Attribute functions any advice is appreciated BTW, you are using Bcad too? nice but seems lack of ET , eg: ATTOUT ATTIN NCOPY etc.. just name few. if you do, any suggestions or rewrite sub ? c:ATTT about prompt blockname, the better idea first pick en (assoc 2 enlst ), input index because OP has too many blocks! (39 . "ID") p/s: another, for nth 3 5 6 etc.. perhaps sorting can be optimized by parsing number Quote Link to comment Share on other sites More sharing options...
BIGAL Posted April 18, 2020 Share Posted April 18, 2020 Yes have Briscad V20 another without stealing post is polygon done differently. a bit of a gotcha. Quote Link to comment Share on other sites More sharing options...
zams23 Posted April 19, 2020 Author Share Posted April 19, 2020 On 4/17/2020 at 7:51 PM, hanhphuc said: i just notice Bricscad does not have Express Tool?! no ATTOUT ? my attempt is not perfect, unlike ET can select all, i just filter block name selection, i.e: much easier all same tags output keep the output txt format same as ET does. ;; ATT:SORT - for Bricscad user ;; ;; <> : sort - '<' & '>' sign or mode ;; < is ascending/incremental (A-Z) ;; > is descending/decremental (Z-A) ;; i : sorting nth index , 4 is not used because block name all the same default 3 ;; (X Y Z HANDLE BLKNAME TAGNAME TAG1 TAG2 TAGx ) ;; (0 1 2 3 4 5 6 7 x ) ;; note: sorting may not work as expected other than 0 1 2 (XYZ) ;; bn : block name (string) ;; example : ;; (att:sort "ID" 3 < ) ; Blockname="ID" ,3=HANDLE , < =ascending/increment A-Z ;; (att:sort "BKL" 1 > ) ; Blockname="BKL" ,1=Y coordinate, > =descending/decrement Z-A ;; output: ;; returns list of attributes string ATTOUT format ;; (("HANDLE\tBLOCKNAME\tTAGNAME\tTAG1\tTAG2\t etc...") ("HANDLE\tBLOCKNAME\tTAGNAME\tTAG1\tTAG2\t etc.. " ) ) (vl-load-com) (defun att:sort ( bn i <> / ss ass tags l) ;hanhphuc 17.04.2020 (if (setq i (cond ((= i 4) 3)(i)) ; nth 4 is unused ss (ssget ":L" (list '(0 . "INSERT") (cons 2 bn ) '(66 . 1)))) (progn (vlax-for obj (setq ass (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-get-acad-object) ) ) ) (setq l (cons (append (vlax-get obj 'InsertionPoint) (list (vla-get-Handle obj)) (list (vla-get-name obj)) (mapcar '(lambda (x) (LM:vl-getattributevalue obj x)) (setq tags (mapcar 'vla-get-tagstring (vlax-invoke obj 'getattributes) ) ) ) ) l ) ) ) (vlax-release-object ass) (cons (apply 'strcat (vl-list* "HANDLE" "\tBLOCKNAME" (mapcar '(lambda (x) (strcat "\t" x)) tags) ) ) (mapcar '(lambda (x) (setq x (cdddr x)) (apply 'strcat (cons (strcat "'" (car x)) (mapcar '(lambda (x) (strcat "\t" x)) (cdr x)) ) ) ) (vl-sort l '(lambda (a b) (<> (nth i a) (nth i b)))) ) ) ) ) ) ;; Get Attribute Values - Lee Mac ;; Returns an association list of attributes present in the supplied block. ;; blk - [ent] Block (Insert) Entity Name ;; Returns: [lst] Association list of ((<tag> . <value>) ... ) (defun LM:vl-getattributevalue ( blk tag ) (setq tag (strcase tag)) (vl-some '(lambda ( att ) (if (= tag (strcase (vla-get-tagstring att))) (vla-get-textstring att))) (vlax-invoke blk 'getattributes)) ) ok not AcTable object , much easier please read the header of routine of att:sort routine you can customize your sorting parameters, simply edit index (0 1 2 3 ...) or (< >) sign check in the example codes in C:ATTT, commented in side the code (att:sort bn 1 > ) ;;; here to adjust, (1) indicates sorting Y-coordinates, (>) Z-A (att:sort bn 0 < ) ;;; (0) indicates X-coordinates, (<) increment , but you need to rotate 90d to test (att:sort bn 5 < ) ;;This (5) indicates sorting TAGName , (4)=not in use BlockName all same, you can try 3,5,6 etc.. but can't promise example: Please test in your drawing command : ATTT Index for block name ? : 39 ;;key in index 39 is for your block name "ID" (defun c:attt (/ ss l ls f fn bn b) ;; put your error handle here (foreach x (reverse ((lambda (i / l) (while (setq b (tblnext "BLOCK" (not b))) (setq ls (cons (cons (setq i (1+ i)) (cdr (assoc 2 b)) ) ls ) ) ) ) -1 ) ) (terpri) (princ x) ) (textscr) (initget 5) (if (and (setq i (getint "\nIndex for block name? : ")) (< i (length ls)) (setq bn (cdr (assoc i ls))) (setq l (att:sort bn 1 >)) ;;; here to adjust, (1) indicates sorting Y-coordinates, (>) Z-A (setq fn (vl-filename-mktemp "att-" nil ".txt" ) ) (setq f (open fn "w")) ) (progn (foreach x l (write-line x f) ) (if f (close f) ) (vl-cmdf "_START" (strcat "EXCEL " fn)) ) (princ "\nInvalid block selections!") ) (princ) ) please test if work or error, i didn't test all its not working,.. Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted April 19, 2020 Share Posted April 19, 2020 (edited) 31 minutes ago, zams23 said: its not working,.. the snippet you quoted was sub function/library att:sort LM:vl-getattributevalue must be loaded before you load another LISP defun c:ATTT please take note only can select single table each time you invoke command : ATTT Index for block name? : 39 Select entities: <select only single table not both !!> Edited April 19, 2020 by hanhphuc Quote Link to comment Share on other sites More sharing options...
zams23 Posted July 3, 2020 Author Share Posted July 3, 2020 i try this, but the commad said error... Quote Link to comment Share on other sites More sharing options...
hanhphuc Posted July 3, 2020 Share Posted July 3, 2020 8 hours ago, zams23 said: i try this, but the commad said error... didn't you read my previous comment?? On 4/19/2020 at 7:48 PM, hanhphuc said: the snippet you quoted was sub function/library att:sort LM:vl-getattributevalue ↑↑↑ must be loaded before you load another LISP defun c:ATTT to copy the sub routine, click -> here <-- then paste in same ATTT.lsp file, reload & run command ATTT Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.