kam1967 Posted January 24, 2011 Share Posted January 24, 2011 Hi guys, I'm not sure if you have done this before. I tried to search, but it does not appear that anyone's run into this trouble before. I am trying to use the titleblock information with tags TITLE-1 through TITLE-4 to fill out the drawing property on the Summary tab, starting from the Title, Subject, Author, Keywords matching with TITLE-1, TITLE-2, TITLE-3 and TITLE-4 respectively. See attached. Is it possible to get that done here? Thanks in advance. Quote Link to comment Share on other sites More sharing options...
eyde Posted January 24, 2011 Share Posted January 24, 2011 You need to be in your custom tab not summary. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 24, 2011 Share Posted January 24, 2011 Look into the SummaryInfo property of the ActiveDocument Object. Quote Link to comment Share on other sites More sharing options...
eyde Posted January 24, 2011 Share Posted January 24, 2011 I took the question as asking about title block info not search info. Did I read the question wrong? Quote Link to comment Share on other sites More sharing options...
kam1967 Posted January 25, 2011 Author Share Posted January 25, 2011 Thanks, Lee. Although, I'm not sure if I made myself clear. I was inquiring to see if anyone has a routine to extract and populate the Dwgprops dialogue with the Titleblock info with the following attribute tags: TITLE-1, TITLE-2, TITLE-3 and TITLE-4. So assuming that there is a block called TITLEBLOCK which contains the TITLE1-4 attributes. I'd like to be able to transfer that information directly into the drawing property as shown in the jpeg. Hope I made myself clear this time. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 25, 2011 Share Posted January 25, 2011 Thanks, Lee. Although, I'm not sure if I made myself clear. I was inquiring to see if anyone has a routine to extract and populate the Dwgprops dialogue with the Titleblock info with the following attribute tags: TITLE-1, TITLE-2, TITLE-3 and TITLE-4. So assuming that there is a block called TITLEBLOCK which contains the TITLE1-4 attributes. I'd like to be able to transfer that information directly into the drawing property as shown in the jpeg. Hope I made myself clear this time. I understood, and it is the SummaryInfo object you need to be querying. For example - populate your drawing properties, then run this code to display the properties and methods of the SummaryInfo Object: (vlax-dump-object (vla-get-SummaryInfo (vla-get-ActiveDocument (vlax-get-acad-object) ) ) t ) Quote Link to comment Share on other sites More sharing options...
kam1967 Posted January 25, 2011 Author Share Posted January 25, 2011 (edited) Ah, I ran it and got Autocad to list those drawing properties. Thanks, Lee. So is there a way that I could update the information in the summaryInfo from the titleblock attributes through lisp? How could I assign variables in the summaryinfo to match with the attributes found in the titleblock itself? Any help would be greatly appreciated. ; Title = "TITLE-1" ; Subject = "TITLE-2" ; Author = "TITLE-3" ; Keywords = "TITLE-4" This is a lisp that I need to modify to make it work, however, I'm not sure how to ask it to take these attribute values from TITLEBLOCKA and update the dwgprops summary tab this way. ;;;initialize DWGPROPS if it does not exist ;;;this is stripped down, you can add more to it, if you wish (defun dp:init () (if (and (zerop (getvar "DWGTITLED")) (not (dp:get))) (progn (setq ;dp:Title (val 2)<-could be extracted from Title block via LISP ;dp:Subject (val 3) dp:Author "Your Organization" ;dp:Keywords (val 7) dp:RevisionNo "0" dp:Cust0 (val 300)<-1st Custom Property dp:Cust1 (val 301)<-2nd Custom Property ; ) (dput) (setvar "CMDECHO" 0) (command "_.QSAVE") (setvar "CMDECHO" 1) ) ) (princ) );dp:init (dp:init) Edited January 18, 2018 by SLW210 Added Code Tags Quote Link to comment Share on other sites More sharing options...
pBe Posted January 25, 2011 Share Posted January 25, 2011 How could I assign variables in the summaryinfo to match with the attributes found in the titleblock itself? Any help would be greatly appreciated. ; Title = "TITLE-1" ; Subject = "TITLE-2" ; Author = "TITLE-3" ; Keywords = "TITLE-4" Try this (defun c:GrabTBValue (/ dwg sum ths_blk cnt func strVal) (defun Tag_value (tagname / lay_t attr tag ) (vlax-for lay_t (vla-get-layouts dwg) (vlax-for p (vla-get-block lay_t) (if (and (= (vla-get-objectname p) "AcDbBlockReference") (= (strcase (vla-get-effectivename p)) (strcase ths_blk))) (if (and (= (vla-get-hasattributes p) :vlax-true) (safearray-value (setq attr (vlax-variant-value (vla-getattributes p) ) ) ) ) (foreach tag (vlax-safearray->list attr) (if (= (strcase tagname) (strcase (vla-get-tagstring tag))) (setq strVal (vla-get-TextString tag)) )) ) ) ) ) ) (setq dwg (vla-get-activedocument (vlax-get-acad-object)) sum ( vla-get-SummaryInfo dwg) ths_blk [color=blue]"TITLEBLOCKA"[/color] cnt 0) [color=blue];<---your blockname[/color] (foreach b '("title" "subject" "author" "keywords") (setq func (eval (read (strcat "vla-put-" b)))) (Tag_value (strcat "TITLE-" (itoa (setq cnt (1+ cnt))))) (func sum strVal) ) ) Quote Link to comment Share on other sites More sharing options...
kam1967 Posted January 25, 2011 Author Share Posted January 25, 2011 Awesome, pBe. You're a savior! I will need to see if I can understand your routine later. It looks really concise and clean. Thanks again! Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 25, 2011 Share Posted January 25, 2011 I might approach it this way: (defun c:UpdateSummaryInfo ( / sum tags ss ) (vl-load-com) ;; © Lee Mac 2011 (setq sum (vla-get-SummaryInfo (vla-get-ActiveDocument (vlax-get-acad-object)) ) ) (setq tags '( ("TITLE-1" . title) ("TITLE-2" . subject) ("TITLE-3" . author) ("TITLE-4" . keywords) ) ) (if (setq ss (ssget "_X" '((0 . "INSERT") (66 . 1) (2 . "TITLEBLOCK")))) (mapcar (function (lambda ( attrib / prop ) (if (setq prop (cdr (assoc (strcase (vla-get-TagString attrib)) tags))) (vlax-put-property sum prop (vla-get-TextString attrib)) ) ) ) (vlax-invoke (vlax-ename->vla-object (ssname ss 0)) 'GetAttributes) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 25, 2011 Share Posted January 25, 2011 pBe, Just offering my opinion, ignore it if you like: The algorithm that your code implements is extremely inefficient (and I cannot stress that enough) - let me explain why: For every property, your code iterates through, not only every block in the drawing, but every object in the drawing. Hence you are iterating through every single object in the drawing, four times over. Furthermore, you are also iterating through all the attributes for every attributed block with the name specified in the drawing - also four times over. Notice in my approach, I only iterate through the attributes of a single attributed block once. The key point I make and the most effective way to increase efficiency in a program is to greatly minimise the number of times the program iterates through information (once if possible). Lee Quote Link to comment Share on other sites More sharing options...
kam1967 Posted January 25, 2011 Author Share Posted January 25, 2011 Yes, yours worked like a charm, Lee. But I want to thank you, pBe and Lee, for providing such a great routine. Yes, not everyone is as efficient a programming as you, Lee. But we can only learn and develop our programming skills with advice and support from people such as Lee and some others here at the forum. Thanks again. Quote Link to comment Share on other sites More sharing options...
pBe Posted January 26, 2011 Share Posted January 26, 2011 pBe, Just offering my opinion, ignore it if you like: The algorithm that your code implements is extremely inefficient (and I cannot stress that enough) I always value your opinion Lee . how else would i learn. looking at the code again you're exactly right 4 (four) (1+1+1+1 )(IV) times, a call to sub for every tagname, a search for the block for every call. Thank yiou very much Lee. Awesome, pBe. You're a savior! I will need to see if I can understand your routine later. It looks really concise and clean. You're welocme kam1967 So much for concise and clean though but thanks noetheless (well, back to the drawing board) Quote Link to comment Share on other sites More sharing options...
pBe Posted January 26, 2011 Share Posted January 26, 2011 (edited) pBe, For every property, your code iterates through, not only every block in the drawing, but every object in the drawing. Hence you are iterating through every single object in the drawing, four times over. I thought this had taken care of that...? (vla-get-block lay_t) EDIT: you are right!!!!! , i never realized that line will go through all objects.. OMG The reason for this is I dont know how to handle blocks wtih anonymous names [*U12*] and retrieve the effective name via ssget filter. is there a way to do that other than searching the block table (teach.. teach...) Furthermore, you are also iterating through all the attributes for every attributed block with the name specified in the drawing - also four times over. Lee what about this... (defun c:GrabTBValue (/ dwg sum ths_blk objcts cnt tg_nm) (while (< cnt 4) (setq dwg (vla-get-activedocument (vlax-get-acad-object)) sum ( vla-get-SummaryInfo dwg) ths_blk "TITLEBLOCKA" CNT 0) ;<---your blockname (if (setq objcts (ssget "_X" '((0 . "INSERT")(66 . 1)))) (vlax-for p (vla-get-activeselectionset dwg) (if (and (= (vla-get-objectname p) "AcDbBlockReference") (= (strcase (vla-get-effectivename p)) (strcase ths_blk))) (if (and (= (vla-get-hasattributes p) :vlax-true) (safearray-value (setq attr (vlax-variant-value (vla-getattributes p))))) (foreach tag (vlax-safearray->list attr) (setq tg_nm (strcase (vla-get-tagstring tag))) (cond ((= tg_nm "TITLE-1") (vla-put-title sum (vla-get-TextString tag)) (setq cnt (1+ cnt)) ) ((= tg_nm "TITLE-2") (vla-put-subject sum (vla-get-TextString tag)) (setq cnt (1+ cnt)) ) ((= tg_nm "TITLE-3") (vla-put-author sum (vla-get-TextString tag)) (setq cnt (1+ cnt)) ) ((= tg_nm "TITLE-4") (vla-put-keywords sum (vla-get-TextString tag)) (setq cnt (1+ cnt)) ) ) ) ) ) ) ) )(princ) ) Notice the while statement ( I'm hoping that will stop the routine vlax/foreach/cond all together when the statement is true.. Is that a correct assumption? with humility Edited January 26, 2011 by pBe Quote Link to comment Share on other sites More sharing options...
CADkitt Posted January 26, 2011 Share Posted January 26, 2011 I like it how the file properties are used but this system doesn't work when you use multiple layouts. Or does any one know a work around? Quote Link to comment Share on other sites More sharing options...
pBe Posted January 26, 2011 Share Posted January 26, 2011 You mean more than 1 block source? you can use custom properties up to 20 items (defun c:test () (setq dwg (vla-get-activedocument (vlax-get-acad-object)) sum ( vla-get-SummaryInfo dwg)) (vla-AddCustomInfo sum "Sheet no" "Title of Sheet") ) Quote Link to comment Share on other sites More sharing options...
CADkitt Posted January 26, 2011 Share Posted January 26, 2011 At my job 20 isn't enough. My real problem is I think we should go to a 1 layout per drawing system this would fix a lot of issues also a lot performance issues, but I am the only one that want this. So I am now hammering into them that the drawing is so slow because it has 30 layouts. But since using 1 layout will disrupts there workflow (even if it is temporary) it is not gonna change for a while. I guess it is the same reason why where on Autocad and not Inventor. Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 26, 2011 Share Posted January 26, 2011 The reason for this is I dont know how to handle blocks wtih anonymous names [*U12*] and retrieve the effective name via ssget filter. is there a way to do that other than searching the block table (teach.. teach...) A difficult one, two essential ways to approach it: 1) (My preferred choice) Filter for the block name AND all anonymous blocks: (ssget "_X" '((0 . "INSERT") (2 . "`*U*,TITLEBLOCK") (66 . 1))) Then use a conditional when iterating through the set to check the EffectiveName before operating on the block. 2) Use the Block Refs of the Block Definition Record: ;; Returns list of the Anonymous names taken by a Dynamic Block (if any) - Lee Mac 2011 - www.lee-mac.com ;; Arguments: block - name of Dynamic Block. (defun AnonymousInstancesof ( block / def rec nme ref lst ) (while (setq def (tblnext "BLOCK" (null def))) (if (= 1 (logand 1 (cdr (assoc 70 def)))) (progn (setq rec (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" (setq nme (cdr (assoc 2 def)))) ) ) ) ) ) (while (setq ref (assoc 331 rec)) (if (and (eq block (vla-get-effectivename (vlax-ename->vla-object (cdr ref)))) (not (member nme lst)) ) (setq lst (cons nme lst)) ) (setq rec (cdr (member (assoc 331 rec) rec))) ) ) ) ) (reverse lst) ) Then use something like (similar to here): (defun LM:BlockList->Str ( lst del / f ) ;; © Lee Mac 2011 (defun f ( s ) (if (wcmatch s "`**") (strcat "`" s) s)) (if (cdr lst) (strcat (f (car lst)) del (LM:BlockList->Str (cdr lst) del)) (f (car lst)) ) ) To create the ssget filter: (ssget "_X" (list (cons 0 "INSERT") (cons 2 (LM:BlockList->Str (cons "TITLEBLOCK" (AnonymousInstancesof "TITLEBLOCK")) ",")) (cons 66 1) ) ) But its really 6 of one, half a dozen of the other... in the first method we are iterating through all anonymous block references in the drawing and choosing those we like; in the second we iterate through the anonymous block definitions (instead of references) and choose those we like... Notice the while statement (I'm hoping that will stop the routine vlax/foreach/cond all together when the statement is true.. Is that a correct assumption? Not quite, the While is redundant since the test condition will not be evaluated until the entire selection set is iterated, by which point the attributes are likely found already, and if they aren't the code will run needlessly another 3 times... But still you're on the right track using the COND to allow you to update the information in one pass. Perhaps take a look at my earlier code. Lee Quote Link to comment Share on other sites More sharing options...
pBe Posted February 5, 2011 Share Posted February 5, 2011 Thanks Lee at least now it just one pass BTW: i like the idea of using (setq tags '( ("TITLE-1" . title) ("TITLE-2" . subject) ("TITLE-3" . author) ("TITLE-4" . keywords) ) ) (assoc ...) I already applied this approach on the new codes I've written this past few days Quote Link to comment Share on other sites More sharing options...
Volleyer1 Posted January 10, 2012 Share Posted January 10, 2012 Hi Lee I need to do a very similar task to work on about 150 drawings. I don't suppose you could suggest how to do this but with concatenation of each title line. What I am actually trying to do is map and populate the following Drawing summary : Title block Summary : Title 1, +space, +Title 2, +space, +Title 3 Subject : Status Comments : Version Any help appreciated. 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.