Jump to content

EXPORT ATTRIBUTE


zams23

Recommended Posts

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 :
image.thumb.png.e3fbefb00bc3b30c33b827f0d086644e.png

image.png.ac9f5ca3412ebb2f1cc116060d7e5ddd.png
I want the order to remain the same

Link to comment
Share on other sites

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 :
image.thumb.png.e3fbefb00bc3b30c33b827f0d086644e.png

image.png.ac9f5ca3412ebb2f1cc116060d7e5ddd.png
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) 

 

 

Link to comment
Share on other sites

thanks for your help, However, this method is not always accurate, because some rows handles are not ordered from (A-Z). like this attribute:

image.png.280bfefb859a81d5e8c29a2b2d04d0c4.png

image.png.4eb026c220dff98418086d934b9b226e.png

and the result use sort by handle rows like this :

image.png.3922b72ef9aec5b92fdfac2b2d11f2d1.png

Link to comment
Share on other sites

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:

image.png.280bfefb859a81d5e8c29a2b2d04d0c4.png

 

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?

 

 

 

Link to comment
Share on other sites

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 by BIGAL
Link to comment
Share on other sites

 

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 

 

 

 

 

 

Link to comment
Share on other sites

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 by StevJ
  • Thanks 1
Link to comment
Share on other sites

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)

 

  • Thanks 1
Link to comment
Share on other sites

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

 

 

 

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

 

attt.gif

Edited by hanhphuc
Link to comment
Share on other sites

  • 2 months later...
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

 

 

 

 

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