4.2.5、自定义数据类型
4.2.5.1、概述
CMS 变量除支持布尔型、整型、浮点型、字符串型等基础数据类型外,还支持由工程开发人员自定义的数据类型,包括自定义数组型和自定义结构型。
合理使用自定义类型,可以大幅减少变量建立和维护的工作量,尤其适用于大量同类变量的批量管理场景。
标签协议用户请注意: 如果您的通道使用 Omron、EtherNet/IP、OPC UA 等标签寻址协议,且 PLC 已完成编程,可跳过手动定义步骤,直接通过「3. 标签协议特殊说明 → 从标签加载生成」从 PLC 一键导入,无需手动创建数组或结构体。
4.2.5.2、自定义数组型
适用场景
当某个变量需要存储一组同类数据时,例如记录某设备连续采集的 10 个温度值,可将其定义为数组型变量,通过索引访问每个元素,避免建立多个同类变量。
操作步骤
第一步:添加变量,选择数组类型
在变量表中点击添加变量,将数据类型下拉选择为 数组,此时右侧出现配置图标。
第二步:配置数组属性
点击配置图标,在弹窗中设置以下属性:
| 配置项 | 说明 |
|---|---|
| 数据类型 | 数组成员的基础数据类型,如整型、浮点型等 |
| 数组维度 | 支持最多 3 维 |
| 各维度长度 | 设置每个维度的元素数量 |
| 各维度起始位 | 设置每个维度的索引起始值 |
第三步:确认生成
点击确认后,系统自动展开生成对应的数组成员元素,可在变量表中逐一查看和配置。

以采集设备 10 个历史温度值为例:
- 数据类型:浮点型
- 维度:1 维
- 长度:10,起始位:0
确认后生成 Temp[0] 至 Temp[9] 共 10 个成员变量。
4.2.5.3、自定义结构型
适用场景
当系统中存在多台同类设备,每台设备具有相同的参数结构时,可先将单台设备的参数定义为结构类型(UDT),再基于该类型批量创建实例变量。
典型场景: 现场有 3 台驱动电机,每台电机具有启停状态、转速等参数。使用传统方式需逐一建立多个基础变量;改用结构类型后,每台电机只需一个结构体实例变量,建立和维护效率显著提升。
操作步骤
整体流程分为三步:定义结构类型 → 创建实例变量 → 配置成员属性。
第一步:定义结构类型(UDT)
- 在左下角 自定义数据类型 面板中,点击添加 数据类型,命名为
Motor。 - 选中
Motor,在右侧点击 添加 按钮,逐一添加结构成员,填写成员名称、数据类型和描述。

示例结构体 Motor:
| 成员名称 | 数据类型 | 描述 |
|---|---|---|
| Start | 二进制型 | 启动命令 |
| Stop | 二进制型 | 停止命令 |
| Speed | 无符号32位整型 | 当前转速 |
| Temp | 无符号32位整型 | 当前温度 |
第二步:创建实例变量
- 选中变量通道,点击添加变量。
- 输入实例变量名,数据类型下拉选择刚定义的
Motor。 - 以 3 台电机为例,依次创建
Motor1、Motor2、Motor3。

