最开始获取流水码时,只有log_key 和idx两个字段,在实际使用中,经常遇到数据被锁定,导致获取流水码失败,因此引入批次的概念。
表设计:
函数信息:
FUNCTION zfmbc_test_get_number.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" REFERENCE(I_LOG_KEY) TYPE ZTEST_04-LOG_KEY
*" REFERENCE(I_ERDAT) TYPE SY-DATUM DEFAULT SY-DATUM
*" REFERENCE(I_COUNT) TYPE INT4 DEFAULT 1
*" REFERENCE(I_FILL_CNT) TYPE INT4 DEFAULT 6
*" REFERENCE(I_GROUP) TYPE INT4 DEFAULT 3
*" EXPORTING
*" VALUE(E_SERIALSTR) TYPE CLIKE
*" VALUE(ET_SERIALSTR) TYPE ZTBC_SERIALSTR
*" EXCEPTIONS
*" ERROR
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& DEVELOPER < 开 发>:
*& CREATE ON <创建日期>: 2024-04-10
*& FS NUMBER <FS 编号>:
*& FUNCTIONAL CONSULTANT<功能顾问>:
*& DESCRIPTION <FS 中业务需求概述>:
*&
*&---------------------------------------------------------------------*
* MODIFICATION LOG<程序修改日志,创建时不要填写>
*<版本> <日期> <开发者> <功能顾问> 任务编号 <请求号>
*VERSION DATE PROGRAMMER CORR. # IL# TRANSPORT
* 1 YYYY/MM/DD
*DESCRIPTION<程序逻辑修改 版本1> :
*
*DESCRIPTION<程序逻辑修改 版本2> :
*
*&---------------------------------------------------------------------*
"注意:LOG_KEY 只有一个I_GROUP,否则数据异常
DATA:
lv_count TYPE i, "剩余条数
lv_batch TYPE ztest_04-batch, "批次
lv_group TYPE i, "分组处理
lt_serialstr TYPE ztbc_serialstr.
lv_group = i_group.
DO lv_group TIMES.
"批次
lv_batch = sy-index.
"剩余编码条数
lv_count = i_count - lines( et_serialstr ).
"判断是否获取足够条码
IF lv_count < 1.
EXIT.
ENDIF.
CALL FUNCTION 'ZFMBC_TEST_GET_NUMBER_BATCH'
EXPORTING
i_log_key = i_log_key
i_erdat = i_erdat
i_count = lv_count
i_fill_cnt = i_fill_cnt
i_batch = lv_batch
i_group = i_group
IMPORTING
et_serialstr = lt_serialstr
EXCEPTIONS
error = 1
OTHERS = 2.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
"汇总条码
IF lt_serialstr[] IS NOT INITIAL.
APPEND LINES OF lt_serialstr TO et_serialstr.
CLEAR lt_serialstr.
ENDIF.
ENDDO.
READ TABLE et_serialstr INTO e_serialstr INDEX 1.
IF i_count NE lines( et_serialstr ).
MESSAGE '编码获取失败' TYPE 'E' RAISING error.
ENDIF.
ENDFUNCTION.
FUNCTION zfmbc_test_get_number_batch .
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" REFERENCE(I_LOG_KEY) TYPE ZTEST_04-LOG_KEY
*" REFERENCE(I_ERDAT) TYPE SY-DATUM
*" REFERENCE(I_COUNT) TYPE INT4
*" REFERENCE(I_FILL_CNT) TYPE INT4
*" REFERENCE(I_BATCH) TYPE ZTEST_04-BATCH
*" REFERENCE(I_GROUP) TYPE INT4
*" EXPORTING
*" REFERENCE(ET_SERIALSTR) TYPE ZTBC_SERIALSTR
*" EXCEPTIONS
*" ERROR
*"----------------------------------------------------------------------
*&---------------------------------------------------------------------*
*& DEVELOPER < 开 发>:
*& CREATE ON <创建日期>: 2024-04-10
*& FS NUMBER <FS 编号>:
*& FUNCTIONAL CONSULTANT<功能顾问>:
*& DESCRIPTION <FS 中业务需求概述>:
*&
*&---------------------------------------------------------------------*
* MODIFICATION LOG<程序修改日志,创建时不要填写>
*<版本> <日期> <开发者> <功能顾问> 任务编号 <请求号>
*VERSION DATE PROGRAMMER CORR. # IL# TRANSPORT
* 1 YYYY/MM/DD
*DESCRIPTION<程序逻辑修改 版本1> :
*
*DESCRIPTION<程序逻辑修改 版本2> :
*
*&---------------------------------------------------------------------*
DATA:
lv_group TYPE i,
lv_seq_numc TYPE n LENGTH 20 , " 流水号补位
lv_serialstr TYPE string,
lv_begindex TYPE i,
lv_endindex TYPE i,
ls_ztest_04 TYPE ztest_04.
CONSTANTS lc_connection TYPE char50 VALUE 'R/3*ZTEST_04'.
"分组初始值
lv_group = i_group.
IF lv_group IS INITIAL.
lv_group = 1.
ENDIF.
"起始编码
lv_begindex = 1000000 DIV lv_group * ( i_batch - 1 ).
lv_endindex = 1000000 DIV lv_group * i_batch.
IF lv_endindex = 1000000.
lv_endindex = 999999.
ENDIF.
"KEY
ls_ztest_04-log_key = i_log_key && i_erdat+2(6).
"批次
ls_ztest_04-batch = i_batch.
"锁定数据
CALL FUNCTION 'ENQUEUE_EZ_ZTEST_04'
EXPORTING
mode_ztest_04 = 'E'
mandt = sy-mandt
log_key = ls_ztest_04-log_key
batch = ls_ztest_04-batch
x_log_key = ' '
x_batch = ' '
_scope = '3'
_wait = ' '
_collect = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
RAISING error.
ENDIF.
"获取数据库条码
SELECT SINGLE idx
FROM ztest_04
WHERE log_key = @ls_ztest_04-log_key
AND batch = @ls_ztest_04-batch
INTO @ls_ztest_04-idx.
IF ls_ztest_04-idx < lv_endindex.
"防止跨批次执行
IF ls_ztest_04-idx < lv_begindex.
ls_ztest_04-idx = lv_begindex.
ENDIF.
"循环取号
DO i_count TIMES.
"序号赋值
lv_serialstr = lv_seq_numc = ls_ztest_04-idx = ls_ztest_04-idx + 1.
"填充0
SHIFT lv_serialstr LEFT BY ( 20 - i_fill_cnt ) PLACES.
"汇总
lv_serialstr = |{ ls_ztest_04-log_key }{ lv_serialstr }|.
APPEND lv_serialstr TO et_serialstr[].
IF ls_ztest_04-idx >= lv_endindex.
EXIT.
ENDIF.
ENDDO.
"更新数据库
MODIFY ztest_04 CONNECTION (lc_connection) FROM ls_ztest_04 .
IF sy-subrc EQ 0.
COMMIT CONNECTION (lc_connection).
ELSE.
ROLLBACK CONNECTION (lc_connection).
CLEAR et_serialstr[].
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
RAISING error.
ENDIF.
ENDIF.
"解锁
CALL FUNCTION 'DEQUEUE_EZ_ZTEST_04'
EXPORTING
mode_ztest_04 = 'E'
mandt = sy-mandt
log_key = ls_ztest_04-log_key
batch = ls_ztest_04-batch
x_log_key = ' '
x_batch = ' '
_scope = '3'
_synchron = ' '
_collect = ' '.
ENDFUNCTION.
测试: