
简介面向钢结构详图设计与TEKLA二次开发初学者的一套图纸入门源代码围绕模型图纸列表载入、图纸选择、图纸打开及图纸数值提取等基础环节展示如何借助TEKLA API与C#把重复操作转为可复用的自动化流程。压缩包共20个文件约74KB以cs源代码为主配有resx资源、sln解决方案、csproj项目文件以及config、settings等配置项构成可直接在Visual Studio中查阅的入门工程便于对照理解界面窗体、事件处理与数据读取的组织方式。已有793人学习适合作为熟悉TEKLA对象模型、补齐WinForms交互与API调用思路的练习素材也能为后续定制图纸管理和数据提取工具提供参考。1. 先弄明白TEKLA二次开发到底在开发什么TEKLA二次开发这个词新手十有八九会把它和「学 Tekla 建模」搞混。建模是你握着鼠标一根梁一根柱地摆二次开发是写段程序让软件替你去摆、去改、去出图。这次看的资源主题是图纸入门附带了能直接跑起来的源代码——图纸就是 Tekla 出零件图、构件图那套功能源代码是别人写好、你能打开看懂再改成自己用的示例程序。最容易卡住新手的不是技术是心理一看「开发」「源代码」就以为得先把算法啃完。入门阶段用到的编程其实大多是「找到对象、改个属性、保存」这种朴素动作。这份资源要解决的就是把「鼠标点一百遍」换成「代码跑一遍」。适合每天重复出图的人、想给团队做小工具的人以及完全没写过代码但愿意花几个晚上试试的人。2. 为什么值得学把重复画图的时间省回来2.1 图纸岗的重复劳动到底重复在哪把一张构件图从模型状态变成能发出去的成品中间的动作拆开看是这样的选图纸类型和属性、调视图比例、挪视图位置、补标注、改标题栏、核对尺寸链、导 PDF。单看每一步都不难难在次数——一张图要点几十下鼠标一套项目几十上百张图加起来就是好几天。更麻烦的是「改一次」。截面换了、构件编号变了、轴线调了模型一改图纸要么重新出、要么手工调回来前面那些点击全部作废。这种活儿不烧脑但极其消耗耐心时间长了人会变得很机械。二次开发的切入点恰恰在这里凡是规则固定、每次做法都一样的动作就适合写成代码。你不必一上来就想着「做个大系统」先盯着一天里重复次数最多的那一个动作把它自动化收益就已经很实在了。判断一件事值不值得写代码我一般看两个条件第一这件事下次还会做而且不止一次第二这件事的规则能用一句话说清楚比如「所有构件图的标题栏第二行改成项目名」。两个条件都满足写代码就是赚的只要有一个不满足比如就这一次、或者规则每次都不一样手点反而更快。2.2 会写几行代码的详图员和只会点鼠标的详图员差在哪先说清楚这不是抢饭碗。写代码的人依然要懂图纸规范、懂出图习惯因为代码里那些规则是你定的软件不会替你判断「这张图该不该剖」。区别在于产能的上限只会点鼠标的人产能受限于手速和耐心会用代码的人产能受限于「你想清楚了没有」。具体能做的事入门阶段就能摸到的有这么几类批量改标题栏比如项目名、图号前缀、日期一次改完整个模型的图纸。批量调视图比例和位置让一批构件图的排版统一。出图前自动检查比如某个视图里有没有漏掉的零件标注。按命名规则自动出图构件编号一到手就生成对应图纸。批量导出 PDF 或 DWG省掉一张张点导出的时间。这些事情的代码内核都不复杂无非是「循环 判断 改属性」。真正需要经验的地方在于你得先手工把这件事做对一遍才知道代码该按什么顺序做。跳过手工这一步直接写代码八成写出来的东西不符合出图规范。反过来说也要认清一件事不是所有活儿都适合自动化。一次性任务、规则天天变的任务、需要大量人工判断美不美观的任务写代码的投入产出比很低。入门阶段最常见的翻车就是花两个星期写了个工具结果那个流程下个月就不用了。血泪经验就一句话先做最枯燥、最重复、规则最死的那一个。2.3 零基础要付出的成本三个真实门槛说「零基础也能学」不是画饼但也不能假装没门槛。老实讲需要跨过去的有三道。第一道是编程语言。Tekla Open API 是一套 .NET 接口主流写法是 C#所以要跟 Visual Studio 打交道。好消息是入门不需要学完一整本 C# 教材掌握类、对象、方法、循环、if 判断、List 这几个概念就够你跑通第一个例子了。LINQ、异步、委托、设计模式这些等你真的遇到问题了再补完全来得及。第二道是看懂 API 帮助文档。Tekla 安装时会附带一份开发帮助文档里面按「命名空间 → 类 → 属性/方法」的层级组织。新手第一次打开会懵因为目录树长得吓人。实际用法很朴素你想改标题栏就在文档里搜 Title你想拿图纸列表就搜 DrawingHandler。带着具体问题去搜比从头读到尾效率高十倍。第三道是理解 Tekla 自己的对象模型这一道最容易被低估。模型侧有零件、构件、梁、柱这些概念图纸侧有图纸、视图、图纸对象这些概念两边是两套东西。代码里如果搞混了「模型里的零件」和「图纸里的零件」结果就是一片 null 和类型转换异常。第 4 章会专门把这三层结构拆开讲。至于数学入门阶段真不用太担心。几何计算 API 基本帮你做完了你需要提供的是坐标点、方向向量这种直白的东西很少需要自己推公式。真正卡人的往往不是数学而是「不知道这个方法叫什么名字」。3. 动手前的准备环境、语言和第一段能跑的代码3.1 装什么一份能跑起来的最小环境清单先把环境凑齐别急着写逻辑。新手最常见的开局失败不是代码错而是环境没对报一堆找不到程序集的错误人直接劝退。需要准备的东西如下需要的东西作用新手注意点Tekla Structures 本体提供模型和图纸运行环境必须能正常打开一个模型Tekla Open API 的 DLL代码调用的接口库随软件安装在安装目录下Visual Studio写代码、调试社区版完全够用.NET Framework 目标框架运行环境版本要和 API 的要求对上一个测试模型练手用千万别拿正式项目试引用 DLL 这一步是重点。在 Visual Studio 里新建一个「类库.NET Framework」或「控制台应用」项目然后右键引用 → 添加引用 → 浏览到你本机 Tekla 安装目录下找以 Tekla.Structures 开头的几个 DLL通常至少要引入这几个Tekla.Structures.dll基础类型和通用工具Tekla.Structures.Model.dll模型侧的一切Tekla.Structures.Drawing.dll图纸侧的一切Tekla.Structures.Geometry3d.dll点、向量、坐标系Tekla.Structures.Plugins.dll如果要做成 Tekla 里的按钮提示加完引用后把这几个 DLL 的「复制到本地」属性设为 False。它们应该由 Tekla 自己提供跟着你的程序复制一份出去版本一乱就会在客户机器上报错。还有一个特别容易忽略的点你引用的 DLL 版本必须和本机安装的 Tekla 版本一致。两台电脑装的软件版本不同同一份代码在一台机器上跑得好好的换台机器就抛异常这类问题排查起来非常费劲属于典型的「玄学故障」。团队协作的话开工前先把版本统一能省掉后面无数扯皮。3.2 第一段代码连上模型把图纸名字打出来第一个例子别追求有用追求「能跑通」。这里选的目标是连上当前打开的模型把它里面所有图纸的名字打印出来。代码很短但它把开发里最核心的三件事串起来了——连上软件、拿到对象集合、遍历。新建一个控制台项目把下面这段贴进去using System; using TSD Tekla.Structures.Drawing; // 图纸相关起别名避免和模型侧重名 using TSM Tekla.Structures.Model; // 模型相关 namespace DrawingDemo { class Program { static void Main(string[] args) { // 第一步确认 Tekla 已经打开并且加载了模型 TSM.Model model new TSM.Model(); if (!model.GetConnectionStatus()) { Console.WriteLine(没连上模型先把 Tekla 打开并加载一个模型); return; } // 第二步拿到图纸处理器它是操作图纸的总入口 TSD.DrawingHandler handler new TSD.DrawingHandler(); // 第三步取出当前模型里的所有图纸得到一个枚举器 TSD.DrawingEnumerator drawings handler.GetDrawings(); int count 0; while (drawings.MoveNext()) { TSD.Drawing drawing drawings.Current; count; // Name 是图纸名Title1/Title2/Title3 是标题栏里的三行标题 Console.WriteLine(${count}. {drawing.Name} | {drawing.Title1} | {drawing.Title2}); } Console.WriteLine($一共 {count} 张图纸); } } }这段代码的逻辑是一条直线。Model代表模型这一侧GetConnectionStatus()返回一个布尔值告诉你当前有没有连上正在运行的 Tekla 进程这一步必须放在最前面因为后面所有操作都依赖它。DrawingHandler是图纸侧的总入口你可以把它理解成图纸模块的管理员取图纸、存图纸、切换当前图纸都通过它。GetDrawings()返回的是一个DrawingEnumerator这东西不能像数组那样用下标取只能反复调用MoveNext()往后走一格Current就是当前那张图纸。参数上唯一需要留意的是Title1、Title2这类属性它们对应图纸标题栏里从上往下的几行文字具体哪一行显示在图纸的哪个位置取决于你用的图纸模板。第一次跑的时候如果发现某张图纸的标题是空的不用怀疑代码多半是那张图本身就没填。跑通之后建议做个小改动练手把输出改成只打印图纸名以某个前缀开头的那些。别小看这个改动它让你第一次体会到「过滤」这件事怎么写而过滤在真实工具里用得极多。3.3 从控制台到按钮把代码变成 Tekla 里的一个命令控制台程序能跑通逻辑但对同事不友好——总不能让人家先装个 Visual Studio。真正好用的形态是把它做成 Tekla 里的一个按钮点一下就执行。Tekla 的插件有一套固定骨架继承PluginBase加上两个特性标注然后实现Run方法。最小可运行的结构大概是这样using System.Collections.Generic; using Tekla.Structures.Plugins; using TSD Tekla.Structures.Drawing; namespace DrawingDemo { // 第一个特性决定这个插件叫什么名字会显示在 Tekla 的插件列表里 [Plugin(图纸小助手)] // 第二个特性指向参数输入界面的定义没有界面时按项目模板给个占位值 [PluginUserInterface(DrawingDemo.UserInterface)] public class DrawingCountPlugin : PluginBase { // Tekla 会通过这个构造函数把参数传进来无参场景下可以留空 public DrawingCountPlugin(string data) { } // Run 就是点按钮之后真正执行的入口 public override bool Run(ListInputDefinition parameterList) { TSD.DrawingHandler handler new TSD.DrawingHandler(); TSD.DrawingEnumerator drawings handler.GetDrawings(); int count 0; while (drawings.MoveNext()) { count; } // 用消息框把结果告诉用户比控制台友好 System.Windows.Forms.MessageBox.Show($当前模型共有 {count} 张图纸); return true; } } }[Plugin]里的字符串就是按钮在软件里显示的名字改成中文完全没问题。Run的返回值是布尔值返回 true 表示执行成功Tekla 会照常结束这次调用返回 false 通常意味着中途出了状况。parameterList是用户在界面上填的参数这个例子里没有界面所以用不到它。代码写完之后要编译成 DLL然后把 DLL 放到当前模型目录下的 plugin 文件夹里回到 Tekla 里刷新一下「应用程序和组件」列表按钮就出现了。注意插件 DLL 是跟着模型目录走的不是跟着软件安装目录走。换个模型就找不到按钮这不是 bug把 DLL 复制到新模型的 plugin 目录即可。这一步做完你就拥有了一个「能点」的东西。别急着往里面塞复杂逻辑先确认这个按钮能在同事的机器上也点出来——环境问题在这一步暴露比在代码写到两千行的时候暴露要好得多。4. 图纸入门从模型里的一张零件图开始4.1 先理清图纸的三层结构图纸、视图、对象图纸这块最容易把人绕晕因为「图纸」这个词在日常里既指那张纸也指纸上的内容。在 API 里它是有严格层级的用 Excel 打比方最直观一个工作簿里有很多工作表工作表里有很多单元格。对应过来就是图纸、视图、图纸对象。第一层是图纸本身也就是Drawing。它管的是整张图的属性图纸名、标题栏文字、纸张大小、出图比例这种全局设置。你平时在 Tekla 里点「图纸属性」看到的那个对话框大部分内容对应这一层。第二层是视图也就是View。一张图纸上可以有好几个视图比如一个构件图里同时有立面、剖面、节点大样。视图管的是「从哪里看、看多大、摆在纸上哪个位置」比例和坐标系的设置主要在这一层。第三层是图纸对象也就是DrawingObject的各种子类。视图里画的每一样东西都在这一层零件轮廓、螺栓、尺寸标注、零件标记、文字、线条、矩形框。你在图纸上框选能选中的东西基本都是这一层的对象。三层的关系理清了代码该往哪一层下手就清楚了。改标题栏找第一层调比例找第二层改标注文字找第三层。新手最常见的错误是拿第三层的对象去调第二层的属性编译器不会拦你运行时给你一个空引用然后你盯着代码发呆。顺便把两边的概念对应关系列一下这个表建议存下来你嘴里的说法模型侧Model图纸侧Drawing一根梁Beam视图里的 Part一个构件Assembly不对应图纸层面按图纸类型区分一张图无Drawing 或它的子类图上的一个标注无PartMark、Dimension图上的一段说明文字无Text模型侧和图纸侧是两套独立的命名空间这也是为什么代码开头要用别名把Tekla.Structures.Model和Tekla.Structures.Drawing分开。两边的类名有重叠不区分的话编译器直接报歧义。4.2 造出第一张零件图从选中零件到落盘第二个例子做点更有成就感的事在模型里选中一个零件给它生成一张零件图。流程是先在模型侧找到对象再在图纸侧创建对应的图纸对象最后提交给 Tekla 去生成。using System; using TSD Tekla.Structures.Drawing; using TSM Tekla.Structures.Model; namespace DrawingDemo { class CreateDrawing { public static void Run() { // 1. 从模型里拿用户当前选中的对象 TSM.ModelObjectSelector selector new TSM.ModelObjectSelector(); TSM.ModelObjectEnumerator selected selector.GetSelectedObjects(); if (!selected.MoveNext()) { Console.WriteLine(先在模型里选中一个零件再运行本程序); return; } // 2. 转成零件类型。选中的可能是构件也可能是别的必须判断 TSM.Part part selected.Current as TSM.Part; if (part null) { Console.WriteLine(选中的不是零件请重新选择); return; } // 3. 用零件的 Identifier 构造一张零件图 TSD.SinglePartDrawing newDrawing new TSD.SinglePartDrawing(part.Identifier); // 4. 填标题栏文字这几行会直接显示在图纸上 newDrawing.Name 自动生成示例; newDrawing.Title1 某模拟项目; newDrawing.Title2 part.Name; // 5. 交给 Tekla 真正生成 TSD.DrawingHandler handler new TSD.DrawingHandler(); bool ok handler.CreateDrawings(new TSD.Drawing[] { newDrawing }); Console.WriteLine(ok ? 图纸生成成功 : 图纸生成失败检查图纸属性文件是否存在); } } }第一段里ModelObjectSelector的作用是读取用户在软件界面上的选择GetSelectedObjects()返回的同样是枚举器MoveNext()加Current是老朋友了。这段代码其实隐含了一个很实用的设计思路让用户在界面上选中目标代码只负责处理比在代码里写死一堆查询条件灵活得多。第二段的as转换是新手必须养成的习惯。用户选中的东西理论上可能是任何模型对象直接强转一旦类型不对就抛异常用as加空判断出错时能优雅退出并给出提示这是「能用」和「好用」的分水岭。第三段的Identifier是 Tekla 给每个模型对象分配的唯一编号相当于身份证号。创建图纸时传这个编号而不是传对象本身是因为图纸侧和模型侧是两套系统它们之间靠编号对话。第四段设置Name和Title1、Title2的时候要注意这些字符串会原样出现在图纸上长度受模板限制太长会被截断或者压到别的东西上实际用的时候建议先手工量一下能放多少字。第五段的CreateDrawings返回布尔值成功与否一定要判断并且打印出来。这里失败最常见的原因是图纸属性文件不存在——Tekla 出一张图需要一套属性配置比如用哪套图纸尺寸、哪套布局代码里没指定就会去用默认的默认的找不到就失败。稳妥的做法是先在软件里手工给这个零件出一次同样的图确认能出再跑代码。提示不同版本里CreateDrawings的参数形式和图纸类的构造函数可能略有差异以本机安装的 API 帮助文档为准。遇到签名对不上别硬猜直接翻文档。4.3 改一张已有图纸批量改文本和标题栏比起新建图纸日常更常见的是改已有图纸。这段代码演示两件事遍历当前打开图纸里的所有对象把类型是文字的挑出来统一改字体和字号。using System; using TSD Tekla.Structures.Drawing; namespace DrawingDemo { class BatchText { public static void Run() { TSD.DrawingHandler handler new TSD.DrawingHandler(); // 取当前打开的那张图纸 TSD.Drawing current handler.GetActiveDrawing(); if (current null) { Console.WriteLine(先打开一张图纸再运行); return; } // 拿到图纸里的所有对象 TSD.DrawingObjectEnumerator objects current.GetObjects(); int changed 0; while (objects.MoveNext()) { // 只处理文字对象其他类型直接跳过 TSD.Text text objects.Current as TSD.Text; if (text null) continue; // 属性是值类型改之前先取出来改完再塞回去 TSD.Text.TextAttributes attrs text.Attributes; attrs.Font new TSD.Font(Arial, 3.5); // 字体名 字高毫米 text.Attributes attrs; // 关键一步告诉 Tekla 这个对象被改过了 text.Modify(); changed; } // 提交更改让界面刷新 current.CommitChanges(); Console.WriteLine($共修改 {changed} 个文字对象); } } }GetActiveDrawing()拿的是用户此刻正在看的那张图纸返回 null 说明当前没有图纸处于打开状态这个判断必须有否则后面直接空引用。GetObjects()返回图纸上的所有对象注意它拿的是整张图纸的对象包括各个视图里的不是只拿某一个视图的。如果只想处理某个视图就需要先遍历Sheet再遍历View层次感更强代码也更长入门阶段先用整图遍历把逻辑跑通。中间那段Attributes的取值—修改—回填是 Tekla API 的通用套路很多属性都长这样。它不是对象引用而是一个结构体你直接写text.Attributes.Font ...编译器会报错必须先取出来改再整体塞回去。这个坑几乎每个新手都会踩一次。Modify()这一行极其重要但最容易被忘。它相当于告诉 Tekla「这个对象我改完了你更新一下」漏掉它代码不报错图纸也没变化你会怀疑人生。改完一批之后调CommitChanges()让界面统一刷新避免一个个对象各自刷屏。最后提醒一句这个例子会改掉图纸上所有文字对象包括你不想动的那些。真实使用前一定在测试模型上跑或者先加个条件过滤比如只改图层名等于某个值的文字。5. 新手避坑图纸二次开发最容易翻车的五个地方5.1 图纸操作里的三个高频坑第一个坑代码跑完没报错图纸一点变化都没有。现象是把程序从头跑到尾控制台输出了「修改成功」回到 Tekla 一看图纸原封不动。原因是改完对象属性之后漏掉了Modify()或者批量改完漏掉了CommitChanges()。Tekla 内部有一层缓存你不明确告诉它「这个对象脏了需要更新」它就认为什么都没发生。解决办法很朴素每改一个对象就调一次Modify()一批改完再调一次图纸级别的CommitChanges()两个都别省。第二个坑创建图纸一直返回 false。现象是CreateDrawings返回 false或者程序抛异常说找不到属性。原因通常是图纸属性文件缺失或者名字对不上——代码里指定了某套图纸属性但这台机器上根本没有这套配置或者名字拼错了一个字母。解决办法是先手工出一次同样的图确认软件本身能出再回头看代码里指定的属性名另外要确认这个零件已经编号没编号的零件出图会失败。第三个坑改完图纸关掉重开又变回原样。现象是改完当场看着是对的关闭图纸再打开改动全没了。原因是你只改了内存里的对象没把图纸存盘。解决办法是在改完之后显式保存当前图纸用图纸对象自带的保存方法或者用DrawingHandler的保存当前图纸方法。养成习惯凡是改了图纸代码结尾一定要有一步保存别指望软件替你记着。第四个坑改着改着突然抛空引用但昨天还好好的。现象是同一段代码在 A 模型上跑得好好的换到 B 模型就在某一行崩了。原因多半是数据本身的差异比如某张图纸上没有文字对象遍历时某个转换返回了 null你没判断就直接用了。解决办法是所有as转换后面都跟一个空判断continue掉不匹配的对象这也是为什么前面的例子里每一处转换都写了if (xxx null)。5.2 环境和调试里的两个坑第五个坑本机跑得通同事电脑一打开就报找不到程序集。现象是程序在你自己机器上丝滑运行复制到同事电脑上双击就弹异常提示找不到某个 Tekla.Structures 开头的 DLL或者提示版本不匹配。原因是两台机器的 Tekla 版本不同引用的 DLL 版本号对不上.NET 的强名称绑定直接拒绝加载。解决办法是把团队的软件版本统一如果实在统一不了就按目标机器上的 DLL 重新编译一份别指望一份 DLL 通吃。这也是为什么前面强调「复制到本地」要设成 False——让程序用目标机器自己的那份。第六个坑调试时断点根本进不去。现象是按 F5 启动调试程序一闪而过断点显示一个空心圈提示没有加载符号。原因是你在调试一个类库项目它本身不能独立运行得由 Tekla 这个宿主进程来加载。解决办法是把项目的调试设置改成启动外部程序指向 Tekla 的可执行文件或者干脆用「附加到进程」的方式先打开 Tekla再从 Visual Studio 附加到它的进程上。第一次配这个会花点时间配好之后调试体验会顺畅很多。注意调试图纸相关代码时尽量在测试模型上折腾。图纸一旦被脚本改坏恢复起来比模型麻烦很多时候只能重新出图。这六个坑没有一个是「原理深奥」型的全是「不知道有这么回事」型的。新手阶段摔的跟头九成都在这个范围里。把这些记住能省掉大量原地打转的时间。6. 下一步学什么从会跑例子到能写自己的图纸工具跑通前面几个例子之后很多人会进入一个尴尬期例子看懂了但自己想做的功能不知道从哪下手。这个阶段最有效的做法不是继续看教程而是按一条具体的路径往上爬。我建议的顺序是这样的阶段练什么达到什么程度算过关第一步把例子改成只处理符合条件的对象会写过滤条件不误伤其他对象第二步遍历一张图纸的所有视图能定位到具体视图再动手第三步读一份外部表格按表格内容改图纸会读写文件、会做匹配第四步把功能包装成带界面的插件同事不看说明书也能用第五步加日志和异常处理出错时能自己定位问题第一步的关键是学会「加条件」。任何批量操作第一版都应该写成「只处理我指定的那一个」确认无误后再放开范围。第二步要补的知识是图纸的层级遍历从图纸到视图再到对象这条路走通了你就能做「只改某个视图里的标注」这类精细活。第三步是个分水岭一旦你的工具能读外部数据它就从「玩具」变成「能对接实际流程的东西」了通常读的是表格文件把构件编号和图纸名的对应关系放进去。第四步偏工程化界面做得好不好直接影响别人愿不愿意用。第五步最不显眼但最重要没有日志的工具出了问题只能靠猜。学习资源上最该花时间的是本机安装的那份 API 帮助文档其次是软件自带或项目里现成的示例代码。看示例代码有个技巧不要从头读到尾先找到「跟你目标最像」的那一段把它跑起来再一点点删掉你不需要的部分看删到哪里会崩——这个过程比读十遍文档都管用。从那以后我每次写完一段改图纸的代码都强制自己在测试模型上从头跑一遍再放到正式项目里哪怕只改了一行。图纸这种东西改坏了不像模型那样能一眼看出来等发现的时候往往已经发出去好几版了。希望帮到你。本文还有配套的精品资源点击获取