☰
AutoCAD 2023 AutoLISP二次开发:可运行源码实战教程
2026/10/20 22:23:37 网站建设 项目流程

简介:Auto CAD 2023教程资源定位明确,面向建筑设计、机械制图、工程制图等领域的初学者及需要升级软件版本的从业者,重点解决新版功能不熟悉与安装流程易出错的问题。内容系统讲解智能追踪增强、标记导入与标记辅助、计数功能与浮动窗口等新特性:智能追踪增强借助改进算法,在绘图时实现更精准的对齐定位;标记辅助可快速将外部数据导入绘图环境;计数功能通过简单三步即可统计图纸中特定元素的数量;浮动窗口支持灵活调整界面布局,便于多任务并行。这些特性覆盖绘图定位、数据导入、元素统计和界面管理四大高频场景。每个功能均配有详细操作步骤与技巧提示,读者可边学边练,快速上手。安装部分提供从软件包下载到安装完成的全流程图文说明,显著降低新手入门门槛,即使零基础用户也能独立完成。压缩包共4个文件,体量仅9KB,以两个HTML说明文档为主体,分别对应下载引导与主教程,另含一个inscode可运行示例片段和一个gitignore配置忽略文件,结构清晰,适合在各类设备上直接打开阅读。目前已有53人学习下载,适合作为快速上手的随身参考资料,用于日常查阅或系统学习均很实用;资料体量轻盈,却浓缩了功能详解、操作要点与安装指引,性价比高。

1. Auto CAD 2023 教程为什么把「可运行源码」当核心卖点:先跑起来再弄懂原理

画图顺手的人,第一次遇到“把图纸里 A 层的几千个对象全部挪到 B 层”这种需求时,通常会在图层管理器里筛选手动改,改到一半眼就花了。反倒是 AutoCAD 自带脚本接口这条老路,能用一段加载即用的 AutoLISP 源码把这类批量操作变成一条自定义命令。标题里“可运行源码”说的就是这种事:它不是要你从头学一门语言,而是给你一份能直接放进去跑的工具,跑通了再回头看逻辑。

这类教程适合已经会画图、但困在重复劳动里的从业者,也适合刚接触 CAD 二次开发、不想一上来就啃 .NET API 重装备的同学。用 AutoLISP 起步的理由很实在:Auto CAD 2023 命令行自带 LISP 解释器,交互式强、没有编译环境要求,你不需要装 Visual Studio 也能在十分钟内看到第一段源码生效。难点从来不是语法,而是“先让一段代码在 2023 上跑起来,再谈改造”。

2. 把 Auto CAD 2023 的源码跑起来:命令行粘贴、APPLOAD 与启动组三条加载路径

源码写出来不跑起来就是一堆文本。在 Auto CAD 2023 里加载 AutoLISP 源码有常见的三条路径,按场景选:临时验证用命令行直接粘贴,正式脚本用 APPLOAD 加载 .LSP 文件,长期工具放启动组。下面把三条路径的细节和参数一次说清。

2.1 最快速验证:在 Auto CAD 2023 命令行直接粘贴 AutoLISP 表达式

打开任意一张图纸,在命令行输入下面这行内容,回车:

(vl-load-com) (setq myName "第一段可运行源码") (princ (strcat "已加载变量,内容是: " myName))

回车后命令行会回显“已加载变量,内容是: 第一段可运行源码”。这里第一行(vl-load-com)是把 Visual LISP 的 ActiveX 扩展加载进来,后面所有用到vla-系列函数的源码都依赖它;第二行setq是赋值,把字符串存到变量myName里;第三行princ加strcat是输出拼接后的文本。

这种粘贴方式适合验证单条表达式是否成立。注意两个细节:一是表达式要能在单行内结束,括号必须成对,Auto CAD 2023 的命令行不是完整代码编辑器,多行粘贴只认第一行;二是中文输入法下容易把括号和引号打成全角,全角符号会让 LISP 直接报“malformed list”。我一般会在英文输入法下粘贴,或者先在记事本里写好再整体贴入。

2.2 正式用法:APPLOAD 加载 .LSP 文件与安全设置

表达式验证通过后,就该把源码保存成文件。最常见的做法是在记事本里写好,存成.lsp结尾的文件,然后在 Auto CAD 2023 命令行输入APPLOAD回车,弹出加载/卸载应用程序对话框,选中文件点“加载”,命令行会提示“已成功加载”。

