AX2009–Number Sequence 的使用 (1)
本文先介绍AX2009里的NumberSequence的基本使用方法。
AX2009中一共有2大类序列号NumberSequence:
(1) 系统序列号比如RecId, TransactionId等
(2) 用户自定义序列号,在basic –>> setup –>> number sequence
系统序列号的产生是通过SystemSequences这个SQL表格,每个系统序列号是个big64 整型数据,RecId的分配是基于表格的唯一,而不是在company范围内唯一 (详细参阅书籍Inside Dynamics AX2009 第14章 页码489);而用户自定义序列号存储在NumberSequenceTable表格中。我们重点讨论用户自定义序列号的使用。
NumberSequence 模板的建立:
Basic -> Setup -> Number Sequences, 这里实际建立的是Number Sequence 模板。
NumberSequence的使用:
就程序级别而言,NumberSequence只能赋值到EDT类型的fields上。
几乎在每个AX的模块里都会用到序列号的使用,每个模块都在Setup里有parameters这个form,通常这个Form的NumberSequence负责设置该module里的EDT数据会用到的哪些numbersequence。(Setup –>> Parameters –>> NumberSequence)。比如CRM 模块:
这类信息存储在NumberSequenceReference表格中。
分配序号的大部分功能都在NumberSeq和其派生类NumberSeq_Fast这两个类的GetNumInternal/ ReserveNumInternal这两个virtual methods上实现的。NumberSeq:: Release: 释放一个continuous类型的序号NumberCode 到pool里重用。
但是实际编程使用时候有很多变种, 比如:
yourTableBuffer.Field = NumberSeq::newGetNum(NumberSequenceReference::find(TypeID2ExtendedTypeId(TypeId(YourExtendedDataType))), false).num();
NumberSeq num = NumberSeq::newGetNum(NumberSequenceReference::find(id)); ;
num.used(); // mark the number as used
这其中有个参数 boolean _makeDecisionLater
False: 该序号一旦分配系统根据transaction的最终状态(commit/abort)决定其是被占用(当成功commit时候)还是放回NumberSequenceList供重用。
true: 该序号分配后系统不负责根据transaction的最终状态自动设置其使用状况。程序代码要调用NumberSeq::used/NumberSeq::Abort来手动设置该序号的使用状况。
如果你自定义的EDT数据类型需要赋值为NumberSequence,如何创建呢?
Step #1. 每个module都要定义自己的NumberSeqReference派生类(派生于NumberSeqReference),重载如下方法:
loadModule: 注册本module里哪些EDT会用到NumberSequence。凡是在loadModule里注册的EDT都会在module的setup -> parameters-> Number Sequences表单的左栏Reference显示供用户配置.
numberSeqModule: 返回NumberSeqModule Enum里定义对应的module; 如果你是新添加的module,需要把你的Module添加到Enum NumberSeqModule 中去。
Step #2: 修改Class NumberSeqReference的如下2个方法
Construct :注册step#1中定义的NumberSequence派生类
moduleList: 注册step#1中定义的module
实际的EDT关联配置数据插入到NumberSeqReference数据库表,这个是在NumberSeqReference::create方法里实现的。该方法在用户module的setup -> parameters表单加载时候调用的。
Thanks
Clifford Zhang