需求场景
在日常开发过程中,序列号是一个很常见的需求,SAP这里叫号码范围/号码段,系统本身提供了配置。
创建号码段对象
T-CODE: SNUM或SNRO
1:短文本和长文本用来说明这个编号范围对象,输入任意描述即可。
2:子对象数据元素:所谓子对象,多数指一个组织结构,比如公司代码、销售组织、工厂等,这样编号就在对应的每个组织下面独立编号。
3:到期年标记:是指编号按年度归零,每当开始一个新年度时,相应的编号也需要从头开始,比如财务凭证和物料凭证都是这样(比如表BKPF 和MKPF,都把年度做为一个键字段)。
4:编号长度域就填创建的域。指定这个编号范围对象 ZTEST01的长度,我们定义域长度为 10,因此这个编号范围对象生成的编号长度也是 10 位。
5:无翻滚间隔是指如果编号达到最大,是否自动从头开始,勾上就不从头开始,而在获取编号的时候提示出错。
6:编号范围处理,属于翻译问题,实际就是编号范围的事务码,如果指定这个事务码,就可以不需要通过 SNUM 或者 SNRO 的主屏幕然后输入编号范围对象的名字来维护这个编号范围,而可以输入事务码直接进入它的号码范围维护屏幕。
7:警告百分比是指如果编号使用到一定比例,就发出系统警告,提示管理人员增大范围或者进行历史数据归档,避免编号全部用完后影响正常业务。
8:主内存缓冲是 指系统为了提高性能而预先取出一些编号放在应用服务器上,当程序取用编号时直接从应用服务器获取,而无需再读取数据库了。通常,如果对号码的连续性要求不 高的情况下可以使用这种方式,而如果是财务凭证等要求连续的编号,则应该把主内存缓冲关闭,方法是通过菜单“编辑-设置缓存-无缓存”。
DATA:lv_next TYPE i,
lv_quant LIKE inri-quantity, "dummy
lv_code LIKE inri-returncode. "returncode
"先锁定对象
CALL FUNCTION 'NUMBER_RANGE_ENQUEUE'
EXPORTING
object = 'ZTEST01'
EXCEPTIONS
foreign_lock = 1
object_not_found = 2
system_failure = 3
OTHERS = 4.
IF sy-subrc <> 0.
RAISE lock_error.
EXIT.
ENDIF.
"获取下个数字
CLEAR:lv_next.
CALL FUNCTION 'NUMBER_GET_NEXT'
EXPORTING
nr_range_nr = '01' "在编号范围中分配的序列号
object = 'ZTEST01' "编码对象名称
subobject = '1000' "子对象
toyear = '2023' "年
IMPORTING
number = lv_next "输出生成的流水号
quantity = lv_quant
returncode = lv_code
EXCEPTIONS
interval_not_found = 1
number_range_not_intern = 2
object_not_found = 3
quantity_is_0 = 4
quantity_is_not_1 = 5
interval_overflow = 6
buffer_overflow = 7
OTHERS = 8.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
"解锁
CALL FUNCTION 'NUMBER_RANGE_DEQUEUE'
EXPORTING
object = 'ZCHEQUE'
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
ENDIF.
WRITE : / lv_next.