这里有一个新手必踩的设置:Auto CAD 2023 默认会对来自不可信位置的 LISP 文件做安全拦截。如果你从网上下载源码,或者把文件放在临时目录,加载时可能弹安全警告,甚至直接阻止加载。常见的处理是先把源码目录加入可信路径,而不是一上来就关闭安全机制。相关系统变量有三个:

系统变量默认值作用与建议
SECURELOAD1控制是否只加载可信位置的 LISP。0 表示全部放行,1 表示仅放行可信位置,2 表示加载时强制要求信任
TRUSTEDPATHS空逗号分隔的目录列表,Auto CAD 2023 只信任这些目录下的代码文件
ACADLSPASDOC0控制 acad.lsp 是否随每个文档加载。0 仅首个文档,1 每个文档都加载

我一般会把自用脚本统一放到一个不带空格的目录,比如D:/LISP/,然后把D:/LISP/加入 TRUSTEDPATHS,SECURELOAD 保持默认。这样日常加载不会弹窗,也没有把安全机制全部关掉的风险。

2.3 随 CAD 2023 自动加载:启动组与 acad.lsp 的取舍

如果某个工具每天都用,每次开图都手动 APPLOAD 就很烦。在“加载/卸载应用程序”对话框右下角有一个“内容”按钮,点开后把 .LSP 文件加进“启动组”,Auto CAD 2023 每次启动时就会自动加载启动组里的文件,而且对每个新开的文档都生效。

另一种做法是放acad.lsp或acaddoc.lsp到支持文件搜索路径,但这两个文件受 ACADLSPASDOC 和安全机制影响,行为不如启动组直观。对于教程场景,我会优先推荐启动组:它不要求改系统变量,添加和移除都比较可视化,适合作为从“手动加载”到“自动加载”的过渡方案。

三条加载路径可以这样对比:命令行粘贴最快但只适合单条验证;APPLOAD 适合开发和测试阶段;启动组适合正式工具。核心判断标准只有一个——这个源码你打算用一次,还是打算长期用。

3. AutoLISP 在 CAD 2023 里的核心机制:变量、函数与 command 调用,源码不是黑匣子

很多人看到 LISP 源码第一反应是“括号套括号,根本读不懂”。其实 AutoLISP 在 CAD 二次开发里要掌握的核心机制并不多,真正天天用的就是变量、函数、command 调用和选择集四样。把这四样看明白,标题里的“可运行源码”就不再是黑匣子。

3.1 变量与数据类型:字符串、点表与图元名

AutoLISP 的变量用setq赋值,没有类型声明,类型由值决定。实际写代码时最常碰到的三类数据是字符串、点表和图元名,看下面这段:

(setq layerName "A层") (setq pt1 (list 10.0 20.0)) (setq ent (entlast))

layerName是字符串,在 LISP 里必须用英文双引号包起来;pt1是一个点表,(list 10.0 20.0)表示 X 坐标 10.0、Y 坐标 20.0,三维点就再加一个 Z 值;ent是图元名,entlast返回图纸里最后一个对象的图元名,通常用于“刚画完就拿到它”的场景。

字符串操作里高频函数是strcat拼接和strcase转大小写。点表操作最常用的是car取 X、cadr取 Y。图元名则会配合下一章的vla-系列 ActiveX 函数使用。数据类型搞混是最常见的报错来源,比如拿字符串去做加法,Auto CAD 2023 会提示bad argument type。

3.2 用 command 调起 CAD 2023 原生命令:让源码替你干活

AutoLISP 最讨巧的一点是能直接调用 CAD 原生命令,写法是:

(command "_.LINE" (list 0 0) (list 100 50) "") (command "_.-LAYER" "_M" "NEWLAYER" "")

第一行画一条从 (0,0) 到 (100,50) 的直线,末尾空字符串表示结束命令;第二行创建一个叫 NEWLAYER 的图层。注意两个细节:命令名前面加下划线_,是为了在任何语言版本的 CAD 里都能识别;图层命令写成_.-LAYER而不是_.LAYER,是强制走命令行版本而不是弹出对话框。

这条机制的价值在于:你不用记住每个功能的底层 API,只要能用命令行手动作出来的操作,理论上都可以用command在源码里重现。但这里有个经验:在批量循环里尽量少用command,因为它会触发命令行回显,而且如果中间命令弹了对话框,脚本可能卡住。更可控的做法是用 ActiveX 的vla-函数直接改对象属性,下面章节会看到。

3.3 选择集与遍历:让源码知道图纸里有什么

批量操作的前提是拿到一批对象。AutoLISP 里用ssget构造选择集,用ssname按索引取对象,用sslength取数量。最常用的是带过滤器的方式:

