Jump to content

Recommended Posts

Posted (edited)

Hi everybody.

I found this Lisp program online; it displays text and blocks horizontally. Could someone familiar with Lisp please help me adjust it to display them vertically? Thank you.

(defun c:abc ()

  (setq OS (getvar "OSMODE"))
  (setvar "OSMODE" 0)

(princ "\nSelect blocks or text to align horizontaly evenly: ")
(setq ss (ssget))

  (setq albl (entsel "\nSelect text or block to align with: "))
  (setq albl (car albl))
  (setq alpt (cdr (assoc 10 (entget albl))))
  (setq alpty (cadr alpt))
  (setq ctr 0)

    (while
      (setq ename (ssname ss ctr))
      (setq inpt (cdr (assoc 10 (entget ename))))
      (setq inptx (car inpt) )
      (setq inpty (cadr inpt))
      (setq newpt (list inptx alpty))
      (command "move" ename "" inpt newpt)
      (setq ctr (+ ctr 1))
    )

  (setvar "OSMODE" OS)
)

 

Edited by SLW210
Added Code Tags!!!!
Posted (edited)

Post a sample block or drawing also use the <> when posting code.

 

 

Edited by mhupp
  • Thanks 1
Posted

Very quickly try these changes:

 

(setq alpty (cadr alpt))  --->  (setq alptx (car alpt))

 

 (setq newpt (list inptx alpty))  -->   (setq newpt (list alptx inpty))

 

  • Like 3
Posted

Another suggestion

(setq ss (ssget (list (cons 0 "TEXT,INSERT"))))

 

 

  • Like 1
Posted (edited)

Using @BIGAL suggestion for ssget to only pick up text and blocks set in a while loop so you can align multiple things to the same axis. also added a visual to choose between horizontal or vertical alignment.

 

AlignT&B.lsp

Edited by mhupp
Updated the cond to if and fixed link
  • Like 2
  • SLW210 changed the title to I need a LISP to align blocks and texts vertically
Posted

From now own it would be appreciated if you would provide a proper title to your threads.

 

I renamed this one for you.

 

Also, when posting a code, as mentioned by @mhupp, use Code Tags (<> in the editor toolbar)

 

Also, when posting a "found" code, please provide the source where it can be found.

  • Like 1
Posted (edited)

Was looking at the code and that cond is a bit overkill swapped it out with one line if.

 

