Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Extract name of nested block on insert

16 REPLIES 16
Reply
Message 1 of 17
JeffPaulsen
414 Views, 16 Replies

Extract name of nested block on insert

I wrote a program to update our titleblocks (see this thread http://forums.augi.com/showthread.php?p=767374#post767374). I want to modify that program to update our logo block at the same time.

Our company logo is a nested block inside of the titleblock and it is not dynamic. I have a seperate logo drawing for each address and we have several different formats of the logo.

I know how to redefine the block. I can use similar code to what I am using to redefine the titleblock. What I really need to know is how to extract the logo block name from the titleblock so I know which logo to redefine. I'm pretty sure that the logo is the only nested block in our titleblocks.

How can I extract the name of a nested block from the my titleblock block?
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
16 REPLIES 16
Message 2 of 17
Anonymous
in reply to: JeffPaulsen

*If* you're lucky enough that the various logo blocks all start with the same characters (say, for
example, Logo1, Logo2, Logo0723, LogoWalMart, or whatever), then you could search the database for a
Block definition whose name starts with those common characters, using the (substr) function:

(= (substr (cdr (assoc 2 blockdata)) 1 4) "Logo")

If that returns True, you can extract the entire block name, and do the redefinition. If there's
any possibility that the upper-lowercase arrangement might vary, add a (strcase) function.
--
Kent Cooper