(setq sel (ssget "X" (list (cons 8 "A层")))) (princ (strcat "\nA层对象数量: " (itoa (sslength sel))))

这里"X"表示全图搜索,第二个参数是过滤条件,(cons 8 "A层")的意思是“图层名为 A 层”,8 是图层这个属性的 DXF 组码。如果想再加一个类型过滤,比如只选 A 层上的单行文字,可以写成(list (cons 8 "A层") (cons 0 "TEXT"))。

拿到选择集之后,遍历就是固定套路:

(setq i 0) (repeat (sslength sel) (setq ent (ssname sel i)) (setq obj (vlax-ename->vla-object ent)) (princ (strcat "\n对象类型: " (vla-get-ObjectName obj))) (setq i (1+ i)))

vlax-ename->vla-object是把普通图元名转换成 ActiveX 对象,转换之后才能用vla-get-和vla-put-系列函数读取和修改属性。这个组合是后面所有批量脚本的骨架。

3.4 自定义函数与 C: 前缀:从函数变成命令行命令

源码要变成“可运行”,通常得把一段逻辑包成函数,并且让 Auto CAD 2023 把函数注册成命令。写法就是用defun定义函数,函数名以C:开头:

(defun c:Hello ( / msg) (setq msg "命令已触发") (princ msg))

定义之后,在命令行输入Hello就能运行。c:这个前缀是 Auto CAD 2023 识别自定义命令的约定,去掉它就不是命令,只能像普通函数一样用(Hello)调用。括号里斜杠/后面的msg是局部变量,声明成局部变量可以避免函数运行后污染全局命名空间,这是写长脚本时保持环境干净的重要习惯。

每个命令函数最后一行一般放一个(princ),作用是静默退出,否则命令行会回显上一个表达式的值,影响观感。这些小习惯累积起来,源码才会从“能跑”变成“好维护”。

4. 一套能直接复用的 Auto CAD 2023 源码骨架:批量归并图层与文字改前缀

掌握了变量、command、选择集、函数定义这些基础后,就可以拼出一套真正有实用价值的源码。下面给出一套可以直接复制到 .LSP 文件里运行的工具,包含两个命令:批量归并图层和批量给文字加前缀。这两个功能覆盖了最常见的“重复劳动”场景。

4.1 批量归并图层:完整源码与关键参数说明

把 A 层所有对象移到 B 层并删除 A 层,是施工图整理时的刚需。完整源码如下,保存为laymerge.lsp后加载即可:

(vl-load-com) (defun c:LayMerge ( / acadObj doc layers oldName newName sel i ent entObj delResult) (setq acadObj (vlax-get-acad-object)) (setq doc (vla-get-ActiveDocument acadObj)) (setq layers (vla-get-Layers doc)) (setq oldName (strcase (getstring T "\n输入要归并的源图层名: "))) (setq newName (strcase (getstring T "\n输入目标图层名: "))) (if (= oldName newName) (progn (princ "\n源图层与目标图层同名,程序退出。") (exit))) (if (not (tblsearch "LAYER" oldName)) (progn (princ "\n源图层不存在,程序退出。") (exit))) (if (not (tblsearch "LAYER" newName)) (vla-add layers newName)) (if (setq sel (ssget "X" (list (cons 8 oldName)))) (progn (setq i 0) (repeat (sslength sel) (setq ent (ssname sel i)) (setq entObj (vlax-ename->vla-object ent)) (vla-put-Layer entObj newName) (setq i (1+ i))) (princ (strcat "\n已迁移 " (itoa i) " 个对象到图层 " newName))) (princ "\n源图层上没有对象,直接尝试删除图层。")) (if (= (strcase (getvar "CLAYER")) oldName) (setvar "CLAYER" newName)) (setq delResult (vl-catch-all-apply (function (lambda () (vla-delete (vla-item layers oldName)))) nil)) (if (vl-catch-all-error-p delResult) (princ "\n源图层删除失败,请检查是否有块内引用。") (princ "\n源图层已删除。")) (princ))

逻辑说明:程序先取当前文档和图层集合,然后读取两个图层名。tblsearch用来检查图层是否真实存在,如果目标图层不存在就先用vla-add创建。ssget "X"配合(cons 8 oldName)把源图层全部对象选出来,逐个用vla-put-Layer改到目标图层。删除源图层前,如果源图层正好是当前图层,要先setvar "CLAYER"切走,否则 CAD 不允许删除当前图层。删除操作用vl-catch-all-apply包一层,是为了捕获“图块内部引用该图层”“0 层不可删”这类异常,避免程序直接崩溃。

