Нужно с использованием AutoLISP или Visual LISP (...

Tạo vào: 16 tháng 9, 2026

Trả lời bằng GPT-5.6 Thinking bởi Chat01

Câu hỏi

мтекст-1 строка.png

Нужно с использованием AutoLISP или Visual LISP (AutoCAD 2021 (RU))
выбрать несколько многострочных MText рамкой или по одному и
преобразовать каждый мтекст по отдельности в одну строку, см. рисунок.

Suy nghĩ

Flattening MText lines

I’m planning to remove explicit paragraph breaks, preserve formatting codes, temporarily widen the text, and then adjust its width to the resulting single-line extent while keeping the attachment point stable.

Worked for 59s

Trả lời

Да. Здесь важно обработать оба варианта многострочности MText:

  • явные переносы строки \P;
  • автоматический перенос из-за заданной ширины рамки MText.

Ниже вариант для AutoCAD 2021, который оставляет объекты именно MText, но каждый выбранный MText делает одной визуальной строкой. Форматирование текста при этом в основном сохраняется.

lisp
(vl-load-com) ;;------------------------------------------------------------ ;; Замена всех вхождений OLD на NEW ;;------------------------------------------------------------ (defun MT1:ReplaceAll (new old str / pos) (while (setq pos (vl-string-search old str)) (setq str (vl-string-subst new old str pos)) ) str ) ;;------------------------------------------------------------ ;; Убираем явные переводы строк из MText ;;------------------------------------------------------------ (defun MT1:CleanString (str) ;; Перенос строки MText \P заменяем пробелом (setq str (MT1:ReplaceAll " " "\\P" str)) ;; На всякий случай убираем реальные CR/LF (setq str (MT1:ReplaceAll " " (chr 13) str)) (setq str (MT1:ReplaceAll " " (chr 10) str)) str ) ;;------------------------------------------------------------ ;; Команда MT1LINE ;;------------------------------------------------------------ (defun c:MT1LINE (/ *error* acad doc ss i en obj txt h big objlist item aw undo cnt) (vl-load-com) (setq acad (vlax-get-acad-object)) (setq doc (vla-get-ActiveDocument acad)) (setq undo nil cnt 0) ;; Обработчик ошибки (defun *error* (msg) (if undo (progn (vla-EndUndoMark doc) (setq undo nil) ) ) (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*" ) ) ) (princ (strcat "\nОшибка: " msg)) ) (princ) ) ;; Начало группы UNDO (vla-StartUndoMark doc) (setq undo T) (princ "\nВыберите многострочные тексты MText рамкой или по одному: " ) ;; Выбираются только MTEXT (setq ss (ssget "_:L" '((0 . "MTEXT")) ) ) (if ss (progn (setq i 0 objlist nil) ;;------------------------------------------------------ ;; Первый проход: ;; 1. убираем \P ;; 2. отключаем колонки ;; 3. сильно расширяем MText, чтобы исчез автоперенос ;;------------------------------------------------------ (repeat (sslength ss) (setq en (ssname ss i)) (setq obj (vlax-ename->vla-object en)) (setq txt (MT1:CleanString (vla-get-TextString obj) ) ) ;; Высота текста из DXF группы 40 (setq h (cdr (assoc 40 (entget en)) ) ) (if (or (null h) (<= h 0.0)) (setq h 1.0) ) ;; Записываем текст без переводов строк (vla-put-TextString obj txt) ;; Если у MText включены колонки - отключаем (if (vlax-property-available-p obj 'ColumnType T ) (vlax-put-property obj 'ColumnType 0) ) ;; Временная очень большая ширина. ;; Нужна, чтобы убрать автоматические переносы. (setq big (max (vla-get-Width obj) (* h (+ 20.0 (* 2.5 (strlen txt)) ) ) ) ) (vla-put-Width obj big) (vla-Update obj) ;; Сохраняем объект для второго прохода (setq objlist (cons (list obj h) objlist ) ) (setq cnt (1+ cnt)) (setq i (1+ i)) ) ;; Пересчитываем геометрию (vla-Regen doc 0) ;;------------------------------------------------------ ;; Второй проход: ;; уменьшаем ширину рамки до фактической длины строки ;;------------------------------------------------------ (foreach item objlist (setq obj (car item)) (setq h (cadr item)) (if (vlax-property-available-p obj 'ActualWidth ) (progn (setq aw (vlax-get-property obj 'ActualWidth) ) (if (> aw 0.0) ;; небольшой запас, чтобы AutoCAD снова ;; не перенёс последний символ на новую строку (vla-put-Width obj (+ aw (* h 0.20)) ) ) ) ) (vla-Update obj) ) (vla-Regen doc 0) (princ (strcat "\nГотово. Обработано MText: " (itoa cnt) ) ) ) (princ "\nMText не выбраны.") ) ;; Конец группы UNDO (if undo (progn (vla-EndUndoMark doc) (setq undo nil) ) ) (princ) ) (princ "\nКоманда загружена. Введите MT1LINE.") (princ)

Как использовать

Сохраните код, например, как MT1LINE.lsp. В AutoCAD выполните APPLOAD / ПРИЛОЖЗАГР, загрузите LSP и в командной строке введите:

text
MT1LINE

После этого можно выбирать MText обычным способом: рамкой, секущей рамкой или по одному. Например:

text
мтекст много строк

превратится в:

text
мтекст много строк

При этом каждый выбранный объект остаётся отдельным MText, то есть три выбранных MText не объединяются между собой.

Код специально не просто удаляет \P, но и увеличивает ширину каждого MText, потому что в AutoCAD текст может быть многострочным даже без \P — просто из-за узкой рамки. Именно это соответствует показанному на вашем рисунке.

Chia sẻ Q&A này