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

Move a named block left 5 inches.

25 REPLIES 25
Reply
Message 1 of 26
XIJIANGWOO
803 Views, 25 Replies

Move a named block left 5 inches.

Hello Guys,

 

I'm dabbling in lisp to reduce some drafting time. I'm looking for a way to move a named block left 5 inches. The names block in this instance is "Bricks". What would be the easiest way of writing this in lisp form? I searched through the forums and I couldn't find what I was looking for. This is not after an insert command. This is a block that currently exists in the drawing template.

 

I appreciate any help to get me started.

 

Thanks,

 

Xi

 

 

25 REPLIES 25
Message 2 of 26
scot-65
in reply to: XIJIANGWOO


@XIJIANGWOO wrote:

Hello Guys,

 

I'm dabbling in lisp to reduce some drafting time. I'm looking for a way to move a named block left 5 inches. The names block in this instance is "Bricks". What would be the easiest way of writing this in lisp form? I searched through the forums and I couldn't find what I was looking for. This is not after an insert command. This is a block that currently exists in the drawing template.

 

I appreciate any help to get me started.

 

Thanks,

 

Xi

 

 


Are there multiple copies of this block?

YES = use TBLNEXT in a WHILE loop.

NO = use (TBLSEARCH "BLOCK" "Bricks") ;this will grab the first instance.

 

(setq a (entget (car (tblsearch "BLOCK" "Bricks")))) ;will get you the block.

(setq b (cdr (assoc 10 a))) ;will get you the insert point.

(setq c (car b)) ;will get you the x-value of insert point.

Subtract 5.

Rebuild using LIST.

ENTMOD DFX 10 for new coordinate. I will not elaborate here. This is your learning curve for today.

 

If block does not update location, but does on a REGEN, use ENTUPD.

It should move as ENTUPD is for objects inside the block that does require screen updating...

 

Once you master ENTMOD, it will become your most powerful tool to use here in LISP.

Entmod Substitute and Entmod Append are your friends here. Know how to use each one.

 

Good Luck!


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 3 of 26
Kent1Cooper
in reply to: XIJIANGWOO


@XIJIANGWOO wrote:

.... I'm looking for a way to move a named block left 5 inches. The names block in this instance is "Bricks".....


If there's only one in the drawing, it can be as simple as this:

 