参数说明:getstring T里的T表示允许输入包含空格,因为图层名可能叫“A-1 外墙”这种带空格的名字;strcase把所有输入转成大写,避免用户大小写混用导致匹配失败;ssget "X"是全图过滤,只过滤图层名时效率仍然很高,如果图纸特别大可以改成(ssget "W" pt1 pt2 (list (cons 8 oldName)))指定窗口范围。

4.2 按需改造:给文字批量加前缀的源码样板

归并图层的代码骨架确定后,改造成其他批量需求就快了。下面这段是给单行文字批量加前缀的命令:

(defun c:TextPrefix ( / ss n i ent obj) (princ "\n选择要加前缀的单行文字: ") (if (setq ss (ssget '((0 . "TEXT")))) (progn (setq i 0) (setq n (sslength ss)) (repeat n (setq ent (ssname ss i)) (setq obj (vlax-ename->vla-object ent)) (vla-put-TextString obj (strcat "P-" (vla-get-TextString obj))) (setq i (1+ i))) (princ (strcat "\n已完成,共处理 " (itoa n) " 个文字对象。"))) (princ "\n没有选中文字。")) (princ))

这里用ssget的交互式选择,不传第一个参数,让用户自己在屏幕上框选;过滤器((0 . "TEXT"))只选单行文字,避免把多行文本和标注也卷进来。vla-get-TextString读取现有文字内容,strcat拼上前缀,再vla-put-TextString写回。整个遍历过程和 4.1 里的归并图层是同一个套路。

如果要把这个命令扩展到多行文字,可以把过滤器改成(0 . "MTEXT"),但注意 MTEXT 内容里可能带格式代码,比如颜色和字体控制符,直接加前缀有可能插进格式串里。我一般会先跑一次只选 TEXT 的版本,确认效果后再单独处理 MTEXT 这种特殊对象。

4.3 源码加载后的三种验证方式:看命令行、看图层管理器、看对象属性

代码写完了不是说加载成功就完了。我跑功能前习惯做三步验证:第一步,命令行输入命令名,看提示信息是否符合预期;第二步,打开图层管理器,确认源图层是否删除、对象是否到了目标图层;第三步,用LIST命令点选一个刚才被处理过的对象,看它的图层和文字属性是不是真的变了。

第三步最容易被忽略。有些脚本表面成功,实际上属性没改到,原因往往是过滤器写错,比如图层名大小写不一致、对象类型组码写错。Auto CAD 2023 的LIST能看到对象底层的全部属性,这是判断“源码是不是真的干活了”的最可靠手段。

5. Auto CAD 2023 二次开发避坑指南:5 个最容易翻车的点

加载源码和写源码是两件事,翻车点也完全不同。下面这 5 条是我在带新人做 CAD 二次开发时遇到频率最高的问题,每条按“现象、原因、解决”梳理,值得先看一遍再动手。

5.1 命令名找不到:加载成功但输入命令提示“未知命令”

现象:APPLOAD 提示加载成功,文件路径也对,但命令行输入LayMerge却说“未知命令”。

原因:最常见的是函数名没加C:前缀。Auto CAD 2023 只把以C:开头的函数注册成命令,(defun LayMerge ...)只能通过(c:LayMerge)调用,不能直接在命令行输入。另一种情况是文件里有语法错误,LISP 解释器执行到一半中断,后面的defun根本没被求值,但 APPLOAD 的“成功”提示只看文件有没有被读取,不检查函数是否完整定义。

解决:检查defun名字是否为c:LayMerge;在文件末尾加一行(princ "\n命令加载完成"),如果这行没出现,就说明前面有语法错误,逐段注释排查。

5.2 全角符号与括号不配对:malformed list 是最常见报错

现象:加载 .LSP 文件时命令行直接报malformed list,或者extra right paren。

原因:绝大多数是中文输入法惹的祸。LISP 语法里括号、双引号、分号注释都必须用英文半角字符,中文输入法下很容易打出全角括号()、全角引号“”,Auto CAD 2023 会把它们当作普通内容而不是语法符号,括号配平立刻被破坏。

解决:代码编辑全程切英文输入法,尤其是写注释时,注释用;开头,注释内容里的中文没问题,但注释开头那个分号必须是半角。另外建议用支持括号高亮和配对的编辑器写代码,保存时如果括号配平有问题,编辑器会直接标红,不需要等 CAD 报错。

5.3 源图层删不掉:图层明明没对象却提示删除失败

现象:4.1 的归并脚本跑完,提示“源图层删除失败”,但图层管理器里看该图层确实没有直接对象。

原因:最常见的原因是图块定义内部引用了这个图层。ssget "X"只能抓到模型空间和图纸空间里的对象,抓不到块定义里的几何图元。如果某个块在定义时用到了 A 层,即使图上没有块实例,A 层也会被视为“被引用”,禁止删除。另外,0 层在设计上是不可删除层,当前图层也不能删。

解决:先确认源图层不是 0 层、不是当前层;然后针对块引用,暂时不追求删除,而是在命令里加提示“仍有块内引用”。更彻底的做法是先PURGE掉没用到的块定义再删图层,但这对脚本复杂度的提升比较大,教程场景下建议先保留提示机制。

5.4 安全设置拦截:加载文件时弹窗或提示“已阻止加载”

现象:加载自己写的 .LSP 文件时,Auto CAD 2023 弹出安全警告,有时点“加载”也不生效,命令始终找不到。

原因:SECURELOAD 设置为 1 或 2 时,CAD 只加载位于 TRUSTEDPATHS 里的 LISP 文件。把文件放在桌面、下载目录或 U 盘里,都默认不可信。

解决:打开OPTIONS,在“文件”选项卡里找到“受信任的位置”,把源码目录加进去;或者命令行执行SETVAR SECURELOAD 0临时放行。注意不要为了省事直接清零,尤其是要从外部获取源码时,保持默认安全级别、只添加可信目录,才是稳妥做法。

5.5 批量循环中途按 ESC:没有error处理会留后患

现象:批量脚本跑到一半,手误按了 ESC,命令中断;后续手动画图时发现捕捉模式、图层状态和之前不一样,甚至命令行回显开着,操作界面变得很奇怪。

原因:AutoLISP 里如果脚本修改过系统变量,比如开/关CMDECHO、切过当前图层,中途被 ESC 打断,后面的“恢复原状”代码就不会执行。这些系统变量停留在半路状态,直接影响后续手工操作。

解决:在每个命令开头先把要改的系统变量保存到局部变量,定义*error*函数,在出错或中断时把变量恢复回去。格式是:

(defun *error* (msg) (setvar "CMDECHO" 1) (setvar "CLAYER" oldLayer) (princ msg))

*error*是 Auto CAD 2023 预留的异常入口,只要命令被 ESC 打断或报错,都会执行它。这个习惯看着不起眼,但能避免大量“说不清哪里坏了”的玄学问题。

6. 让这套源码更顺手:面板按钮封装、防错设置与文件维护习惯

到这里,源码已经能在命令行跑通。更进一步,就是把自定义命令封装到功能区面板,同时建立两个值得长期保持的维护习惯,让这套工具在项目里真正沉淀下来。

6.1 用 CUI 把自定义命令挂到功能面板

每次输入命令名还是不够快。在 Auto CAD 2023 里输入CUI回车,进入自定义用户界面窗口,左侧选“命令列表”,新建命令,名称填“归并图层”,宏填:

^C^C^P(load "D:/LISP/laymerge.lsp")LayMerge

^C^C是连按两次 ESC,取消当前命令;^P是关闭命令行回显;load每次点击都重新加载一次源码文件,好处是修改源码后按按钮立即生效,不用手动 APPLOAD。之后把这个按钮拖到功能区面板的自定义选项卡里即可。注意宏里路径不要带空格,否则load会被截断,源码文件放在无空格目录能省掉这个麻烦。

6.2 两个值得长期保持的源码维护习惯

第一个习惯是给每个文件头部写版本注释。格式很简单,三五行就行:

;; 文件名: laymerge.lsp ;; 用途: 批量归并图层并删除源图层 ;; 修改记录: 2025-01-10 增加块内引用提示

CAD 二次开发的代码没有编译期保护,改坏一个括号就全盘报错,版本注释是唯一能让人快速定位“上次改了什么”的线索。第二个习惯是改代码前先备份图纸,任何批量操作都只在副本上先跑一遍。AutoLISP 的操作不可撤销,尤其归并图层这种功能,一旦把图层合错,Ctrl+Z 不一定救得回来。

最实用的教训是:不要把“代码能跑”当成终点,而要把“代码在什么条件下不能跑”也写进注释里。删除源图层失败、MTEXT 格式串被破坏、安全位置被拦截,这些边界条件都值得记录到文件头部,下次再遇到直接看注释十分钟解决。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询