Hi,
Does anyone know how to quick select all the blocks from a specific layer (for instance XPTO) and export them along with their attributes, exactly as we do by quick selecting them and then, through AutoCAD Express -> Attribute Export Info, but in a script...
Thanks in advance.
Solved! Go to Solution.
Change selection filter to your suit:
{code}
;;==================================== ATO.LSP========================================;; ;; Attribute export to data file ;; fixo () 2012 * all rights released ;;local defun (defun lst-str (lst del / st strout) ;;; by Fatty T.O.H. 2004 (setq strout (car lst)) (foreach st (cdr lst) (setq strout (strcat strout del st)) ) strout ) (defun C:ATO(/ att_line data datafile data_line dirty en filename header header_lines i new_line obj records sset stab txtline) (if (setq sset (ssget (list (cons 0 "INSERT") (cons 66 1) (cons 410 (getvar "CTAB"))))) (progn (setq data nil) (setq filename (getfiled "Enter output filename:" (getvar "dwgprefix") "csv" ; <--- change file extension to suit (may be txt, dat etc...) 1)) (setq datafile (open filename "W")) (while (setq en (ssname sset 0)) (setq obj (vlax-ename->vla-object en)) (setq txtline nil att_line nil) (setq header_lines (append header_lines (list (strcat "'" (vla-get-handle obj) "\t" (vla-get-effectivename obj))))) (foreach att (append (vlax-invoke obj 'getattributes) (cond ((vl-catch-all-error-p (setq stab (vlax-invoke obj 'getconstantattributes)))) (stab)) ) (if (not (member (vla-get-tagstring att) dirty)) (setq dirty (cons (vla-get-tagstring att) dirty))) (setq att_line (cons (cons (vla-get-tagString att) (vla-get-textString att)) att_line))) (setq txtline (append (reverse att_line) txtline)) (setq data (cons txtline data)) (ssdel en sset) ) (setq data (reverse data)) (setq records nil) (foreach record data (setq new_line nil) (foreach tag dirty (setq new_line (cons (if (assoc tag record) (assoc tag record) (cons tag "<>")) new_line)) ) (setq records (append records (list (mapcar 'cdr (reverse new_line))))) ) (setq data_line "Handle\tBlockName") (foreach tag dirty (setq data_line (strcat data_line (strcat "\t" tag))) ) (write-line data_line datafile) (setq i 0) (while (setq header (nth i header_lines)) (setq data_line (strcat (strcat header "\t") (lst-str (nth i records) "\t"))) (write-line data_line datafile) (setq i (1+ i)) ) (close datafile) ) ) (princ (strcat "\n\t --- Output file: " "\"" filename"\"" " created. ---")) (princ) ) (princ "\n\t --- Start command with \"ATO\" ---") (princ) (or(vl-load-com) (princ)) ;;==================================== code end ========================================;;
{code}
~'J'~
I'm afraid that it doesn't work...
Never the less, here is my LISP file:
(defun C:exta02 (/ss ) (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 8 "LAYER_BLOCK") ))) (bns_attout "block.txt" ss) )
And it returns the error:
; error: An error has occurred inside the *error* functionAutoCAD variable
setting rejected: "osmode" nil
I've also tried the following code but still the same error
(defun C:exta02 (/ss filename) (setq ss (ssget "X" (list (cons 0 "INSERT") (cons 8 "LAYER_BLOCK") ))) (setq filename (getfiled "Enter output filename:" (getvar "dwgprefix") "txt" 1) ) (bns_attout filename ss) )
It does work, however it asks me to select the objects...
As I mentioned, I need it to select them for me, to be precise blocks named "BLOCK_A" inside layer "LAYER_BLOCK".
With soma changes...
(defun C:exta0 (/ ss filename)
(setq ss (ssget "X"
(list (cons 0 "INSERT")
(cons 8 "LAYER_BLOCK")
(cons 2 "BLOCK_A")
)
)
)
(setq filename (getfiled "Enter output filename:"
(getvar "dwgprefix")
"txt"
1
)
)
(bns_attout filename ss)
)
will do the trick
henrique
My mistake
(code)
(defun C:exta02 (/ ss filename)
(load "attout")
(setq ss (ssget "X"
(list (cons 0 "INSERT")
(cons 8 "LAYER_BLOCK")
(cons 2 "BLOCK_A")
)
)
)
(setq filename (getfiled "Enter output filename:"
(getvar "dwgprefix")
"txt"
1
)
)
(bns_attout filename ss)
)
(code)
henrique
Somehow it might work...
I say this because although I entered a tst01.txt name for file at Desktop folder, when it comes to open the file I just can't find it.
Anyway, I picked your code
(setq ss (ssget "X" (list (cons 0 "INSERT") (cons 8 "LAYER_BLOCK") (cons 2 "BLOCK_A") ) )
and inserted it at Hallex 'ato.lsp' and now it works like a charm as follows:
;;==================================== ATO.LSP========================================;; ;; Attribute export to data file ;; fixo () 2012 * all rights released ;;local defun (defun lst-str (lst del / st strout) ;;; by Fatty T.O.H. 2004 (setq strout (car lst)) (foreach st (cdr lst) (setq strout (strcat strout del st)) ) strout ) (defun C:ato(/ att_line data datafile data_line dirty en filename header header_lines i new_line obj records sset stab txtline) (if (setq sset (ssget "X" (list (cons 0 "INSERT") (cons 8 "LAYER_BLOCK") (cons 2 "BLOCK_A") ) )) (progn (setq data nil) (setq filename (getfiled "Enter output filename:" (getvar "dwgprefix") "txt" ; <--- change file extension to suit (may be txt, dat etc...) 1)) (setq datafile (open filename "W")) (while (setq en (ssname sset 0)) (setq obj (vlax-ename->vla-object en)) (setq txtline nil att_line nil) (setq header_lines (append header_lines (list (strcat "'" (vla-get-handle obj) "\t" (vla-get-effectivename obj))))) (foreach att (append (vlax-invoke obj 'getattributes) (cond ((vl-catch-all-error-p (setq stab (vlax-invoke obj 'getconstantattributes)))) (stab)) ) (if (not (member (vla-get-tagstring att) dirty)) (setq dirty (cons (vla-get-tagstring att) dirty))) (setq att_line (cons (cons (vla-get-tagString att) (vla-get-textString att)) att_line))) (setq txtline (append (reverse att_line) txtline)) (setq data (cons txtline data)) (ssdel en sset) ) (setq data (reverse data)) (setq records nil) (foreach record data (setq new_line nil) (foreach tag dirty (setq new_line (cons (if (assoc tag record) (assoc tag record) (cons tag "<>")) new_line)) ) (setq records (append records (list (mapcar 'cdr (reverse new_line))))) ) (setq data_line "Handle\tBlockName") (foreach tag dirty (setq data_line (strcat data_line (strcat "\t" tag))) ) (write-line data_line datafile) (setq i 0) (while (setq header (nth i header_lines)) (setq data_line (strcat (strcat header "\t") (lst-str (nth i records) "\t"))) (write-line data_line datafile) (setq i (1+ i)) ) (close datafile) ) ) (princ (strcat "\n\t --- Output file: " "\"" filename"\"" " created. ---")) (princ) ) (princ "\n\t --- Start command with \"ATO\" ---") (princ) (or(vl-load-com) (princ)) ;;==================================== code end ========================================;;
However if there is a simple solution for this I'll be glad to test it.
For me works...
(code)
(defun C:exta02 (/ ss filename)
(load "attout")
(setq ss (ssget "X"
(list (cons 0 "INSERT")
(cons 8 "LAYER_BLOCK")
(cons 2 "BLOCK_A")
)
)
)
(setq filename (getfiled "Enter output filename:"
(getvar "dwgprefix")
"txt"
1
)
)
(bns_attout filename ss)
)
(end code)
the file was created successfully with both codes...
I picked up Hallex code to try something out, and I've just realized that the attributes are coming out in the wrong order.
Any ideas?
Is it possible to modify this LISP routine to just simply "select" all attributes in a drawing with the same name? But not export?
I'm looking to streamline the "QSELECT" command. I'd like to select all "DOORTAGS" blocks in one page to move them around as a group.
Any thoughts?
a.Z.
Untested...
(defun c:selblksbytag ( / tag ss i stab bl ) (vl-load-com) (initget 1) (setq tag (getstring t "\nSpecify TAG (case sensitive) : ")) (setq ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (if (= (getvar 'cvport) 1) (cons 410 (getvar 'ctab)) (cons 410 "Model"))))) (repeat (setq i (sslength ss)) (if (not (vlax-property-available-p (setq obj (vlax-ename->vla-object (ssname ss (setq i (1- i))))) 'Path)) (foreach att (append (vlax-invoke obj 'getattributes) (cond ( (vl-catch-all-error-p (setq stab (vlax-invoke obj 'getconstantattributes))) ) (stab) )) (if (= (vla-get-tagstring att) tag) (setq bl (cons (vlax-vla-object->ename obj) bl)) ) ) ) ) (setq ss (ssadd)) (foreach b bl (ssadd b ss) ) (sssetfirst nil ss) (princ) )
Is there a way to create a lisp routine that would run the following:
1. QSELECT
2. Select "Block Reference" by default.
3. Select "Name" by dafault for the Properties
Then all I'd have to do is select the block name and be off and running?
Look I had forgot ab obj variable for localizing and TAG specification is always uppercase... That's why it failed... Try now...
(defun c:selblksbytag ( / tag ss i obj stab bl ) (vl-load-com) (initget 1) (setq tag (getstring t "\nSpecify TAG : ")) (setq ss (ssget "_X" (list '(0 . "INSERT") '(66 . 1) (if (= (getvar 'cvport) 1) (cons 410 (getvar 'ctab)) (cons 410 "Model"))))) (repeat (setq i (sslength ss)) (if (not (vlax-property-available-p (setq obj (vlax-ename->vla-object (ssname ss (setq i (1- i))))) 'Path)) (foreach att (append (vlax-invoke obj 'getattributes) (cond ( (vl-catch-all-error-p (setq stab (vlax-invoke obj 'getconstantattributes))) ) (stab) )) (if (= (vla-get-tagstring att) (strcase tag)) (setq bl (cons (vlax-vla-object->ename obj) bl)) ) ) ) ) (setq ss (ssadd)) (foreach b bl (ssadd b ss) ) (sssetfirst nil ss) (princ) )
The name is Marko, not Mark...