XScript 手册 · Chapter 51
SN 对象 — 序列号规则管理
脚本中以关键字 SN 访问。用于标签打印、MES 上报、可追溯性等场景的 固定区(Lot/Line)+ 可变区(序列) 序列号规则。可按规则名注册、生成、管理多套规则。
| 概念 | 说明 |
|---|---|
| 规则(rule) | 以名称标识。同一项目可同时运行多套 |
| 格式 | [固定宽度:类型:对齐]&[字段::长度]|[可变区] 形式 — 例:`[12:0:Left]&[Lot::6] |
| 上下文 | 4 个键:LotNo · LineNo · WorkOrderNo · SubLot |
| 排除字符 | 默认 "1,0,D,I,O"(视觉易混字符) |
一行总结 —
SN.RegisterRule(...)注册 →SN.SetContext(...)填 Lot →SN.GenerateNext(...)生成下一个。
1) 注册 / 更新规则
通过名称 + 完整格式字符串一行完成。
// 直接传完整格式
SN.RegisterRule("prodA", "[12:0:Left]&[Lot::6]|[SN:SequencialDecimal:0:6]");
// 验证是否注册成功
if( SN.GetRule("prodA") == null )
{
LogError("rule register failed");
return false;
}如果存在同名规则,会覆盖 — 已有的序列计数器不会保留,会被重新初始化。
2) 填上下文
生成时合并到序列号中的外部值。
SN.SetContext("prodA", "LotNo", "LOT2026");
SN.SetContext("prodA", "LineNo", "L1");
SN.SetContext("prodA", "WorkOrderNo", "WO001");
SN.SetContext("prodA", "SubLot", "S01");有效键:"LotNo"、"SubLot"、"LineNo"、"WorkOrderNo"(其他键返回 false)。
3) 发放下一个序列号
string sn = SN.GenerateNext("prodA");
if( sn == "" )
{
LogError("generate next failed");
return false;
}
Log($"new SN : {sn}");
// 例: "12LOT2026000001"GenerateNext 调用会 将序列计数器加 1 并返回新值。
不增加计数仅查看
string current = SN.Peek("prodA"); // 上一次发放的可变区值计数器初始化
SN.ResetSequence("prodA"); // 规则定义保留,可变区重置4) 预览 / 批量生成
Preview — 不改变状态
// 用于标签设计 / 检查画面的样本 5 个(实际计数器不会增加)
string[] samples = SN.Preview("prodA", 5);GenerateBatch — 计数器增加 + 批量
// 一次性给打印机发 100 张
string[] batch;
if( SN.GenerateBatch("prodA", 100, batch) == false )
{
LogError("batch failed");
return false;
}
for(i, 0, batch.Length - 1)
{
PRINTER.PrintLabel(batch[i]);
}5) 排除字符(ExcludedChars)
可变区中不使用的字符,以逗号分隔。
// 默认值(未设置时):"1,0,D,I,O"
string current = SN.GetExcludedChars("prodA");
Log($"excluded : {current}");
// 修改
SN.SetExcludedChars("prodA", "1,0,O");
// 无排除
SN.SetExcludedChars("prodA", "");排除与 0/1 易混的 I/O 等字符,可大幅降低打印 / OCR 误识别率。
6) 删除 / 列表
// 已注册的规则名数组
string[] names = SN.GetRuleNames();
for(i, 0, names.Length - 1) Log(names[i]);
// 单个删除
SN.RemoveRule("prodA");7) 持久化 — 文件 · 项目保存 / 读取
规则定义以 JSON 序列化。可变区计数器不在持久化范围 — 仅在运行时保存于内存。
// 文件
SN.SaveToFile("D:/Backup/rules.json");
SN.LoadFromFile("D:/Backup/rules.json");
// 项目目录默认路径(SerialRules.XDF)
SN.SaveToProject();
SN.LoadFromProject();LoadFromXxx 调用前会清空管理器再载入。如需保留同名规则,请提前导出。
常用模式
批次开始时 — 设置 Lot 后发放第一个序列号
FUNCTION OnLotStart(string lotNo, string subLot)
{
SN.SetContext("prodA", "LotNo", lotNo);
SN.SetContext("prodA", "SubLot", subLot);
SN.ResetSequence("prodA"); // 新 Lot 重新计数
string firstSn = SN.GenerateNext("prodA");
Data::CurrentSN = firstSn;
return true;
}新项目首次启动自动注册
FUNCTION OnInit()
{
if( SN.LoadFromProject() == false )
{
// 文件还不存在 — 用代码注册默认规则并保存
SN.RegisterRule("prodA", "[12:0:Left]&[Lot::6]|[SN:SequencialDecimal:0:6]");
SN.SetExcludedChars("prodA", "1,0,D,I,O");
SN.SaveToProject();
}
return true;
}预览 → 用户确认 → 实发
string[] sample = SN.Preview("prodA", 3);
string msg = $"Sample: {sample[0]} / {sample[1]} / {sample[2]}\nProceed?";
if( ShowMessage(EB_YesNo, 0, msg) == ER_Yes )
{
string real = SN.GenerateNext("prodA");
// ... print or report
}函数一览
| 分类 | 函数 |
|---|---|
| 注册 / 查询 | RegisterRule(name, fullFormat) · GetRule(name) · GetRuleNames() · RemoveRule(name) |
| 上下文 | SetContext(name, key, value)(LotNo/SubLot/LineNo/WorkOrderNo) |
| 排除字符 | SetExcludedChars(name, chars) · GetExcludedChars(name) |
| 发放 | GenerateNext(name) · Peek(name) · ResetSequence(name) · Preview(name, count) · GenerateBatch(name, count, ref array) |
| 持久化 | SaveToFile(path) · LoadFromFile(path) · SaveToProject() · LoadFromProject() |