wrote...
I wrote a program to update our titleblocks (see this thread
http://forums.augi.com/showthread.php?p=767374#post767374). I want to modify that program to update
our logo block at the same time.

Our company logo is a nested block inside of the titleblock and it is not dynamic. I have a seperate
logo drawing for each address and we have several different formats of the logo.

I know how to redefine the block. I can use similar code to what I am using to redefine the
titleblock. What I really need to know is how to extract the logo block name from the titleblock so
I know which logo to redefine. I'm pretty sure that the logo is the only nested block in our
titleblocks.

How can I extract the name of a nested block from the my titleblock block?
Message 3 of 17
JeffPaulsen
in reply to: JeffPaulsen

I am not very good at lisp but I do try. I was not able to get this do do anything excpet return "error: bad argument type: listp". I tried putting it into an IF statement and I tried putting into my titleblock program.

Am I supposed to be substituting some othe code where it says "blockdata" ? I tried using the titleblock name, the variable of the selected titleblock and the variable of the DXF list of the titleblock.
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
Message 4 of 17
JeffPaulsen
in reply to: JeffPaulsen

FYI: All my logo blocks do begin with "Logo".
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
Message 5 of 17
Anonymous
in reply to: JeffPaulsen

If the logo block is nested one level deep in the title block and selecting it is not
an issue...

Command: (nentsel)

Select object: ( (34.5887 21.4986 0.0) ((1.0 0.0 0.0)
(0.0 1.0 0.0) (0.0 0.0 1.0) (34.7185 20.5962 0.0)) (
))

Command: (setq e (car (last (nentsel))))

Select object:

That's the ename of the nested block.

Then (cdr (assoc 2 (entget e))) should return the nested block name.

Joe Burke



wrote in message news:5747827@discussion.autodesk.com...
I wrote a program to update our titleblocks (see this thread
http://forums.augi.com/showthread.php?p=767374#post767374). I want to modify that
program to update our logo block at the same time.

Our company logo is a nested block inside of the titleblock and it is not dynamic. I
have a seperate logo drawing for each address and we have several different formats
of the logo.

I know how to redefine the block. I can use similar code to what I am using to
redefine the titleblock. What I really need to know is how to extract the logo block
name from the titleblock so I know which logo to redefine. I'm pretty sure that the
logo is the only nested block in our titleblocks.

How can I extract the name of a nested block from the my titleblock block?
Message 6 of 17
JeffPaulsen
in reply to: JeffPaulsen

Thanks Joe.

I was able to get the nested block name so I can work with this.

I was hoping to retrieve the nested block name without user input. I wanted to just search the parent block for the nested block.

But atleast you gave me a way to get the nested block name.
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
Message 7 of 17
Tom Smith
in reply to: JeffPaulsen

I don't see why you need to retrieve the name from inside the title block. Just do a tblsearch for all of the logo block names, and if one is present in the drawing, update it.

If you had to, you could step through the title block table definition with entnext, looking for a logo block name, but then you'd be right back to updating it as above anyway.
Message 8 of 17
Anonymous
in reply to: JeffPaulsen

Yes, 'blockdata' was my shorthand for the entity data list for the block definition. You would
probably need to make a selection set of all entities in the drawing, and check for a block name
that starts with Logo. That's not too hard, but if it's a *nested* block, I'm not sure how to get
at it (I imagine someone here knows).

(entget (tblobjname "block" "Logo1"))

returns the data list for Logo1 that I would save in 'blockdata', but you seem to have to already
know the entire block name to use it -- (tblobjname) doesn't accept wildcards. There's no point in
using that to extract the block name as I was suggesting, if you need the block name to do it. So I
think there has to be another way to locate a block definition when you're only certain of part of
its name -- it's just beyond my abilities.
--
Kent Cooper


wrote...
I am not very good at lisp but I do try. I was not able to get this do do anything excpet return
"error: bad argument type: listp". I tried putting it into an IF statement and I tried putting into
my titleblock program.

Am I supposed to be substituting some othe code where it says "blockdata" ? I tried using the
titleblock name, the variable of the selected titleblock and the variable of the DXF list of the
titleblock.
Message 9 of 17
t.willey
in reply to: JeffPaulsen

Jeff,

To do this without user input, you need to know the name of the main
block, the title block. Then you will step through the blocks definition
like Kent said to search for you block. Simple example to get you going.

(setq BlkEnt (tblobjname "block" "YourBlockName")) ; get your block
definition ename
(while (setq BlkEnt (entnext BlkEnt)) ; this will step through all the
entities within the block
(setq EntData (entget BlkEnt)) ; gett he dxf list of the entity
(if
(and
(= (cdr (assoc 0 EntData)) "INSERT") ; make sure it is a block
(wcmatch (strcase (cdr (assoc 2 EntData))) "LOGO*") ; make sure
the block name starts with LOGO
)
..... do what you want here because it is the right block
)
)

Hope that makes sense.

--

Tim
"A blind man lets nothing block his vision."


wrote in message news:5748069@discussion.autodesk.com...
Thanks Joe.

I was able to get the nested block name so I can work with this.

I was hoping to retrieve the nested block name without user input. I wanted
to just search the parent block for the nested block.

But atleast you gave me a way to get the nested block name.
Message 10 of 17
Anonymous
in reply to: JeffPaulsen

I tried that, but (tblsearch) also requires a full block name, and doesn't accept wild-cards. I
guess if there are a limited number of them, you could do

(tblsearch "block" "logo1")
and
(tblsearch "block" "logo2")

and so on for each, in a (cond) function until it finds one. But they use a different Logo for each
client. If they use names like "LogoWalMart" for one client, and will some day make one called
"LogoDonaldTrump" and another called "LogoGucci", neither of which exist when the routine is
written, then either you need to add those to the routine every time a new one comes along, or you
need a wild-card solution. The same is true if they use names like "Logo1", "Logo2", and so on, if
there will some day be a "Logo37" that doesn't exist yet.

-Insert ? Logo*
or
(command "insert" "?" "Logo*")

will tell you, but I'm not sure how to get just the block name out of what it returns (assuming
there's only one) into a Lisp variable. Any ideas?
--
Kent Cooper


wrote...
I don't see why you need to retrieve the name from inside the title block. Just do a tblsearch for
all of the logo block names, and if one is present in the drawing, update it.

If you had to, you could step through the title block table definition with entnext, looking for a
logo block name, but then you'd be right back to updating it as above anyway.
Message 11 of 17
Anonymous
in reply to: JeffPaulsen

That's the part I've never worked with before -- stepping through the entities in a block
definition. Assuming there's only one Logo* block in there, you could make it stop stepping once it
finds it, so it doesn't need to keep checking all the subsequent entities. Perhaps something like:

....
(while
(and
(setq BlkEnt (entnext BlkEnt))
(not Foundit)
)
(setq EntData (entget BlkEnt))
(if
(and
(= (cdr (assoc 0 EntData)) "INSERT")
(wcmatch (strcase (cdr (assoc 2 EntData))) "LOGO*")
)
(progn
(..... do what you want here because it is the right block....)
(setq Foundit T)
); end progn
); end if
); end while
....

This should be a good approach, again assuming certain things. If the title block's name is also
different for different jobs, or for different sheet sizes, or between imperial and metric drawings,
or whatever, then you might still want a wild-card approach of some kind. But since that one
presumably isn't nested, at least then you can make a selection set of all insertions, and check for
one with the right kind of name, *also* assuming those title block blocks have some commonality of
naming.
--
Kent Cooper


wrote...
Jeff,

To do this without user input, you need to know the name of the main
block, the title block. Then you will step through the blocks definition
like Kent said to search for you block. Simple example to get you going.

(setq BlkEnt (tblobjname "block" "YourBlockName")) ; get your block
definition ename
(while (setq BlkEnt (entnext BlkEnt)) ; this will step through all the
entities within the block
(setq EntData (entget BlkEnt)) ; gett he dxf list of the entity
(if
(and
(= (cdr (assoc 0 EntData)) "INSERT") ; make sure it is a block
(wcmatch (strcase (cdr (assoc 2 EntData))) "LOGO*") ; make sure
the block name starts with LOGO
)
..... do what you want here because it is the right block
)
)

Hope that makes sense.
--
Tim
....
Message 12 of 17
JeffPaulsen
in reply to: JeffPaulsen

Thanks Tim.

I am going to finish writing a routine to update just the logo using nentsel per Joe's suggestion. This will be handy for our "custom" title blocks.

Then I will be jumping right in and trying your suggestion in my titleblock update routine.
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
Message 13 of 17
Tom Smith
in reply to: JeffPaulsen

>they use a different Logo for each client

I didn't get that. OP said "a seperate logo drawing for each address and we have several different formats of the logo." I took that to mean a diffrent logo for each branch of his firm, not each client. Which would be a finite number, but of course it could change in the future.

Tim has posted a method below for stepping through the title block looking for LOGO*.

Another way would be to step through the block table with tblnext, looking for a qualifying block name and up[dating it if found. I wouldn't bother bailing on the first one found, either. I'd update *any* block found in the drawing beginning with LOGO, if there was a matching external block name from findfile.

(EDIT)
Though I'm a vl dummy, you could also step through the block table that way.

(defun c:test (/ blocks blockname)
(setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
(vlax-for block blocks
(if (wcmatch (setq blockname (vla-get-name block)) "LOGO*")
(print blockname) ;redefine block here
))
(princ)
)
Message 14 of 17
JeffPaulsen
in reply to: JeffPaulsen

Thanks a lot guys. You've been a big help.

I used Tim's suggestion to modify my titleblock update routine to automatically update our nested logo block when the titleblock is updated. I posted the final code for this on the AUGI forums http://forums.augi.com/showthread.php?t=69110

I used Joe's suggestion to write another routine to update only the nested logo by picking the logo on the screen.

(defun updatelogo ( / );vss lgname nlgname)
(setq vss (car (last (nentsel "\nSelect Logo to Update: "))))
(setq lgname (cdr (assoc 2 (entget vss))))
(if (findfile (setq nlgname (strcat "Z:/Autodesk 2008/JRSym/Logos/JRLogos/"lgname".dwg")))
(progn
(command "-insert" (strcat lgname"="nlgname) "y")
(command)
(princ (strcat "\n"lgname" redefined."))
)
(princ (strcat "\nCould not find "nlgname))
)
(princ)
)
(defun c:updatelogo () (updatelogo))
(defun c:udlg () (updatelogo))
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200
Message 15 of 17
t.willey
in reply to: JeffPaulsen

Looks like you are picking it up pretty quickly Jeff. Congrates.

--

Tim
"A blind man lets nothing block his vision."


wrote in message news:5748573@discussion.autodesk.com...
Thanks a lot guys. You've been a big help.

I used Tim's suggestion to modify my titleblock update routine to
automatically update our nested logo block when the titleblock is updated. I
posted the final code for this on the AUGI forums
http://forums.augi.com/showthread.php?t=69110

I used Joe's suggestion to write another routine to update only the nested
logo by picking the logo on the screen.

(defun updatelogo ( / );vss lgname nlgname)
(setq vss (car (last (nentsel "\nSelect Logo to Update: "))))
(setq lgname (cdr (assoc 2 (entget vss))))
(if (findfile (setq nlgname (strcat "Z:/Autodesk
2008/JRSym/Logos/JRLogos/"lgname".dwg")))
(progn
(command "-insert" (strcat lgname"="nlgname) "y")
(command)
(princ (strcat "\n"lgname" redefined."))
)
(princ (strcat "\nCould not find "nlgname))
)
(princ)
)
(defun c:updatelogo () (updatelogo))
(defun c:udlg () (updatelogo))
Message 16 of 17
Tom Smith
in reply to: JeffPaulsen

Ditto
Message 17 of 17
JeffPaulsen
in reply to: JeffPaulsen

To anyone who uses my code above. I left an extra right paren and semicolon in the first line by accident. I put them in there for testing purposes.

The first line should read.
(defun updatelogo ( / vss lgname nlgname)

And thanks for the kind words guys. This was an accomplishment for me 😃
Jeff Paulsen
Civil 3D 2020.4 | Win 10 Pro N 64-bit
Xeon W-2223 @ 3.60GHz, 32GB Ram | NVidia Quadro P2200

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost