在调用PO(PI)接口时,PO定义的结构通常是所有字段都是STRING的,而在ABAP中定义的数据结构 可能 是CURR,DEC,或者带着一个例程转换的数据(比如物料号带前导0,而PO传出对方系统不而要前导0),DEC直接给STRING,会出现千分隔(,逗号),点号等问题,所以需要做一个功能来做转换,以下是功能介绍。
1.关键特性:
- 自动前导零处理:数值类型自动去除前导零
- 智能日期转换:初始日期转为空值,非空日期转为ISO格式
- 负数处理:自动将负号移至数字前部
- 浮点精度控制:通过
IV_DECIM
参数控制小数位数 - 空值处理:自动检测并转换初始值为空字符串
- 类型安全:使用ABAP类型描述服务确保类型兼容性
2.完整函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
FUNCTION zfm_po_outbound_data_conv. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" VALUE(IS_INPUT) OPTIONAL *" VALUE(IV_DECIM) DEFAULT 3 *" EXPORTING *" VALUE(ES_OUTPUT) *" TABLES *" IT_DATA OPTIONAL *" ET_DATA OPTIONAL *" EXCEPTIONS *" CONVERSION_ERROR *"---------------------------------------------------------------------- *--------------------------------------------------------------------* * 数据定义 *--------------------------------------------------------------------* TYPES:abap. "字段清单 DATA: lrf_stru TYPE REF TO cl_abap_structdescr, lt_comp TYPE abap_compdescr_tab WITH HEADER LINE, ls_comp TYPE abap_compdescr. FIELD-SYMBOLS: <l_field_s> TYPE any, <l_field_t> TYPE any. *--------------------------------------------------------------------* * 结构字段转换 *--------------------------------------------------------------------* IF is_input IS SUPPLIED . "传入结构或内表包含的字段名和字段类型 lrf_stru ?= cl_abap_typedescr=>describe_by_data( is_input ). lt_comp[] = lrf_stru->components. TRY. "结构中的字段转换 LOOP AT lt_comp INTO ls_comp. ASSIGN COMPONENT ls_comp-name OF STRUCTURE is_input TO <l_field_s>. IF sy-subrc = 0. ASSIGN COMPONENT ls_comp-name OF STRUCTURE es_output TO <l_field_t>. IF sy-subrc = 0. <l_field_t> = <l_field_s>. CASE ls_comp-type_kind. "D:date WHEN 'D'. "日期字段,如果为初始值,清空 IF <l_field_s> IS INITIAL. CLEAR <l_field_t>. ENDIF. "F:float WHEN 'F'. "浮点数转换 CALL FUNCTION 'FLTP_CHAR_CONVERSION' EXPORTING decim = iv_decim input = <l_field_s> IMPORTING flstr = <l_field_t>. CONDENSE <l_field_t> NO-GAPS. "P:packed; I:INT; b:INT1; s:INT2; 8:INT8 WHEN 'P' OR 'I' OR 'b' OR 's' OR '8'. "数量、金额字段,去空格,负号提前 CONDENSE <l_field_t> NO-GAPS. IF <l_field_s> < 0. CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT' CHANGING value = <l_field_t>. ENDIF. WHEN OTHERS. ENDCASE. ENDIF. ENDIF. ENDLOOP. CATCH cx_sy_conversion_error. "数据转换出错:非数字、溢出等 RAISE conversion_error. CATCH cx_root. RAISE conversion_error. "其他错误 ENDTRY. ENDIF. *--------------------------------------------------------------------* * 内表字段转换 *--------------------------------------------------------------------* IF it_data[] IS NOT INITIAL. "传入结构或内表包含的字段名和字段类型 lrf_stru ?= cl_abap_typedescr=>describe_by_data( it_data ). lt_comp[] = lrf_stru->components. TRY. "内表中的字段转换 LOOP AT it_data. CLEAR et_data. LOOP AT lt_comp INTO ls_comp. ASSIGN COMPONENT ls_comp-name OF STRUCTURE it_data TO <l_field_s>. IF sy-subrc = 0. ASSIGN COMPONENT ls_comp-name OF STRUCTURE et_data TO <l_field_t>. IF sy-subrc = 0. <l_field_t> = <l_field_s>. CASE ls_comp-type_kind. "D:date WHEN 'D'. "日期字段,如果为初始值,清空 IF <l_field_s> IS INITIAL. CLEAR <l_field_t>. ENDIF. "F:float WHEN 'F'. "浮点数转换 CALL FUNCTION 'FLTP_CHAR_CONVERSION' EXPORTING decim = iv_decim input = <l_field_s> IMPORTING flstr = <l_field_t>. CONDENSE <l_field_t> NO-GAPS. "P:packed; I:INT; b:INT1; s:INT2; 8:INT8 WHEN 'P' OR 'I' OR 'b' OR 's' OR '8'. "数量、金额字段,去空格,负号提前 CONDENSE <l_field_t> NO-GAPS. IF <l_field_s> < 0. CALL FUNCTION 'CLOI_PUT_SIGN_IN_FRONT' CHANGING value = <l_field_t>. ENDIF. WHEN OTHERS. ENDCASE. ENDIF. ENDIF. ENDLOOP. APPEND et_data. ENDLOOP. CATCH cx_sy_conversion_error. "数据转换出错:非数字、溢出等 RAISE conversion_error. CATCH cx_root. RAISE conversion_error. "其他错误 ENDTRY. ENDIF. ENDFUNCTION. |
3.调用例子
1 2 3 4 5 6 7 8 9 10 |
CALL FUNCTION 'ZFM_PO_OUTBOUND_DATA_CONV' TABLES IT_DATA = LT_DATA[] ET_DATA = <LT_ITEM> EXCEPTIONS CONVERSION_ERROR = 1 OTHERS = 2. IF SY-SUBRC <> 0. "Implement suitable error handling here ENDIF. |
4.功能说明
功能概述
该函数模块用于对采购订单(PO)输出数据进行标准化转换,主要处理日期、浮点数、数值类型的格式化,确保数据在接口传输或报表输出时符合规范要求。支持结构(Structure)和内表(Internal Table)两种输入形式,通过动态字段分析实现通用化处理。
4.1.函数接口说明
参数 | 方向 | 说明 |
---|---|---|
IS_INPUT | IMPORTING | 可选,输入结构(与IT_DATA 二选一) |
IV_DECIM | IMPORTING | 浮点数小数位精度(默认值:3) |
ES_OUTPUT | EXPORTING | 输出结构(转换后结果) |
IT_DATA | TABLES | 可选,输入内表(与IS_INPUT 二选一) |
ET_DATA | TABLES | 输出内表(转换后结果) |
CONVERSION_ERROR | EXCEPTIONS | 转换异常(如数据类型错误、溢出等) |
4.2.核心逻辑解析
4.2.1.1. 动态字段分析
1 2 |
lrf_stru ?= cl_abap_typedescr=>describe_by_data( is_input ). lt_comp[] = lrf_stru->components. |
- 使用
cl_abap_structdescr
获取输入结构的字段元数据(字段名、类型、长度等)。 lt_comp
存储字段描述信息,用于后续动态访问字段。
4.2.2.2. 结构转换流程
1 2 3 4 5 |
LOOP AT lt_comp INTO ls_comp. ASSIGN COMPONENT ls_comp-name OF STRUCTURE is_input TO <l_field_s>. ASSIGN COMPONENT ls_comp-name OF STRUCTURE es_output TO <l_field_t>. ... ENDLOOP. |
- 字段级处理:遍历所有字段,通过字段符号
<l_field_s>
/<l_field_t>
动态读写值。 - 类型区分处理:
- 日期(Type ‘D’):初始值清零abap复制下载IF <l_field_s> IS INITIAL. CLEAR <l_field_t>. ENDIF.
- 浮点数(Type ‘F’):调用
FLTP_CHAR_CONVERSION
转字符串abap复制下载CALL FUNCTION ‘FLTP_CHAR_CONVERSION’ EXPORTING decim = iv_decim ” 控制小数位 input = <l_field_s> IMPORTING flstr = <l_field_t>. CONDENSE <l_field_t> NO-GAPS. ” 删除空格 - 数值类型(P/I/b/s/8):负号前置+压缩空格abap复制下载CONDENSE <l_field_t> NO-GAPS. IF <l_field_s> < 0. CALL FUNCTION ‘CLOI_PUT_SIGN_IN_FRONT’ ” 负号移至前端 CHANGING value = <l_field_t>. ENDIF.
4.2.3.3. 内表转换流程
1 2 3 4 5 6 7 |
LOOP AT it_data. CLEAR et_data. LOOP AT lt_comp INTO ls_comp. ... " 字段级转换(同结构逻辑) ENDLOOP. APPEND et_data. ENDLOOP. |
- 逐行处理内表,每行字段转换逻辑与结构一致。
- 转换后行追加至输出表
ET_DATA
。
4.2.4.4. 异常处理
1 2 |
CATCH cx_sy_conversion_error. RAISE conversion_error. CATCH cx_root. RAISE conversion_error. |
- 捕获数据类型转换错误(如非数字字符转数值)及其他未知异常。
- 统一抛出
CONVERSION_ERROR
供调用方处理。
4.3.关键设计亮点
- 动态字段绑定
通过ASSIGN COMPONENT
动态访问字段,无需预定义结构类型,增强函数通用性。 - 类型安全转换
严格区分数据类型(日期、浮点、整型等),避免隐式转换错误。 - 负号标准化
数值类型强制将负号(-
)从尾部移至头部(如"123-"
→"-123"
),符合财务规范。 - 空格压缩优化
使用CONDENSE ... NO-GAPS
消除数值字符串冗余空格,减少数据传输量。
4.4.注意事项
- 输入选择
IS_INPUT
与IT_DATA
不可同时传入,需根据场景二选一。 - 性能考量
内表过大时,逐行循环可能影响性能,建议分块处理或异步调用。 - 异常处理
调用方必须捕获CONVERSION_ERROR
,避免程序中断。 - 浮点精度
IV_DECIM
过大可能导致字符串超长(需确保输出字段长度足够)。
4.5.总结
zfm_po_outbound_data_conv
通过动态字段分析与类型化转换规则,高效解决了PO数据输出时的格式化需求,特别适用于EDI接口、IDoc映射或财务凭证生成等场景。其模块化设计兼顾灵活性与健壮性,是ABAP数据转换层的实用工具函数。