假设现在有这样一个内表
TYPES: BEGIN OF TY_DATA,
INDEX TYPE CHAR1,
DATA TYPE CHAR2,
END OF TY_DATA.
DATA LT_DATA TYPE TABLE OF TY_DATA.
LT_DATA = VALUE #(
( INDEX = '1' DATA = 'AA' )
( INDEX = '2' DATA = 'BB' )
( INDEX = '3' DATA = 'CC' )
( INDEX = '' DATA = '' )
).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LT_DATA ).
现在我们要取得这个内表里面的第二条数据,那么我们需要怎么做呢?
READ TABLE LT_DATA INTO DATA(LW_DATA) WITH KEY DATA = 'BB' .
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
ABAP新语法中,提供了新的内表访问方式,大概类似于C和java的数组操作
语法格式如下:itab[ index ] itab[KEY = value ]
index可以使用内表行数,注意如果是纵深列表,那么允许使用和数组一样的方式 itab[ index ][index]
.
需要注意的是C或者JAVA的数组下标从0开始,但是这里内表下标是从1开始
ABAP新语法方式:
DATA(test) = itab[ index(或者表达式)].
或者
DATA(test) = VALUE #( itab[ index(或者表达式) ] OPTIONAL ).
本例中:
DATA(LW_DATA) = LT_DATA[ 2 ].
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
或者
DATA(LW_DATA) = LT_DATA[ DATA = 'BB' ].
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
或者
DATA(LW_DATA) = VALUE #( LT_DATA[ 2 ] OPTIONAL ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
或者:
DATA(LW_DATA) = VALUE #( LT_DATA[ DATA = 'BB' ] OPTIONAL ).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
结果都是一样的
使用DATA(LW_DATA) = LT_DATA[ 5 ].
的时候返回不到会dump,因为没有catch 到异常:cx_sy_itab_line_not_found
。而try catch的话就会发现一个问题,那就是我并没有节省工作量啊,甚至好像还多了点。
所以使用第二种VALUE方式DATA(LW_DATA) = VALUE #( LT_DATA[ 5 ] OPTIONAL ).
这样会自动catch到异常。也就是说不会报错,也能读到相应的值,感觉是不是很赞?
但是问题,就这么忽然的来了,不管能不能访问到,sy-subrc的返回值都是0.
1、访问不到的情况:
DATA(LW_DATA) = VALUE #( LT_DATA[ 5 ] OPTIONAL ).
IF SY-SUBRC = 0.
WRITE: / 'E'.
ENDIF.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
2、访问到情况
DATA(LW_DATA) = VALUE #( LT_DATA[ 2 ] OPTIONAL ).
IF SY-SUBRC = 0.
WRITE: / 'E'.
ENDIF.
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
也就是说是忽略错误的。所以我怎么知道是访问不到,还是访问到的就是空呢?要知道内表是允许放置空行的。
比如我访问DATA(LW_DATA) = VALUE #( LT_DATA[ DATA = 'DD' ] OPTIONAL ).
和DATA(LW_DATA) = VALUE #( LT_DATA[ 4 ] OPTIONAL ).
这两种的结果都如下图所示:
经过查阅官方文档(并没有给出什么具体的解决方案),有另一个语法可以近似的进行判定
即加一个DEFAULT
DATA(LW_DATA) = VALUE #( LT_DATA[ DATA = 'DD' ]
DEFAULT VALUE #( DATA = 'EE' )
).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
DATA(LW_DATA) = VALUE #( LT_DATA[ 4 ]
DEFAULT VALUE #( DATA = 'EE' )
).
CALL METHOD CL_DEMO_OUTPUT=>DISPLAY( LW_DATA ).
相信看到 DEFAULT就已经明白了,如果取不到相关的值,就用一个默认值进行替代,我们可以通过这个默认值来判定是否有相关的行,只能说是一个很粗糙的解决方案了。