一、基础拼接方法
1. 使用 && 操作符(推荐,7.02+)
DATA(lv_result) = 'Hello' && ' ' && 'World'. " Hello World
" 多字段拼接
DATA: lv_name TYPE string VALUE '张三',
lv_age TYPE i VALUE 25,
lv_city TYPE string VALUE '北京'.
DATA(lv_info) = lv_name && ',年龄:' && lv_age && ',城市:' && lv_city.
" 结果:张三,年龄:25,城市:北京
2. 使用 CONCATENATE 语句(经典方式)
DATA: lv_first TYPE string VALUE 'SAP',
lv_second TYPE string VALUE 'ERP',
lv_result TYPE string.
" 基础拼接
CONCATENATE lv_first lv_second INTO lv_result. " SAPERP
CONCATENATE lv_first lv_second INTO lv_result SEPARATED BY ' '. " SAP ERP
" 多字符串
CONCATENATE '2025' '03' '14' INTO lv_result SEPARATED BY '-'. " 2025-03-14
3. 使用 | ... | 字符串模板(7.02+,最强大)
" 基础嵌入
DATA(lv_name) = 'Kimi'.
DATA(lv_msg) = |你好,{ lv_name }!|. " 你好,Kimi!
" 表达式嵌入
DATA(lv_a) = 10.
DATA(lv_b) = 20.
DATA(lv_sum) = |{ lv_a } + { lv_b } = { lv_a + lv_b }|. " 10 + 20 = 30
" 调用方法
DATA(lv_date) = |今天是{ cl_abap_context_info=>get_system_date( ) }|.
二、实际业务场景示例
场景1:构建动态SQL条件
DATA: lt_where TYPE TABLE OF string,
lv_where TYPE string.
" 收集条件
IF lv_bukrs IS NOT INITIAL.
APPEND |BUKRS = '{ lv_bukrs }'| TO lt_where.
ENDIF.
IF lv_gjahr IS NOT INITIAL.
APPEND |GJAHR = { lv_gjahr }| TO lt_where.
ENDIF.
" 拼接成完整WHERE条件
lv_where = concat_lines_of( table = lt_where sep = ' AND ' ).
" 结果:BUKRS = '1000' AND GJAHR = 2025
场景2:格式化输出(期间转换场景)
DATA: lv_yyyppp TYPE char7 VALUE '2025001',
lv_year TYPE char4,
lv_period TYPE char3,
lv_yyyymm TYPE char6.
" 拆分并重组
lv_year = lv_yyyppp(4). " 2025
lv_period = lv_yyyppp+4(3). " 001
" 使用模板格式化(自动去前导零)
lv_yyyymm = |{ lv_year }{ lv_period+1(2) }|. " 202501
" 或者使用CONCATENATE
CONCATENATE lv_year lv_period+1(2) INTO lv_yyyymm. " 202501
场景3:构建文件路径
DATA: lv_path TYPE string,
lv_folder TYPE string VALUE '/usr/sap/tmp',
lv_filename TYPE string VALUE 'export.csv',
lv_date TYPE sy-datum VALUE '20250314'.
" 方法1:模板(推荐)
lv_path = |{ lv_folder }/{ lv_date }_{ lv_filename }|.
" /usr/sap/tmp/20250314_export.csv
" 方法2:操作符
lv_path = lv_folder && '/' && lv_date && '_' && lv_filename.
三、高级技巧
1. 内嵌格式化选项
DATA: lv_amount TYPE p DECIMALS 2 VALUE '1234567.89',
lv_date TYPE d VALUE '20250314'.
DATA(lv_formatted) = |金额:{ lv_amount NUMBER = USER },
日期:{ lv_date DATE = USER }|.
" 金额:1,234,567.89,日期:2025/03/14(根据用户设置)
2. 条件表达式
DATA(lv_status) = 'A'.
DATA(lv_msg) = |状态:{ lv_status }{
COND #( WHEN lv_status = 'A' THEN '(已批准)'
WHEN lv_status = 'R' THEN '(已拒绝)'
ELSE '(待处理)' )
}|.
3. 循环拼接(处理内表)
DATA: lt_items TYPE TABLE OF string,
lv_line TYPE string.
lt_items = VALUE #( ( '苹果' ) ( '香蕉' ) ( '橙子' ) ).
" 方法1:REDUCE(7.40+)
DATA(lv_list) = REDUCE string(
INIT text = ''
FOR wa IN lt_items
NEXT text = text && wa && '、'
).
lv_list = lv_list && '。'. " 苹果、香蕉、橙子、。
" 方法2:CONCATENATE LINES OF
CONCATENATE LINES OF lt_items INTO lv_line SEPARATED BY ','.
四、方法对比与选择建议
| 方法 | 版本要求 | 适用场景 | 特点 |
|---|
&& | 7.02+ | 简单快速拼接 | 简洁,左结合 |
|...| | 7.02+ | 复杂格式化 | 功能最强,支持表达式 |
CONCATENATE | 所有 | 传统代码兼容 | 明确SEPARATED BY |
concat_lines_of | 7.40+ | 内表转字符串 | 处理多行数据 |
性能提示
" 避免在循环中反复拼接(产生大量临时对象)
" ❌ 低效
DO 1000 TIMES.
lv_result = lv_result && 'X'. " 每次创建新对象
ENDDO.
" ✅ 高效:使用STRING_TABLE缓冲
DATA: lt_buffer TYPE TABLE OF string.
DO 1000 TIMES.
APPEND 'X' TO lt_buffer.
ENDDO.
lv_result = concat_lines_of( table = lt_buffer ).
五、针对您之前的YYYYPPP转换(字符串版)
DATA: lv_yyyppp TYPE char7 VALUE '2025001',
lv_yyyymm TYPE char6.
" 方法1:子串拼接
lv_yyyymm = lv_yyyppp(4) && lv_yyyppp+4(2).
" lv_yyyppp(4) = 前4位:2025
" lv_yyyppp+4(2) = 从第5位取2位:00(取前两位期间)
" 方法2:模板(更直观)
lv_yyyymm = |{ lv_yyyppp(4) }{ lv_yyyppp+4(2) }|.
WRITE: / '转换结果:', lv_yyyymm. " 202500