ABAP杂项
字符串拼接
*cl_abap_char_utilities=>CR_LF 获取换行符
CONCATENATE L1 cl_abap_char_utilities=>CR_LF L2 INTO L3.
*或者
CONCATENATE L1 cl_abap_char_utilities=>newline L2 INTO L3.
ALV布局保存参数
* 布局可以通过调用`REUSE_ALV_VARIANT_ALL_MAINTAIN`这个函数模块进行修改 比如删除掉全局的缺省布局
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
is_layout = gt_layout
it_fieldcat = gt_fieldcat[]
i_save = 'U' "SPACE. 布局不能被保存 U 仅自定义的布局可以被保存
"X 仅全局布局可以被保存 A 自定义的布局和全局的布局都可以被保存
i_callback_user_command = 'FORM_USER_COMMAND' "客户命令指定子程序
i_callback_pf_status_set = 'FORM_PF_STATUS_SET' "GUI指定子程序
it_events = gt_events
TABLES
t_outtab = gt_out[]
EXCEPTIONS
program_error = 1
OTHERS = 2.
动态赋值内表字段的值
data: BEGIN OF student occurs 0,
name type char5,
age type int2,
school type string,
END OF student.
data field type string . "字段名
FIELD-SYMBOLS <filed> type any.
* 想实现的效果 内表中的字段名
* student-filed = '张三'. "name
* student-filed = '24'. "age
* student-filed = 'zhangsan小学'."school
* append student.
* 实现方式
field = 'student-name'.
ASSIGN (field) to <filed>.
<filed> = '张三'.
field = 'student-age'.
ASSIGN (field) to <filed>.
<filed> = 24.
field = 'student-school'.
ASSIGN (field) to <filed>.
<filed> = 'zhangsan小学'.
append student.
ABAP Sql
sum函数的用法
*销售订单中的退货订单 在进行含税价格求和时 需要将退货的订单的金额置为负数 在进行求和
select sum( vbap~kzwi1 * ( case auart
when 'ZRE' then ( -1 )
else 1
end ) ) as kzwi1_sum
from vbap inner join vbak on vbak~vbeln = vbap~vbeln
遍历结构
FIELD-SYMBOLS: <F>.
DO.
ASSIGN COMPONENT SY-INDEX OF STRUCTURE student TO <F>.
IF SY-SUBRC NE 0.
EXIT.
ELSE.
* Do something.....
ENDIF.
ENDDO.
两个内表不同名称字段赋值的快捷方法
简单结构
* 定义两个工作区
DATA:
BEGIN OF struct1,
a1 TYPE string VALUE 'a1',
a2 TYPE string VALUE 'a2',
a3 TYPE string VALUE 'a3',
a4 TYPE string VALUE 'a4',
a5 TYPE string VALUE 'a5',
END OF struct1,
BEGIN OF struct2,
b1 TYPE string VALUE 'b1',
b2 TYPE string VALUE 'b2',
b3 TYPE string VALUE 'b3',
a4 TYPE string VALUE 'b4',
a5 TYPE string VALUE 'b5',
END OF struct2.
* 创建映射关系 其实字段名称相同的话 可以不用去映射 但是就不能指定kind为3的其他映射关系
* level 代表层级 有的结构或者内表是嵌套结构 结构中的字段属性可能也是一个结构
* kind 代表映射类型 可指定 1 2 3 9
DATA(mapper) =
cl_abap_corresponding=>create(
source = struct1
destination = struct2
mapping = VALUE cl_abap_corresponding=>mapping_table(
( level = 0 kind = 1 srcname = 'a1' dstname = 'b3' )
( level = 0 kind = 1 srcname = 'a3' dstname = 'b1' )
( level = 0 kind = 3 ) ) ).
*执行
mapper->execute( EXPORTING source = struct1
CHANGING destination = struct2 ).
cl_demo_output=>display( struct2 ).
官方文档对于kind的解释
CL_ABAP_CORRESPONDING=>MAPPING_COMPONENT (1) (The components specified in this row are mapped to each other.)
CL_ABAP_CORRESPONDING=>MAPPING_EXCEPT_COMPONENT (2) (The component of the source structure specified in this row is excluded from the mapping of identically named components.)
CL_ABAP_CORRESPONDING=>MAPPING_EXCEPT_ALL (3) (All components of the current source structure are excluded from the mapping of identically name components.)
CL_ABAP_CORRESPONDING=>MAPPING_DISCARDING_DUPLICATES (9) (In a source table, duplicate rows are ignored as when using [DISCARDING DUPLICATES](javascript:call_link('abencorresponding_constr_dupl.htm')) in a mapping rule of the component operator. The target table must have a unique table key.)
嵌套结构
*定义结构
DATA:
BEGIN OF struct1,
a1 TYPE string VALUE 'a1',
a2 TYPE string VALUE 'a2',
a3 TYPE string VALUE 'a3',
a4 TYPE string VALUE 'a4',
a5 TYPE string VALUE 'a5',
BEGIN OF asub1,
s1_a1 TYPE string VALUE 's1_a1',
s1_a2 TYPE string VALUE 's1_a2',
s1_a3 TYPE string VALUE 's1_a3',
BEGIN OF asub2,
s2_a1 TYPE string VALUE 's2_a1',
s2_a2 TYPE string VALUE 's2_a2',
s2_a3 TYPE string VALUE 's2_a3',
END OF asub2,
END OF asub1,
END OF struct1,
BEGIN OF struct2,
b1 TYPE string VALUE 'b1',
b2 TYPE string VALUE 'b2',
b3 TYPE string VALUE 'b3',
a4 TYPE string VALUE 'b4',
a5 TYPE string VALUE 'b5',
BEGIN OF bsub1,
s1_b1 TYPE string VALUE 's1_b1',
s1_b2 TYPE string VALUE 's1_b2',
s1_b3 TYPE string VALUE 's1_b3',
BEGIN OF bsub2,
s2_b1 TYPE string VALUE 's2_b1',
s2_b2 TYPE string VALUE 's2_b2',
s2_b3 TYPE string VALUE 's2_b3',
END OF bsub2,
END OF bsub1,
END OF struct2.
*定义映射表
DATA(mapping_tab) = VALUE cl_abap_corresponding=>mapping_table(
( level = 0 kind = 1 srcname = 'a1' dstname = 'b3' )
( level = 0 kind = 1 srcname = 'a3' dstname = 'b1' )
( level = 0 kind = 2 srcname = 'a5' )
( level = 0 kind = 1 srcname = 'asub1' dstname = 'bsub1' )
( level = 1 kind = 1 srcname = 's1_a1' dstname = 's1_b3' )
( level = 1 kind = 1 srcname = 's1_a3' dstname = 's1_b1' )
( level = 1 kind = 1 srcname = 'asub2' dstname = 'bsub2' )
( level = 2 kind = 1 srcname = 's2_a1' dstname = 's2_b3' )
( level = 2 kind = 1 srcname = 's2_a3' dstname = 's2_b1' ) ).
*执行
cl_abap_corresponding=>create(
source = struct1
destination = struct2
mapping = mapping_tab
)->execute( EXPORTING source = struct1
CHANGING destination = struct2 ).
内表
TYPES: BEGIN OF line1,
col1 TYPE i,
col2 TYPE i,
END OF line1,
BEGIN OF line2,
col2 TYPE i,
col3 TYPE i,
END OF line2.
*创建两个内表
DATA: itab1 TYPE TABLE OF line1 WITH EMPTY KEY,
itab2 TYPE TABLE OF line2 WITH EMPTY KEY.
* 添加数据
itab1 = VALUE #(
( col1 = 11 col2 = 12 )
( col1 = 21 col2 = 22 ) ).
itab2 = VALUE #(
( col2 = 212 col3 = 312 )
( col2 = 222 col3 = 322 ) ).
* 创建映射表
cl_abap_corresponding=>create(
source = itab1
destination = itab2
mapping = VALUE cl_abap_corresponding=>mapping_table(
( level = 0 kind = 1 srcname = 'col1' dstname = 'col2' )
( level = 0 kind = 1 srcname = 'col2' dstname = 'col3' ) )
)->execute( EXPORTING source = itab1
CHANGING destination = itab2 ).
动态声明变量的类型
FIELD-SYMBOLS: <f>.
DATA col__typ.
DATA dec TYPE i.
DATA length TYPE i.
ASSIGN input TO <f>.
* 判断传输参数的类型
DESCRIBE FIELD <f> TYPE col__typ.
** 判断传入参数的小数位数
DESCRIBE FIELD <f> DECIMALS dec.
* 获取传入参数的总长度
DESCRIBE FIELD <f> LENGTH length IN BYTE MODE.
DATA:
dref_i TYPE REF TO data,
elem_type TYPE REF TO cl_abap_elemdescr.
"创建基本类型,cl_abap_elemdesc类中提供了很多静态方法 可以去类中查看
elem_type ?= cl_abap_elemdescr=>get_p( EXPORTING p_length = length p_decimals = dec ).
*创建变量对象
CREATE DATA dref_i TYPE HANDLE elem_type .
*引用动态创建的变量
FIELD-SYMBOLS <output> TYPE any.
IF dref_i IS BOUND.
ASSIGN dref_i->* TO <output>.
ENDIF.
ABAP SQL中不同长度字段的关联
SELECT B~VBELN,
A~KSCHL
FROM NAST AS a
INNER JOIN VBRK AS B ON LEFT( a~OBJKY,10 ) = B~VBELN
WHERE ( B~VKORG BETWEEN 'A101' AND 'A103' )
AND A~KSCHL = 'ZGPB'
INTO TABLE @DATA(LT_NA).
ABAP SQL中with关键字的用法
感觉这个关键字类似于创建了一张临时表,我们可以在后面的sql中使用这张表,例如下面这个示例,需要按照销售订单和行号以及发票编号分组,由于发票中会有多个批次,体现在发票上就是多个行项目,但是我们并不关心批次,可以使用这种方式进行汇总之后再关联主要SQL获取数据
WITH +itab AS (
SELECT vbeln, aubel,aupos,FKDAT_ANA,
SUM( CASE vbrp~vbtyp_ana WHEN 'M' THEN fkimg ELSE 0 - fkimg END ) AS fkimg ,
SUM( CASE vbrp~vbtyp_ana WHEN 'M' THEN kzwi1 ELSE 0 - kzwi1 END ) AS zkpje
FROM vbrp WHERE aubel IN @s_vbeln AND vbeln IN @s_fp GROUP BY aubel, aupos,vbeln,FKDAT_ANA
)
SELECT
vbak~vbeln,
vbkd~bstkd,
vbak~kunnr,
vbak~vkorg, "组织
vbak~vtweg,"渠道
vbak~auart AS ddlx,
vbak~erdat,
vbkd~kdgrp,"客户类型
vbkd~bstdk,
vbap~posnr,
vbap~matnr,
vbap~arktx,
CASE vbak~auart WHEN 'ZOR' THEN kwmeng ELSE 0 - kwmeng END AS kwmeng,
CASE vbak~auart WHEN 'ZOR' THEN kbmeng ELSE 0 - kbmeng END AS kbmeng,
vbap~vrkme , "销售单位
vbap~umvkz,"销售单位和基本单位的换算因子
vbap~meins AS jbdw,"基本单位
CASE vbak~auart WHEN 'ZOR' THEN kzwi1 ELSE 0 - kzwi1 END AS zje,
vpa1~kunnr AS zywy,
zsdt0011d~z_dnum AS dm,
zsdt0011d~z_hnum AS hm,
zsdt0011d~je AS fpje,
zsdt0011d~se AS fpse,
bseg~belnr,
+itab~vbeln AS fp,
+itab~fkimg,
+itab~zkpje,
+itab~fkdat_ana as kprq
FROM vbak
INNER JOIN vbap ON vbap~vbeln = vbak~vbeln
LEFT JOIN +itab ON vbap~vbeln = +itab~aubel AND vbap~posnr = +itab~aupos
INNER JOIN vbkd ON vbak~vbeln = vbkd~vbeln AND vbkd~posnr = ''
LEFT JOIN vbpa AS vpa1 ON vbak~vbeln = vpa1~vbeln AND vpa1~parvw = 'Z1' "业务员
LEFT JOIN zsdt0011d ON zsdt0011d~djbh = +itab~vbeln
LEFT JOIN bseg ON koart = 'D' AND bseg~vbeln = +itab~vbeln
WHERE
vbak~vkorg IN @s_vkorg
AND vbak~erdat IN @s_erdat
AND vbak~vbeln IN @s_vbeln
AND vbak~kunnr IN @s_kunnr
AND vpa1~kunnr IN @s_ywy
AND +itab~aubel IN @s_fp
AND zsdt0011d~z_dnum IN @s_dm
AND zsdt0011d~z_hnum IN @s_hm
AND vbap~abgru = ''
INTO TABLE @DATA(table).
注意:
- with后面的表名必须要以
+开头 - 多个临时表使用逗号隔开即可,像下面这样
WITH
+wo AS ( SELECT aufk~auart,aufk~erdat,afih~iwerk,afih~ingpr,aufk~vaplz,afih~iloan,equnr,aufk~objnr
FROM aufk INNER JOIN afih
ON aufk~aufnr = afih~aufnr ),
+wocounts AS ( SELECT COUNT(*) AS wosum
FROM +wo ),
+co AS ( SELECT objnr,wrttp,
SUM( wtg001 + wtg002 + wtg003 + wtg004 + wtg005 + wtg006 + wtg007 + wtg008 ) AS cost01,
SUM( wtg009 + wtg010 + wtg011 + wtg012 + wtg013 + wtg014 + wtg015 + wtg016 ) AS cost02
from v_cosp_view
GROUP BY objnr,wrttp,versn
HAVING wrttp IN ('01','04')
AND versn = '000' )
SELECT +wo~auart,+wo~iloan,+wo~equnr,+co~wrttp,SUM( +wocounts~wosum ) AS wonum,
sum( cost01 ) as cost01,
sum( cost02 ) as cost02
FROM +wo CROSS JOIN +wocounts
INNER JOIN +co
ON +wo~objnr = +co~objnr
WHERE +wo~auart IN @s_auart
AND +wo~erdat IN @s_erdat
AND +wo~iwerk IN @s_iwerk
AND +wo~ingpr IN @s_ingpr
AND +wo~vaplz IN @s_vaplz
AND +wo~iloan IN (
SELECT iloan FROM iflot
INNER JOIN iflos
ON iflot~tplnr = iflos~tplnr
WHERE strno IN @s_strno AND actvs = 'X')
GROUP BY +wo~auart,+wo~iloan,+wo~equnr,wrttp
INTO TABLE @DATA(lt_basic).
内表转ranges
FOR ALL ENTRIES IN这个关键字是在我们经常需要使用的,但是使用了该关键字之后,ABAP SQL中很多功能就无法使用,例如group by就无法和FOR ALL ENTRIES IN同时使用,那么这个问题我们就可以使用ranges解决,此时就需要将我们内表中的数据转移到ranges中,使用loop的方式感觉不太优雅,我们可以使用下面这个方式,实际上就是在Value中遍历该内表
data r_vbeln type RANGE OF sy-index.
DATA: BEGIN OF vbeln OCCURS 0,
col LIKE sy-index,
END OF vbeln.
*向内表添加假数据
DO 10 TIMES.
vbeln-col = sy-index.
APPEND vbeln.
ENDDO.
r_vbeln = VALUE #( for wa_vbeln in vbeln (
sign = 'I' option = 'EQ' low = wa_vbeln-col
) ).
range的定义方式有两种,但是通过这种方式给range赋值只适用于第二种定义的方式
ranges:s_vbeln for vbak-vbeln.
data:s_vbeln type range of vbak-vbeln.

浙公网安备 33010602011771号