newpt (if (eq mode 'V) (list (car pt1) (cadr pt) (caddr pt)) (list (car pt) (cadr pt1) (caddr pt)))

 

I also notice entmod doesn't like text that are not left justified.

 

-edit

Apparently text only uses 10 to locate if its left-justified and 11 for everything else. so need to test for that and update either 10 or 11.

 

(if (or (not (assoc 11 ed)) (eq (cdr (assoc 11 ed)) '(0.0 0.0 0.0))) ;test if 11 doesnt exist or is 0,0,0
  (setq ed (subst (cons 10 newpt) (assoc 10 ed) ed))
  (setq ed (subst (cons 11 newpt) (assoc 11 ed) ed))
)
(entmod ed)

 

Edited by mhupp
  • Like 1
Posted
On 4/29/2026 at 10:21 AM, mhupp said:

Using @BIGAL suggestion for ssget to only pick up text and blocks set in a while loop so you can align multiple things to the same axis. also added a visual to choose between horizontal or vertical alignment.

 

AlignT&B.lsp 1.19 kB · 9 downloads

The block att  misaligned text.

  • Like 1
Posted
On 4/28/2026 at 12:38 PM, mhupp said:

Post a sample block or drawing...

 

 

 

You have not posted a drawing yet.

 

A before and after would be very helpful.

Posted (edited)
5 hours ago, sd2006 said:

The block att  misaligned text.

 

 

im guessing the text is left justified and your wanting them to be aligned vertical down the center. need to update line 21 & 22 with code above. and make text center or middle justified.

 

-edit 

or all the same justification. The text justification effects how the text align with the point and each other same with blocks.

The insertion point is what is being updated. its the grip that shows when block is selected.

 

--edit edit

The left pic shows the grips that will be aligned to. (green dots)

the right pic because they are middle justified will use the middle grip points instead of the bottom right for allignment.

 

 

image.png.bb97dd96ba9cdb46f415561159018ada.png

 

Edited by mhupp
  • Like 1
Posted (edited)

@mhuppPlease take a look at the file! use lisp Align T&B.lisp  your,

 

Edited by sd2006
Posted

Indeed, if the block has attributes, (entmod) becomes more complicated: it requires going through transformation matrices and applying them to the attributes.
The move command would be simpler...
Here is the mhupp code adapted for proper operation: Merits to Mhupp for his code

;;----------------------------------------------------------------------------;;
;; Modify Text or Blocks to align Horozontal or Vertical
;; https://www.cadtutor.net/forum/topic/99091-i-need-a-lisp-to-align-blocks-and-texts-vertically/
(defun C:ATB () (C:AlignTextBlock))
(defun C:AlignTextBlock (/ vars vals pt1 pt2 vector mode ent ed pt newpt)
  (vl-load-com)
  (setq vars '(OSMODE ORTHOMODE)
        vals (mapcar 'getvar vars)
  )
  (mapcar 'setvar vars '(0 1))
  (setq pt1 (getpoint "\nAlignment Point: "))
  (setq pt2 (getpoint pt1 "\nSelect Horozontal or Vertical:"))
  (setq vector (mapcar '- pt2 pt1))
  (if (eq (car Vector) 0.0) (setq mode 'V) (setq mode 'H))
  (while (setq ss (ssget '((0 . "TEXT,INSERT"))))
    (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq ed (entget ent)
            pt (cdr (assoc 10 ed))
            newpt (if (eq mode 'V) (list (car pt1) (cadr pt) (caddr pt)) (list (car pt) (cadr pt1) (caddr pt)))
      )
      (vla-Move (vlax-ename->vla-object ent) (vlax-3d-point pt) (vlax-3d-point newpt))
;      (if (or (not (assoc 11 ed)) (eq (cdr (assoc 11 ed)) '(0.0 0.0 0.0))) ;test if 11 doesnt exist or is 0,0,0
;        (setq ed (subst (cons 10 newpt) (assoc 10 ed) ed))
;        (setq ed (subst (cons 11 newpt) (assoc 11 ed) ed))
;      )
;      (entmod ed)
    )
  )
  (mapcar 'setvar vars vals)
  (princ)
)
(princ "\nAlignTextBlock Lisp Loaded")
(princ "\nType ATB or AlignTextBlock to run command")

 

  • Like 4
Posted

@mhupp

If you want to keep (entmod) in your code and make it efficient, you can refine your filter (ssget) to exclude blocks with attributes.

(setq ss (ssget '((0 . "TEXT,INSERT") (66 . 0))))

  • Like 2
Posted (edited)
7 hours ago, Tsuky said:

@mhupp

If you want to keep (entmod) in your code and make it efficient, you can refine your filter (ssget) to exclude blocks with attributes.

(setq ss (ssget '((0 . "TEXT,INSERT") (66 . 0))))

 

I Just try to avoid using command. apparently their is a bug in autocad 2026 and newer that balloons lisp to 276 seconds when it only took .24 second in older versions. just figured everything contained in the block id would move when updating. cant test right but does adding the 66 . 0  exclude single text outside of blocks?

 

vla-move works for me keep it simple.  

 

 

Edited by mhupp
  • Like 2
Posted

I used to use JTB Align Plus - JTB World.

 

I need IT to reinstall, haven't needed it recently, so I'll probably wait until I need, but pretty sure it will do everything the OP wants and more.

 

I have a LISP, but IIRC it may need a lot of tweaking for the OPs usage. 

  • Like 1
Posted
On 5/1/2026 at 12:36 AM, Tsuky said:

Indeed, if the block has attributes, (entmod) becomes more complicated: it requires going through transformation matrices and applying them to the attributes.
The move command would be simpler...
Here is the mhupp code adapted for proper operation: Merits to Mhupp for his code

;;----------------------------------------------------------------------------;;
;; Modify Text or Blocks to align Horozontal or Vertical
;; https://www.cadtutor.net/forum/topic/99091-i-need-a-lisp-to-align-blocks-and-texts-vertically/
(defun C:ATB () (C:AlignTextBlock))
(defun C:AlignTextBlock (/ vars vals pt1 pt2 vector mode ent ed pt newpt)
  (vl-load-com)
  (setq vars '(OSMODE ORTHOMODE)
        vals (mapcar 'getvar vars)
  )
  (mapcar 'setvar vars '(0 1))
  (setq pt1 (getpoint "\nAlignment Point: "))
  (setq pt2 (getpoint pt1 "\nSelect Horozontal or Vertical:"))
  (setq vector (mapcar '- pt2 pt1))
  (if (eq (car Vector) 0.0) (setq mode 'V) (setq mode 'H))
  (while (setq ss (ssget '((0 . "TEXT,INSERT"))))
    (foreach ent (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))
      (setq ed (entget ent)
            pt (cdr (assoc 10 ed))
            newpt (if (eq mode 'V) (list (car pt1) (cadr pt) (caddr pt)) (list (car pt) (cadr pt1) (caddr pt)))
      )
      (vla-Move (vlax-ename->vla-object ent) (vlax-3d-point pt) (vlax-3d-point newpt))
;      (if (or (not (assoc 11 ed)) (eq (cdr (assoc 11 ed)) '(0.0 0.0 0.0))) ;test if 11 doesnt exist or is 0,0,0
;        (setq ed (subst (cons 10 newpt) (assoc 10 ed) ed))
;        (setq ed (subst (cons 11 newpt) (assoc 11 ed) ed))
;      )
;      (entmod ed)
    )
  )
  (mapcar 'setvar vars vals)
  (princ)
)
(princ "\nAlignTextBlock Lisp Loaded")
(princ "\nType ATB or AlignTextBlock to run command")

 

It doesn't work with mtext. Can you do that? Thank you.

Posted (edited)

@TsukyIt doesn't work with mtext. Can you do that? Thank you.

Edited by sd2006
Posted
3 minutes ago, sd2006 said:

It doesn't work with mtext. Can you do that? Thank you.

 

added a "*" to ssget to pick up mtext or text. updated the foreach to pull the vla-objects name from the selection set.

 

;;----------------------------------------------------------------------------;;
;; Modify Text or Blocks to align Horozontal or Vertical
;; https://www.cadtutor.net/forum/topic/99091-i-need-a-lisp-to-align-blocks-and-texts-vertically/
(defun C:ATB () (C:AlignTextBlock))
(defun C:AlignTextBlock (/ vars vals pt1 pt2 vector mode ent ed pt newpt)
  (vl-load-com)
  (setq vars '(OSMODE ORTHOMODE)
        vals (mapcar 'getvar vars)
  )
  (mapcar 'setvar vars '(0 1))
  (setq pt1 (getpoint "\nAlignment Point: "))
  (setq pt2 (getpoint pt1 "\nSelect Horozontal or Vertical:"))
  (setq vector (mapcar '- pt2 pt1))
  (if (eq (car Vector) 0.0) (setq mode 'V) (setq mode 'H))
  (while (setq ss (ssget '((0 . "*TEXT,INSERT"))))
    (foreach obj (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))))
      (setq pt (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint obj)))
            newpt (if (eq mode 'V) (list (car pt1) (cadr pt) (caddr pt)) (list (car pt) (cadr pt1) (caddr pt)))
      )
      (vla-Move obj (vlax-3d-point pt) (vlax-3d-point newpt))
    )
  )
  (mapcar 'setvar vars vals)
  (princ)
)
(princ "\nAlignTextBlock Lisp Loaded")
(princ "\nType ATB or AlignTextBlock to run command")

 

  • Like 1
Posted
On 4/29/2026 at 12:11 AM, Steven P said:

Very quickly try these changes:

 

(setq alpty (cadr alpt))  --->  (setq alptx (car alpt))

 

 (setq newpt (list inptx alpty))  -->   (setq newpt (list alptx inpty))

 

hi @Steven PI adjusted it as you instructed, but it moved further away to a different position.see attach file. thank you.

abc.lsp bock 1.dwg

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...