(command "_.move" (ssname (ssget "_X" '((2 . "Bricks"))) 0) "" "-5,0" "")

 

I find it isn't even case-sensitive about the Block name.

 

If there are more than one, it will move only the last-inserted one of them, but could be made to move all of them:

 

(command "_.move" (ssget "_X" '((2 . "Bricks"))) "" "-5,0" "")

Kent Cooper, AIA
Message 4 of 26
Kent1Cooper
in reply to: scot-65


scot-65 wrote:

....

(setq a (entget (car (tblsearch "BLOCK" "Bricks")))) ;will get you the block.

(setq b (cdr (assoc 10 a))) ;will get you the insert point.

(setq c (car b)) ;will get you the x-value of insert point.

Subtract 5.

Rebuild using LIST.

ENTMOD DFX 10 for new coordinate. ....

If block does not update location, but does on a REGEN, use ENTUPD.

....


That won't do it.  The (tblsearch) function finds the definition of the Block, but says nothing about any instance of insertion of that Block.  You can have a Block definition in the Table without even having any insertions of it in the drawing.  Trying the first line of code above:

 

Command: (setq a (entget (car (tblsearch "BLOCK" "Bricks"))))
; error: bad argument type: lentityp (0 . "BLOCK")

 

If you want an entity data list kind of thing, with pseudo-entity characteristics, you can use (tblobjname) instead:

 

Command: (setq a (entget (tblobjname "BLOCK" "Bricks")))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

But changing the (10 0.0 0.0 0.0) in that list to (10 -5.0 0.0 0.0) doesn't have any effect on insertions of that Block.

Command: (setq a (subst '(10 -5.0 0.0 0.0) (assoc 10 a) a))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 -5.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

Yes, it "looks" like it's changed something, but the Block doesn't move, even with Regeneration.  And (entmod) doesn't do anything, either, since the Block definition isn't an entity:

 

Command: (entmod a)
nil

 

[When you do that with an actual entity [e.g. change the insertion point of a Block insertion, or an endpoint of a Line], it doesn't return nil, but returns the altered entity data list and changes the entity.]

 

You can try with the list from (tblsearch) without the (entget (car ...)) wrapper, since that also has pseudo-entity characteristics, including a (10) entry:

 

Command: (setq a (tblsearch "block" "Bricks"))
((0 . "BLOCK") (2 . "Bricks") (70 . 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>))

 

But changing that (10) entry in the same way also does nothing to insertions of the Block, and (entmod) on it also returns nil.

 

And (entupd) doesn't do it, either [here on the (tblobjname) list]:

 

Command: (entupd a)
; error: bad argument type: lentityp ((-1 . <Entity name: 7ef49d98>) (0 .
"BLOCK") (330 . <Entity name: 7ef49d90>) (5 . "33") (100 . "AcDbEntity") (67 .
0) (8 . "0") (100 . "AcDbBlockBegin") (70 . 0) (10 -5.0 0.0 0.0) (-2 . <Entity
name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

And likewise if you separate the pseudo-entity of the (tblobjname) item from the list (entget) returns for it, and use (entmod) on the latter and then (entupd) on the former.  And since it can't (entupd) something that's not a real entity, it doesn't actually change the Block definition.  Checking that again:

 

Command: (entget (tblobjname "block" "Bricks"))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

It's still what it was before.

Kent Cooper, AIA
Message 5 of 26
pbejse
in reply to: scot-65

 

You can however use

(vla-put-origin
      (vla-item
            (vla-get-blocks
                  (vla-get-ActiveDocument (vlax-get-acad-object)))
            "Bricks")
      (vlax-3d-point '(-5.0 0.0 0.0)))

 

But there are issues  when dealing with blocks, like when its mirrored/scaled . it will be different effect for each block.

Mirrored: will move to the opposite direction

Sacled: will depend on the current insertion scale , so 5 for some would be 0.75 on the other insertion.

 

So using the command "move" makes more sense in this case scot-65

 

HTH

Message 6 of 26
pbejse
in reply to: XIJIANGWOO


@XIJIANGWOO wrote:

Hello Guys,

 

I'm dabbling in lisp to reduce some drafting time. I'm looking for a way to move a named block left 5 inches. The names block in this instance is "Bricks". What would be the easiest way of writing this in lisp form? I searched through the forums and I couldn't find what I was looking for. This is not after an insert command. This is a block that currently exists in the drawing template.

 

I appreciate any help to get me started.

 

Thanks,

 

Xi

 

 


Now that i read your post, it makes me wonder what exactly you meant by move 5 inches,

 

<<< This is not after an insert command. >>>

 

Does it mean prior to inserting to blocks?  then why dont you just redefine the block and overwrite the template

Plain ol BEDIT and save the template.

If its too late for that redefine the block

(command "._-insert" "Bricks=" (command))

otherwise use (vla-put-oriign...) approach

 

Now if the blocks are already inserted , then (command "_move" ... )  will do the trick.

 

HTH

Message 7 of 26
Kent1Cooper
in reply to: pbejse


@pbejse wrote:
.... 

<<< This is not after an insert command. >>>

 

Does it mean prior to inserting to blocks?....


I interpreted that to mean simply that it's not immediately after an Insert command, so that they can't use (entlast) to find the Block to move, but must find it by other means.

Kent Cooper, AIA
Message 8 of 26
pbejse
in reply to: Kent1Cooper


@Kent1Cooper wrote:

 

I interpreted that to mean simply that it's not immediately after an Insert command, so that they can't use (entlast) to find the Block to move, but must find it by other means.



You may very well be right Kent, thats how put it at first really.

 

but whats with the reference to template

 

<< This is a block that currently exists in the drawing template >>

 

whats that all about?   Smiley Happy  

Message 9 of 26
scot-65
in reply to: Kent1Cooper

It took 10 minutes to assemble and post my response.

It might have a few errors, some intentional for learning curve purposes.

Use ssget and create a selection set instead of using tblsearch. My Bad.

 

How long did it take to compose your response?

 

🙂

 

 


@Kent1Cooper wrote:

@scot-65 wrote:

....

(setq a (entget (car (tblsearch "BLOCK" "Bricks")))) ;will get you the block.

(setq b (cdr (assoc 10 a))) ;will get you the insert point.

(setq c (car b)) ;will get you the x-value of insert point.

Subtract 5.

Rebuild using LIST.

ENTMOD DFX 10 for new coordinate. ....

If block does not update location, but does on a REGEN, use ENTUPD.

....


That won't do it.  The (tblsearch) function finds the definition of the Block, but says nothing about any instance of insertion of that Block.  You can have a Block definition in the Table without even having any insertions of it in the drawing.  Trying the first line of code above:

 

Command: (setq a (entget (car (tblsearch "BLOCK" "Bricks"))))
; error: bad argument type: lentityp (0 . "BLOCK")

 

If you want an entity data list kind of thing, with pseudo-entity characteristics, you can use (tblobjname) instead:

 

Command: (setq a (entget (tblobjname "BLOCK" "Bricks")))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

But changing the (10 0.0 0.0 0.0) in that list to (10 -5.0 0.0 0.0) doesn't have any effect on insertions of that Block.

Command: (setq a (subst '(10 -5.0 0.0 0.0) (assoc 10 a) a))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 -5.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

Yes, it "looks" like it's changed something, but the Block doesn't move, even with Regeneration.  And (entmod) doesn't do anything, either, since the Block definition isn't an entity:

 

Command: (entmod a)
nil

 

[When you do that with an actual entity [e.g. change the insertion point of a Block insertion, or an endpoint of a Line], it doesn't return nil, but returns the altered entity data list and changes the entity.]

 

You can try with the list from (tblsearch) without the (entget (car ...)) wrapper, since that also has pseudo-entity characteristics, including a (10) entry:

 

Command: (setq a (tblsearch "block" "Bricks"))
((0 . "BLOCK") (2 . "Bricks") (70 . 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>))

 

But changing that (10) entry in the same way also does nothing to insertions of the Block, and (entmod) on it also returns nil.

 

And (entupd) doesn't do it, either [here on the (tblobjname) list]:

 

Command: (entupd a)
; error: bad argument type: lentityp ((-1 . <Entity name: 7ef49d98>) (0 .
"BLOCK") (330 . <Entity name: 7ef49d90>) (5 . "33") (100 . "AcDbEntity") (67 .
0) (8 . "0") (100 . "AcDbBlockBegin") (70 . 0) (10 -5.0 0.0 0.0) (-2 . <Entity
name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

And likewise if you separate the pseudo-entity of the (tblobjname) item from the list (entget) returns for it, and use (entmod) on the latter and then (entupd) on the former.  And since it can't (entupd) something that's not a real entity, it doesn't actually change the Block definition.  Checking that again:

 

Command: (entget (tblobjname "block" "Bricks"))
((-1 . <Entity name: 7ef49d98>) (0 . "BLOCK") (330 . <Entity name: 7ef49d90>)
(5 . "33") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70
. 0) (10 0.0 0.0 0.0) (-2 . <Entity name: 7ef49da8>) (2 . "Bricks") (1 . ""))

 

It's still what it was before.





Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 10 of 26
XIJIANGWOO
in reply to: XIJIANGWOO

Thanks Guys !

 

Kent's solution was simple and perfect for what I wanted to accomplish. I simply wanted to be able to open a template

and decide whether I should move my block 5 inches to the left or leave as is. I'm not at all advanced in lisp so I am still playing with the other suggestions as well.

 

Thanks again for all of the help. I appreciate it.

 

Xi

Message 11 of 26
lorenzo.ticci
in reply to: XIJIANGWOO

regarding Kent's solution,

why it is not possible use a string variable instead of "Bricks" ?

for example.. (setq blocco "Bricks")
and as consequence:

(command "_.move" (ssname (ssget "_X" '((2 . blocco))) 0) "" "-5,0,0" "")

Thanx for the interesting discussion
Message 12 of 26
marko_ribar
in reply to: lorenzo.ticci

Apostrophe sign in (ssget) filter means that list expression isn't evaluated but taken literally as its written...

 

Try instead :

(command "_.move" (ssname (ssget "_X" (list (cons 2 blocco))) 0) "" "-5,0,0" "")

 

About "The Apostrophe and Quote function" read here :

http://www.lee-mac.com/quote.html

 

HTH, M.R.

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 13 of 26
lorenzo.ticci
in reply to: marko_ribar

Thank you so mutch marko_ribar! and one question more...the lisp analized befor is really good for working with only a single block name "bricks"..if I have a saved block named "brick" and I want to "_insert" more times...for example during a for cicle in which the same block has to be inserted more times and at the same time moved of different coordinate....what do you suggest?...Itcould be possible to insert the block brick.dwg by using a string variable (setq blocco "brick.dwg"), positioning the dwg on coordinate 0,0,0 and then move it into the new coordinate?after this inserting the same block again at the coordinate 0,0,0 and then to move the block to a new coordinate? thank you for supporting!
Message 14 of 26
Kent1Cooper
in reply to: lorenzo.ticci


@lorenzo.ticci wrote:
....if I have a saved block named "brick" and I want to "_insert" more times...for example during a for cicle in which the same block has to be inserted more times and at the same time moved of different coordinate....what do you suggest?...Itcould be possible to insert the block brick.dwg by using a string variable (setq blocco "brick.dwg"), positioning the dwg on coordinate 0,0,0 and then move it into the new coordinate?after this inserting the same block again at the coordinate 0,0,0 and then to move the block to a new coordinate? thank you for supporting!

For that, I would [...Insert one if there isn't one already, and...] just use COPY with the Multiple option.

Kent Cooper, AIA
Message 15 of 26
marko_ribar
in reply to: Kent1Cooper

Or if you have already built point list where you want insertions to occur and you placed your "brick.dwg" in SFSP, try this code :

 

(defun c:insertbricks ( / blocco ptlst )
  (setq blocco (findfile "brick.dwg"))
(setq ptlst '((0.0 0.0 0.0) (1.0 1.0 0.0) (2.0 2.0 0.0))) ; ptlst example - here you must build or specify point list (foreach pt ptlst (command "_.-INSERT" blocco "_none" pt) (while (> (getvar 'cmdactive) 0) (command "")) ) (princ) )

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 16 of 26
lorenzo.ticci
in reply to: Kent1Cooper

ok , but in which way coud I copy the same block and move the copy in a new coordinate? there could be problem when searcing the block according to ita bloc name?
Message 17 of 26
marko_ribar
in reply to: lorenzo.ticci


@lorenzo.ticci wrote:
ok , but in which way coud I copy the same block and move the copy in a new coordinate? there could be problem when searcing the block according to ita bloc name?

Instead of :

(setq blocco (findfile "Brick.dwg"))

 

I suggest that you hardcode dwg with it's full path...

(setq blocco "c:\\folder\\subfolder1\\subfolder2\\...\\Brick.dwg")

 

But you may also use Kent's method : insert one block in 0,0,0 coordinate and then copy (first point : 0,0,0) (second point : x,y,z) as many times as you have second points build into a list of points...

Marko Ribar, d.i.a. (graduated engineer of architecture)
Message 18 of 26
lorenzo.ticci
in reply to: marko_ribar

good idea...let me think...considering that for my contest...it coul be possible to organize an excel file and let the lisp working with a for or while cicle...but I think it could be easierif something like this is possible:

(defun c:insertbricks ( / blocco pt )
(setq blocco (findfile A".dwg")); A is a string variable that I could take from the excel file during the for cicle...A has the same name of the block that i have stored in a dedicated browse.
(setq pt '(VAL1 VAL2 VAL3)); pt is made up by the three string variables VAL1,2,3 that i can take from the excel file
(command "_.-INSERT" blocco "_none" pt)
)

do you think it could be reasonable or I have to espect conflict when i will insert the same block during the second time?
Message 19 of 26
Kent1Cooper
in reply to: lorenzo.ticci


@lorenzo.ticci wrote:
ok , but in which way coud I copy the same block and move the copy in a new coordinate? there could be problem when searcing the block according to ita bloc name?

Maybe I don't understand what you're really trying to do.  I see no point in Copying and then Moving when you can Copy directly to the location(s) you want.  You can have a routine find a Block by name, and do the equivalent of:

 

COPY;

The Block [+ Enter to end selection];

Multiple option;

Get insertion base point from found Block for base point;

New Coordinates 1 as point to make first copy to;

New Coordinates 2 as point to make next copy to;

New Coordinates 3 as point to make next copy to;

... etc. ...

 

Am I missing something?

Kent Cooper, AIA
Message 20 of 26
lorenzo.ticci
in reply to: Kent1Cooper

two ways of aking...

the first one is:

 

VAL2, VAL3, VAL4 are string variables taken from the excel file during each "for" cicle or "while" cicle

 

(setq coord (strcat VAL2 "," VAL3 "," VAL4))

(setq blocco "D:\\CANTIERE_LORE\\1.dwg"); defining the path of the dwg to be inserted

(command "_.-INSERT" blocco coord)

 

in this way I have a problem...when I insert the block the window used for attributes open blocking the lisp routine...and forcing my manual input that Iwould like to avoid..

 

The other way is the copy with multiple option...

 

considering thre different points for the positioning of the copy...coord1, coord2, coord3 is it corret the following :

 

(command "_.copy" (ssname (ssget "_X" (list (cons 2 VAL1))) 0) "" "_Multiple" coord1 coord2 coord3 "")

 

 

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

Post to forums  

Autodesk Design & Make Report

”Boost