svorgodne Posted February 2, 2011 Share Posted February 2, 2011 I have certain blocks I need to extract attributes from several times so I can compare the results. So it would be very much desirable somebody to help me with an autolisp routine that can ask for the attributes from blocks starting with a "wildcard" and extracting the information to excel files with sequential name Thanks in advance S Quote Link to comment Share on other sites More sharing options...
migs Posted February 2, 2011 Share Posted February 2, 2011 If you have the Express Tools installed there is an ATTOUT which extracts attributes from blocks, not sure if this would be of use to you Quote Link to comment Share on other sites More sharing options...
SOliver Posted February 4, 2011 Share Posted February 4, 2011 The following code should help get you started (vl-load-com) (defun c:ccc( / blockFound block blockRecord atts getAtts name validCollection attList i) (while (= blockFound nil) (setq block (entsel "\nSelect an instance of an attibute block:")) (if(= block nil) (princ "\nNo entity selected") (progn (setq block(vlax-ename->vla-object(car block))) (if(eq (vlax-get-property block 'objectName) "AcDbBlockReference") (if(= (vla-get-hasattributes block) :vlax-true) (setq blockFound t) (princ "\nSelected block contains no attributes") ) (princ "\nSelected entity is not a block reference") ) ) ) ) (setq blockRecord (getBlockTableRecord (vlax-get-property block 'Name))) (setq atts (getAttNames blockRecord)) (listAttributes (vlax-get-property blockRecord 'Name) atts) (while(= validCollection nil) (setq name (getstring "\nEnter attribute name to add to collection or leave blank to proceed: ")) (cond ((eq name "") (if(/= getAtts nil) (setq validCollection t) (princ "\nAt least one attribute must be added to the collection list:") ) ) ((isInList atts name) (if(= (isInList getAtts name) nil) (setq getAtts(append getAtts(list name))) (princ "\nAttribute is already in the collection list") ) ) ( (princ "\nInvalid attribute name added") ) ) ) (setq sset (ssget "X" (list (cons 0 "INSERT")(cons 2 (vlax-get-property blockRecord 'Name))))) (setq i -1) (while (<(setq i (1+ i))(sslength sset)) (setq attList (append attList (list (getAttValues (vlax-ename->vla-object(ssname sset i)) getAtts)))) ) (princ attList) ) (defun getBlockTableRecord (name / bl c) (vlax-for c (vla-get-blocks(vla-get-activedocument(vlax-get-acad-object))) (if(eq (vla-get-name c) name) (setq bl c) ) ) bl ) (defun getAttNames (blockRecord / c names ) (vlax-for c blockRecord (if(eq (vlax-get-property c 'objectName) "AcDbAttributeDefinition") (setq names (append names(list (vlax-get-property c 'tagString)))) ) ) names ) (defun getAttValues ( ent atts / i return attList) (setq attList (vlax-safearray->list(vlax-variant-value(vla-getattributes ent)))) (foreach c atts (setq i -1) (while (< (setq i (1+ i)) (length attList)) (if(eq (strcase (vla-get-tagString (nth i attList)))(strcase c)) (setq return (append return (list (vla-get-textString (nth i attList))))) ) ) ) return ) (defun listAttributes (blockName atts / c) (princ (strcat "\nBlock name: " blockName)) (princ "\nAttributes:") (foreach c atts (princ (strcat "\n " c)) ) ) (defun isInList (lst item / i return) (setq i -1) (while (<(setq i (1+ i))(length lst)) (if(eq (strcase (nth i lst))(strcase item)) (setq i (length lst) return t) ) ) return ) This will prompt you to select an instance of a block, assuming it contains attributes it will then proceed to ask you to enter one or more attribute names which you would wish to collect values from. The end result so far is a list of lists containing attribute values stored in the order of which they were requested. Where you go from here is up to you Hope this helps, SOliver. Quote Link to comment Share on other sites More sharing options...
SOliver Posted February 5, 2011 Share Posted February 5, 2011 Right had a play about with excel earlier in the day. _$ (vl-load-com) (defun c:ccc( / blockFound block blockRecord atts getAtts name validCollection attList i) (while (= blockFound nil) (setq block (entsel "\nSelect an instance of an attibute block:")) (if(= block nil) (princ "\nNo entity selected") (progn (setq block(vlax-ename->vla-object(car block))) (if(eq (vlax-get-property block 'objectName) "AcDbBlockReference") (if(= (vla-get-hasattributes block) :vlax-true) (setq blockFound t) (princ "\nSelected block contains no attributes") ) (princ "\nSelected entity is not a block reference") ) ) ) ) (setq blockRecord (getBlockTableRecord (vlax-get-property block 'Name))) (setq atts (getAttNames blockRecord)) (listAttributes (vlax-get-property blockRecord 'Name) atts) (while(= validCollection nil) (setq name (getstring "\nEnter attribute name to add to collection or leave blank to proceed: ")) (cond ((eq name "") (if(/= getAtts nil) (setq validCollection t) (princ "\nAt least one attribute must be added to the collection list:") ) ) ((isInList atts name) (if(= (isInList getAtts name) nil) (setq getAtts(append getAtts(list name))) (princ "\nAttribute is already in the collection list") ) ) ( (princ "\nInvalid attribute name added") ) ) ) (setq sset (ssget "X" (list (cons 0 "INSERT")(cons 2 (vlax-get-property blockRecord 'Name))))) (setq i -1) (while (<(setq i (1+ i))(sslength sset)) (setq attList (append attList (list (getAttValues (vlax-ename->vla-object(ssname sset i)) getAtts)))) ) (toExcel atts attList) ) (defun getBlockTableRecord (name / bl c) (vlax-for c (vla-get-blocks(vla-get-activedocument(vlax-get-acad-object))) (if(eq (vla-get-name c) name) (setq bl c) ) ) bl ) (defun getAttNames (blockRecord / c names ) (vlax-for c blockRecord (if(eq (vlax-get-property c 'objectName) "AcDbAttributeDefinition") (setq names (append names(list (vlax-get-property c 'tagString)))) ) ) names ) (defun getAttValues ( ent atts / i return attList) (setq attList (vlax-safearray->list(vlax-variant-value(vla-getattributes ent)))) (foreach c atts (setq i -1) (while (< (setq i (1+ i)) (length attList)) (if(eq (strcase (vla-get-tagString (nth i attList)))(strcase c)) (setq return (append return (list (vla-get-textString (nth i attList))))) ) ) ) return ) (defun listAttributes (blockName atts / c) (princ (strcat "\nBlock name: " blockName)) (princ "\nAttributes:") (foreach c atts (princ (strcat "\n " c)) ) ) (defun isInList (lst item / i return) (setq i -1) (while (<(setq i (1+ i))(length lst)) (if(eq (strcase (nth i lst))(strcase item)) (setq i (length lst) return t) ) ) return ) (defun toExcel(headers values / ) (setq excel (vlax-get-or-create-object "Excel.Application")) (setq wbook (vla-add (vlax-get-property excel 'workbooks))) (setq wsheet (vlax-get-property wbook 'activesheet)) (setq cells (vlax-get-property wsheet 'cells)) (setq y 0) (while (< (setq y(1+ y)) (+ 2(length values))) (setq x 0) (while (<(setq x(1+ x))(1+(length headers))) (if(= y 1) (vlax-put-property cells 'item y x (nth (1- x) headers)) (vlax-put-property cells 'item y x (nth (1- x)(nth (- y 2) values))) ) ) ) (vlax-put-property excel 'visible 1) (vlax-release-object cells) (vlax-release-object wsheet) (vlax-release-object wbook) (vlax-release-object excel) ) (defun getColumnLetter(index / return) (if(< index 27 ) (chr (+ index 64)) (strcat (chr(+ 64(/ (- index (rem index 26)) 26)))(chr(+ 64(rem index 26)))) ) ) Same as before but this time an excel spreadsheet is created with the contents of the list generated from the attribute block references. SOliver. 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.