第三步:配置成员属性
点击实例变量行的 成员配置 按钮,在弹窗中为结构体各成员配置属性,包括变量地址、读写方式等。
其中变量地址支持使用地址模板,可快速批量生成多个实例的地址,避免逐个手动填写。
地址模板规则:
每个成员的实际地址由三部分组成:
实际地址 = 前缀 + (模板基础地址 + 偏移量)
- 模板基础地址:第一个实例(
Motor1)各成员的起始地址,手动填写一次后作为模板。 - 偏移量:后续实例相对于基础地址的偏移步长,每个实例统一设置,系统自动累加计算。这是最常用的区分方式,适用于各实例数据连续存储的场景。
- 前缀:地址中不参与偏移计算的固定部分,可手动修改。当各实例数据存储位置并非简单偏移、而是存储区域本身不同时(如 S7 协议中每台电机使用独立 DB 块:
DB1.、DB2.、DB3.),可将区域标识作为前缀逐实例修改,块内偏移量统一置 0。
Modbus 示例(无前缀,偏移 30):
| 成员 | Motor1(偏移 0) | Motor2(偏移 30) | Motor3(偏移 60) |
|---|---|---|---|
| Start | 400001.1 | 400031.1 | 400061.1 |
| Stop | 400001.2 | 400031.2 | 400061.2 |
| Speed | 400006 | 400036 | 400066 |
| Temp | 400010 | 400040 | 400070 |
S7 示例一:同一 DB 块,偏移量区分(前缀固定 DB1.,偏移 30):
| 成员 | Motor1(偏移 0) | Motor2(偏移 30) | Motor3(偏移 60) |
|---|---|---|---|
| Start | DB1.DBX0.1 | DB1.DBX30.1 | DB1.DBX60.1 |
| Stop | DB1.DBX0.2 | DB1.DBX30.2 | DB1.DBX60.2 |
| Speed | DB1.DBD6 | DB1.DBD36 | DB1.DBD66 |
| Temp | DB1.DBD10 | DB1.DBD40 | DB1.DBD70 |
S7 示例二:不同 DB 块,前缀区分(偏移量固定 0,前缀逐实例修改):
| 成员 | Motor1(前缀 DB1.) | Motor2(前缀 DB2.) | Motor3(前缀 DB3.) |
|---|---|---|---|
| Start | DB1.DBX0.1 | DB2.DBX0.1 | DB3.DBX0.1 |
| Stop | DB1.DBX0.2 | DB2.DBX0.2 | DB3.DBX0.2 |
| Speed | DB1.DBD6 | DB2.DBD6 | DB3.DBD6 |
| Temp | DB1.DBD10 | DB2.DBD10 | DB3.DBD10 |
操作示例(以三台电机为例):
-
打开
Motor1的成员配置弹窗,手动填写各成员的基础地址(偏移量保持 0),点击确认,Motor1地址配置完成。
-
打开
Motor2的成员配置弹窗,将偏移量设置为 30,系统自动在Motor1模板地址基础上累加 30,生成Motor2各成员地址,可在预览列核对地址是否符合预期,确认后保存。
-
打开
Motor3的成员配置弹窗,将偏移量设置为 60,同理生成Motor3地址,再次核对预览列后保存。
提示: 每个通道的 UDT 地址模板独立保存。如需在其他通道复用相同的 UDT 地址模板,可使用弹窗中的导入功能,从已配置好的通道导入模板,无需重新手动填写基础地址。
4.2.5.4、标签协议特殊说明
适用于支持标签寻址的协议:Omron、EtherNet/IP、CIP、AB EtherNet/IP、OPC UA、西门子台达等。此类协议的变量地址为标签路径,与传统地址偏移方式不同。
从标签加载生成(推荐方式)
标签协议的核心优势在于:无需手动定义数组或结构体类型,可直接从 PLC 标签中加载生成对应变量。
适用场景: PLC 已完成编程且在线连接,PLC 端已定义好变量结构(含数组和结构体)。
操作步骤:
- 确认通道协议为标签协议(如 Omron、EtherNet/IP),且 PLC 处于在线状态。
- 点击变量表右上角的 自动加载标签 按钮,打开标签浏览器弹窗。
- 在标签树中逐级浏览至目标变量(如
GVL_FTC.Motor1),选中后确认。 - 系统将按标签原有的层级结构自动生成对应的变量,包括其中的数组和结构体成员,无需手动定义数据类型。

以电机 Motor1 为例:
选中标签 GVL_FTC.Motor1 后,变量表中将生成以下层级结构(与 PLC 标签定义一致):
Motor1 Struct(Motor)
├── Command Struct
│ ├── Start 二进制变量量 启动命令
│ ├── Stop 二进制变量量 停止命令
│ ├── Reset 二进制变量量 复位命令
│ └── Setpoint 无符号32位整型 转速设定值
├── Status Struct
│ ├── Running 二进制变量量 运行状态
│ ├── Fault 二进制变量量 故障状态
│ ├── Speed 无符号32位整型 当前转速
│ └── Temp 无符号32位整型 当前温度
└── Parameters Struct
├── RatedSpeed 无符号32位整型 额定转速
├── RatedPower 无符号32位整型 额定功率
├── MaxSpeed 无符号32位整型 最大转速
└── MinSpeed 无符号32位整型 最小转速
每个变量的名称、数据类型、描述和地址均由 PLC 标签自动映射,无需手动填写。若加载的结构体中包含子结构体或数组,可在变量表中点击展开点查看其成员。
- 删除:选中变量节点,点击 删除 按钮。删除子节点仅移除该成员;删除根节点时其下所有子成员一并移除(仅影响本地,不修改 PLC 端)。
- 同步 PLC 变更:在根变量的变量地址处点击 同步标签,系统从 PLC 拉取最新定义并更新本地。PLC 端修改的属性会覆盖本地,新增的成员会自动追加;PLC 端已移除的成员不会自动清理,需手动删除。
手动创建自定义类型(离线场景)
若 PLC 处于离线状态无法在线浏览标签,也可按前文「第 1 节 / 第 2 节」的方式手动创建数组型和结构型变量。创建完成后,实例变量的地址配置方式与普通协议不同——只需为实例根变量选择一个标签路径,其成员变量会根据结构自动关联到该路径下的子标签。
操作步骤:
-
按第 2 节方法定义结构类型(如
Motor)并创建实例变量(如Motor1)。 -
在
Motor1的变量地址列点击,弹出标签路径选择弹窗。 -
浏览标签树,选中目标路径(如
...GVL_FTC.Motor1)并确认。 -
系统自动根据
Motor结构体的成员定义,将各成员映射到所选标签路径下的子标签。例如Motor结构体包含Command(Struct)成员,Command下又包含Start、Stop等子成员,则映射关系为:Motor1.Command.Start→...Motor1.Command.StartMotor1.Command.Stop→...Motor1.Command.Stop- 以此类推

此方式仅在 PLC 离线时作为备用方案使用。只要 PLC 在线,优先使用上方「从标签加载生成」方式,更高效且不会出现人工录入错误。
4.2.5.5、注意事项
- 自定义数据类型从 v2.40.0 版本开始支持;从标签加载生成功能正在迭代中,预计从 v2.40.2 版本开始支持。
- 结构类型(UDT)定义完成后,若需修改成员,已创建的实例变量会同步受影响,请在工程初期规划好结构体成员。
- 每个通道的地址模板独立保存,修改某通道的偏移量不影响其他通道。