Autolisp 函数,增量文本或多行文本 +1

问题描述 投票:0回答:2

我不太熟悉 AutoLISP,在编写将文本或多行文本中的数字递增 1 的脚本时遇到问题,最好是所有选定的文本。

(defun c:IncrementTextNumbers (/ ss obj)
  (setq ss (ssget '((0 . "TEXT")(62 . 1))))
  (if ss
    (progn
      (setq obj (ssname ss 0))
      (while obj
        (if (and (= (cdr (assoc 0 (entget obj))) "TEXT")
                 (numberp (atoi (cdr (assoc 1 (entget obj))))))
          (progn
            (setq num (atoi (cdr (assoc 1 (entget obj)))))
            (setq new-num (+ num 1))
            (command "_.CHANGE" obj "" new-num)
          )
        )
        (setq obj (ssname ss (1+ (ssname ss (sslength ss) obj))))
      )
      (princ "\nHighlighted text numbers incremented successfully.")
    )
    (princ "\nNo highlighted text objects found.")
  )
  (princ)
lisp autocad autocad-plugin autolisp
2个回答
0
投票

您应该使用

(entmod )
而不是零钱。还简化了您的示例。试试这个代码。

(defun c:IncrementTextNumbers (/ ss obj)
      (setq ss (ssget '((0 . "*TEXT"))))
      (if ss
        (progn
          (setq index 0)
          (setq obj (ssname ss index))
          (while obj
            (setq content (cdr (assoc 1 (entget obj))))
            (setq num (atoi content))
            (if (numberp num)
              (progn
                (setq new-num (1+ num ))
                (setq ed (entget obj)) 
                (setq ed (subst (cons 1 (itoa new-num)) (assoc 1 ed) ed)) 
                (entmod ed) 
              )
            )
            (setq index(1+ index ))         
            (setq obj (ssname ss index))
          )
          (princ "\nHighlighted text numbers incremented successfully.")
        )
        (princ "\nNo highlighted text objects found.")
      )
      (princ)
)

0
投票

选择集处理

您的代码的主要问题是用于迭代选择集的方法 - 具体来说,这一行:

(setq obj (ssname ss (1+ (ssname ss (sslength ss) obj))))

ssname
函数接受一个选择集和一个索引作为参数;在这里,在最里面的表达式中,您提供了一个选择集 (
ss
)、一个索引 (
(sslength ss)
) 和一个实体名称 (
obj
)。
ssname
还返回一个实体名称,您不能使用
1+
函数增加它。

我建议学习我关于 Selection Set Processing 的教程,以了解迭代选择集的各种方法。

对于这个特定的例子,我可能会使用我的教程中描述的 'reverse repeat' 技术,因为这会产生简洁高效的代码,例如:

(defun c:IncrementTextNumbers ( / idx sel )
    (if (setq sel (ssget "_:L" '((0 . "TEXT,MTEXT"))))
        (repeat (setq idx (sslength sel))
            (setq idx (1- idx)
                ;; ... do stuff ...
            )
        )
    )
    (princ)
)

在这里,你还会注意到我已经按照以下方式修改了

ssget
表达式:

  • "_:L"
    模式字符串排除锁定层上的对象 - 下划线确保使用模式字符串的非本地化版本。
  • 在选择过滤器中使用
    TEXT,MTEXT
    允许用户选择单行文本和多行文本,同时排除
    RTEXT
    .

字符串到数字的转换

首先,我要注意你的程序中的这一行不是必需的:

(= (cdr (assoc 0 (entget obj))) "TEXT")

因为您已经在

TEXT
选择过滤器中过滤
ssget
实体。

其次,你应该知道

atoi
总是无益地返回一个数值,不管输入文本如何,观察:

_$ (atoi "abc")
0

因此,对于所有文本内容,表达式

(numberp (atoi ...))
将始终返回
T

由于在这种情况下您也无法测试非零内容(因为内容可能合法为零),我建议使用

distof
函数将字符串转换为数字(因为此函数将返回
nil 
用于非数字输入),或者如果您想将输入限制为仅整数,则可以使用
wcmatch
函数来测试字符串是否仅包含数字(或者更好的是,将此测试合并到
ssget
选择中过滤器)。

以下是每种方法的示例:

使用

distof

(defun c:IncrementTextNumbers ( / enx idx sel str )
    (if (setq sel (ssget "_:L" '((0 . "TEXT,MTEXT"))))
        (repeat (setq idx (sslength sel))
            (setq idx (1- idx)
                  enx (entget (ssname sel idx))
                  str (cdr (assoc 1 enx))
            )
            (if (distof str 2)
                ;; ... do stuff ...
            )
        )
    )
    (princ)
)

使用

wcmatch
(测试正整数)

(defun c:IncrementTextNumbers ( / enx idx sel str )
    (if (setq sel (ssget "_:L" '((0 . "TEXT,MTEXT"))))
        (repeat (setq idx (sslength sel))
            (setq idx (1- idx)
                  enx (entget (ssname sel idx))
                  str (cdr (assoc 1 enx))
            )
            (if (wcmatch str "~*[~0-9]*")
                ;; ... do stuff ...
            )
        )
    )
    (princ)
)

使用

ssget
过滤器(测试正整数

(defun c:IncrementTextNumbers ( / enx idx sel str )
    (if (setq sel (ssget "_:L" '((0 . "TEXT,MTEXT") (1 . "~*[~0-9]*"))))
        (repeat (setq idx (sslength sel))
            (setq idx (1- idx)
                  enx (entget (ssname sel idx))
                  str (cdr (assoc 1 enx))
            )
            ;; ... do stuff ...
        )
    )
    (princ)
)

使用
entmod
代替命令

最后,您可以使用

entmod
直接修改图形数据库的内容,而不是使用 AutoCAD 命令执行此操作(这更慢且不太可靠,因为您依赖于提示的顺序保持不变在 AutoCAD 版本之间)。

考虑以下代码:

(defun c:IncrementTextNumbers ( / enx idx itm sel )
    (if (setq sel (ssget "_:L" '((0 . "TEXT,MTEXT") (1 . "~*[~0-9]*"))))
        (repeat (setq idx (sslength sel))
            (setq idx (1- idx)
                  enx (entget (ssname sel idx))
                  itm (assoc 1 enx)
            )
            (entmod (subst (cons 1 (itoa (1+ (atoi (cdr itm))))) itm enx))
        )
    )
    (princ)
)
© www.soinside.com 2019 - 2024. All rights reserved.