ABAP7.4から導入された構文
はじめに
ABAP7.4で、ABAPに色々な革新がもたらされました。
ABAP7.4は2013年にリリースされており新しいものではありませんが、私はこれまでに見たことや使ったことがありませんでした。
この記事では、筆者の独断で「便利だ」「使ってみたい」と感じた機能について紹介します。
ABAP7.4でリリースされた機能についての詳細は、末尾にあるリンクを参考にしてください。
ABAP7.4で何が良くなったのか
・変数の宣言が楽になった
・中間変数を減らせるので、コードを短くできる
紹介する機能
- 変数宣言
- 内部テーブルの操作
- 内部テーブルの宣言
- 内部テーブルの読み込み
- 内部テーブルへの値の設定
- 特定の行のインデックスを取得する(line_index)
- 指定した行が存在するかどうかを確認する(line_exists)
- 内部テーブルAの指定の項目を内部テーブルBへ格納
- 内部テーブルAの条件と一致するのを内部テーブルBへ格納
- 内部テーブルの中で指定の条件と一致するレコード数カウント
- 型変換
- 文字列操作
- 文字列編集処理の結果を項目に設定する
- 文字列編集用機能(String Functions)一覧
- 条件分岐
- 構造
- 追加予定
- その他サンプル
- 終わりに
1,変数宣言
変数の定義
<ABAP7.4より前>
・変数はプログラムやルーチンの先頭でまとめて定義する
・宣言時に型の定義が必要
DATA l_str type string. l_str = 'hello'.
<ABAP7.4以降>
・変数は使いたい場所で宣言すればよい
・コンパイラが型を判断してくれる
DATA(l_str) = 'hello'.
メソッド呼び出し時の引数
メソッドから受け取る引数も、DATAを使用してその場で定義できます。
一方、汎用モジュールではDATAを利用した引数の定義はできませんでした。残念!
CALL METHOD cl_reca_date=>get_current_date
EXPORTING
id_timezone = sy-zonlo
IMPORTING
ed_time = DATA(l_time)
ed_date = DATA(l_date)
ed_timestamp = DATA(l_timestamp)
.
2,内部テーブルの操作
2-1、内部テーブルの宣言
内部テーブルはDBを読み込むのに使うことが多いと思います。DATA宣言を使うと、SELECTで指定した項目を持つ内部テーブルを自動的に作ることができます。
DATA(l_mtart) = 'ROH'. SELECT matnr, mtart FROM mara INTO TABLE @DATA(itab_mara) WHERE mtart = @l_mtart.
※SQL内で変数を使う場合は先頭に@をつけます。(データ定義か否かにかかわらず)
2-2、内部テーブルの読み込み
ワークエリアの作成
内部テーブルをループしてワークエリアに読み込むとき、内部テーブルの型を参照して自動的にワークエリアを作ることができます。
LOOP AT itab_mara INTO DATA(wa_mara). WRITE: / wa_mara-matnr, wa-mtart. ENDLOOP.
フィールドシンボルも使えます。
LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs_mara>). WRITE: / <fs_mara>-matnr, <fs_mara>-mtart. ENDLOOP.
指定した行を読み込む方法
<ABAP7.4より前>
・内部テーブルを読み込む際はインデックス、またはキーを指定してワークエリアに行を格納する
DATA: wa_mara LIKE LINE OF itab_mara. READ TABLE itab_mara INTO w_mara INDEX 1. READ TABLE itab_mara INTO w_mara WITH KEY matnr = 'BRICK002'.
<ABAP7.4以降>
・インデックスやキーを指定して直接行にアクセスできる
" インデックスを指定 wa_mara = itab_mara[ 1 ]. " キーを指定 wa_mara = itab_mara[ matnr = 'BRICK002' ].
データが読み込めない場合、例外CX_SY_ITAB_LINE_NOT_FOUNDが発生します。
ABAP7.4 SP8からは、例外が発生しないようにOPTIONALまたはDEFAULTを指定できるようになりました(VALUE #と組み合わせること)。
OPTIONALを指定した場合は、READ TABLEで対象の行がなかった場合と同じように初期値が返されます。
wa_mara = VALUE #( itab_mara[ matnr = 'BRICK002b' ] OPTIONAL ).
2-3、内部テーブルへの値の設定
直接値を設定する
<ABAP7.4より前>
・ワークエリアで値を編集し、それを内部テーブルに格納する
DATA: lr_sel_mara TYPE RANGE OF mtart,
wa_sel_mara LIKE LINE OF lr_sel_mara.
wa_sel_mara-sign = 'I'.
wa_sel_mara-option = 'EQ'.
wa_sel_mara-low = 'ROH'.
APPEND wa_sel_mara TO lr_sel_mara.
wa_sel_mara-low = 'HAWA'.
APPEND wa_sel_mara TO lr_sel_mara.
<ABAP7.4以降>
・VALUEを使って内部テーブルに値を直接入れることができる
構文その1: VALUE <型> ((行データ1) (行データ2)...)
型を明示的に指定する方法です。
TYPES: t_sel_mara TYPE RANGE OF mtart.
DATA(lr_sel_mara2) = VALUE t_sel_mara(
( sign = 'I' option = 'EQ' low = 'ROH')
( sign = 'I' option = 'EQ' low = 'HAWA')
).
構文その2: VALUE # ((行データ1) (行データ2)...)
テーブルの型が設定先の変数から推測できる場合はこちらの構文が使えます。
DATA: lr_sel_mara3 TYPE RANGE OF mtart.
lr_sel_mara3 = VALUE #(
( sign = 'I' option = 'EQ' low = 'ROH')
( sign = 'I' option = 'EQ' low = 'HAWA')
).
sign, optionが共通の場合、次のような書き方もできます。
lr_sel_mara3 = VALUE #(
sign = 'I' option = 'EQ' ( low = 'ROH')
( low = 'HAWA')
).
条件に該当する複数データの中で1レコードのみ格納する
DATA: it_data1 type tat_data,
it_data2 type tat_vbap.
it_data1 = CORRESPONDING tat_data(
it_data2 DISCARDING DUPLICATES
MAPPING vbelng = vbelng ).
内部テーブルデータ格納
格納先内部テーブル = VALUE #( BASE 格納先内部テーブル
( 項目ID1 = 構造-項目ID1
項目ID2 = 構造-項目ID2 ) ).
* 内部テーブル定義されてない場合
DATA(it_data) = VALUE tty_data( ( comp1 = 1 comp2 = 'name1' )
( comp1 = 2 comp2 = 'name2' )
( comp1 = 3 comp2 = 'name3' ) ).
* 内部テーブル定義されている場合
it_data = VALUE #( ( comp1 = 1 comp2 = 'name1' )
( comp1 = 2 comp2 = 'name2' )
( comp1 = 3 comp2 = 'name3' ) ).
* 同一値設定する場合
it_data = VALUE #( comp1 = 1 ( comp2 = 'name1' )
( comp2 = 'name2' )
( comp2 = 'name3' ) ).
内部テーブルを上書きせずに追加
「BASE 内部テーブル」
it_data = VALUE #( BASE it_data
( comp1 = 4 comp2 = 'name4' )
( comp1 = 5 comp2 = 'name5' )
( comp1 = 6 comp2 = 'name6' ) ).
「LINES OF 内部テーブル」
* 内部テーブル定義した際、既存の内部テーブル(it_data)のレコードを追加
DATA(it_data2) = VALUE tty_data( ( comp1 = 10 comp2 = 'name10' )
( LINES OF it_data ) ).
2‐4、特定の行のインデックスを取得する(line_index)
<ABAP7.4より前>
・READ TABLEなどで行を読み込み、sy-tabixを取得する
DATA: l_index type sy-tabix. READ TABLE itab_mara TRANSPORTING NO FIELDS with key matnr = 'BRICK002'. l_index = sy-tabix.
<ABAP7.4以降>
・line_index命令でインデックスを取得できる
l_index = line_index( itab_mara[ matnr = 'BRICK002' ] ).
2‐5、指定した行が存在するかどうかを確認する(line_exists)
<ABAP7.4より前>
・READ TABLEして、sy-subrcの値で判断する
READ TABLE itab_mara TRANSPORTING NO FIELDS WITH KEY matnr = 'BRICK002'. IF sy-subrc = 0. "存在する場合の処理 ELSE. "存在しない場合の処理 ENDIF.
<ABAP7.4以降>
・line_exists命令で判断できる
line_existsはブール値を返します。
ABAP7.4から、IF条件の結果がtureのときは if <変数> = abap_trueという風にabap_trueを書かなくてもよくなったので、以下のような簡潔な書き方ができます。
IF line_exists( itab_mara[ matnr = 'BRICK002' ] ). "存在する場合の処理 ELSE. "存在しない場合の処理 ENDIF.
存在チェック
SELECT FROM MARA as t1 FIELDS @abap_on where … into @lw_exist_chk. if lw_exist_chk. "「= abap_on」の記述を省略 " データが存在した場合のロジック else. " データが存在しなかった場合のロジック endif.
2‐6、内部テーブルAの指定の項目を内部テーブルBへ格納
例文①
<ABAP7.4より前>
DATA: lt_citys TYPE ta_citys,
ls_ship TYPE ta_ship,
ls_city TYPE ort01.
LOOP AT gt_ships INTO ls_ship.
ls_city = ls_ship-city.
APPEND ls_city TO gt_citys.
ENDLOOP.
<ABAP7.4以降>
DATA(gt_citys) = VALUE ta_citys( FOR ls_ship IN gt_ships ( ls_ship-city ) ).
2‐7、内部テーブルAの条件と一致するのを内部テーブルBへ格納
例文①
<ABAP7.4より前>
DATA: gt_citys TYPE ty_citys,
ls_ship TYPE ty_ship,
ls_city TYPE ort01.
LOOP AT gt_ships INTO ls_ship WHERE route = 'R0001'.
ls_city = ls_ship-city.
APPEND ls_city TO gt_citys.
ENDLOOP.
<ABAP7.4以降>
DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships
WHERE ( route = 'R0001' ) ( ls_ship-city ) ).
例文②:
V. FOR with THEN and UNTIL|WHILE
FOR i = ... [THEN expr] UNTIL|WHILE log_exp
<ABAP7.4より前>
TYPES:
BEGIN OF ty_line,
col1 TYPE i,
col2 TYPE i,
col3 TYPE i,
END OF ty_line,
ty_tab TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.
DATA: gt_itab TYPE ty_tab,
j TYPE i.
FIELD-SYMBOLS <ls_tab> TYPE ty_line.j= 1.
DO.
j = j + 10.
IF j > 40. EXIT. ENDIF.
APPEND INITIAL LINE TO gt_itab ASSIGNING <ls_tab>.
<ls_tab>-col1 = j.
<ls_tab>-col2 = j + 1.
<ls_tab>-col3 = j + 2.
ENDDO.
<ABAP7.4以降>
DATA(gt_itab) = VALUE ty_tab( FOR j = 11 THEN j + 10 UNTIL j > 40
( col1 = j col2 = j + 1 col3 = j + 2 ) ).
例文③
内部テーブル = VALUE #( FOR カウンター THEN カウンター演算 UNTIL 繰り返し処理を終了する条件 ( 項目1 = 値 項目2 = 値 … ) ).
<ABAP7.4より前>
* 内部テーブルに10レコード分格納 DO 10 TIMES. l_cnt = l_cnt + 1. CLEAR wa_data. wa_data-comp1 = l_cnt. wa_data-comp2 = 'name' && l_cnt. APPEND wa_data TO it_data. ENDDO.
<ABAP7.4以降>
* 内部テーブルに10レコード分格納
it_data = VALUE #( FOR l_cnt_temp = 1 THEN l_cnt_temp + 1 UNTIL l_cnt_temp > 10
( comp1 = l_cnt_temp comp2 = 'name' && l_cnt ) ).
例文④
内部テーブル = VALUE #( FOR 構造 IN 内部テーブル WHERE ( 条件 ) ( 項目1 = 値 項目2 = 値 … ) ).
<ABAP7.4より前>
* 内部テーブルのcomp1が4より大きい際にRANGEテーブルを作成
LOOP AT it_data INTO wa_data WHERE comp1 > 4.
wa_range-sign = 'I'.
wa_range-option = 'EQ'.
wa_range-low = wa_data-comp2.
APPEND wa_range TO it_range.
CLEAR:
wa_data.
ENDLOOP.
<ABAP7.4以降>
* 内部テーブルのcomp1が4より大きい際にRANGEテーブルを作成
it_range = VALUE #( FOR wa_data_temp IN it_data
WHERE ( comp1 > 4 )
( sign = 'I'
option = 'EQ'
low = wa_data_temp-comp2 ) ).
2‐8、内部テーブルの中で指定の条件と一致するレコード数カウント
<ABAP7.4より前>
DATA: lv_lines TYPE i. LOOP AT gt_itab INTO ls_itab where F1 = ‘XYZ’. lv_lines = lv_lines + 1. ENDLOOP.
<ABAP7.4以降>
DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab
WHERE( F1 = ‘XYZ’ ) NEXT x = x + 1 ).
3,型変換
サブルーチンで受け取った引数を汎用モジュールなどに渡すとき、汎用モジュールの型に合わせるために中間変数を定義したことはないでしょうか?
<ABAP7.4より前>
・中間変数に引数を格納して型変換し、汎用モジュール等に渡す
DATA: im_text(50) TYPE c,
l_str TYPE string, "中間変数
l_xstr TYPE xstring.
im_text = 'Hello'.
l_str = im_text.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = l_str
IMPORTING
buffer = l_xstr
.
<ABAP7.4以降>
・CONV命令で直接型を変換できる
・VALUEと同じく、型を明示的に指定する方法と#で暗黙的に指定する方法がある
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = CONV string( im_text ) "明示的に型を指定
IMPORTING
buffer = l_xstr
.
3-1、Alpha変換
Alpha変換とは、内部書式(前ゼロつき)と外部書式(前ゼロなし)の変換のことです。
<ABAP7.4より前>
・汎用モジュール'CONVERSION_EXIT_ALPHA_INPUT'/'CONVERSION_EXIT_ALPHA_OUTPUT'を使って変換する
DATA: lv_input TYPE ebeln.
DATA: lv_output TYPE ebeln.
lv_input = 12345.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = lv_input
IMPORTING
output = lv_output. "0000012345
<ABAP7.4以降>
・|{ <変数> ALPHA = IN / OUT }|で変換できる
DATA: lv_input TYPE ebeln.
DATA: lv_output TYPE ebeln.
lv_input = 12345.
lv_output = |{ lv_input alpha = IN }|. "0000012345
4,文字列操作
4‐1、文字列結合
<ABAP7.4より前>
・CONCATENATEで文字列を結合
・結合する文字列の中にクォーテーション(')を使いたい場合、エスケープする必要がある
DATA: im_comment(10) TYPE c,
l_out TYPE string.
im_comment = 'Hello!'.
CONCATENATE 'He said' '''' im_comment '''' INTO l_out SEPARATED BY space.
<ABAP7.4以降>
・||で囲った中にリテラルや変数を直接書き込むことができる
・変数は{}で囲む
l_out = |He said '{ im_comment }'|.
l_out2 = |Date: { sy-datum } Time: { sy-uzeit }|.
FIELDS
'PARTNER NAME IS ' && ADRC~name1 && ' ' && ADRC~name2 as FIELD1 "&&で結合した場合
CONCAT( 'PARTNER NAME IS ' ,
concat_with_space( ADRC~name1, ADRC~name2, 1 ) ) as field1 "CONCAT系で書いた場合
5,文字列編集処理の結果を項目に設定する
SELECT FROM sflight
FIELDS
@abap_on AS check, "固定値
carrid,
connid,
concat_with_space( carrid,connid,4 ) AS cws,
left( planetype, 3 ) AS plane_series1,
length( planetype ) as plane_series2,
lpad( CAST( paymentsum AS CHAR ) , 20, '0' ) AS paymentsum_char,
concat_with_space( CAST( seatsmax_b AS CHAR ), CAST( seatsocc_b AS CHAR ), 2 ) AS field_concat
INTO TABLE @DATA(results).
REPORT demo_sql_function_string.
CLASS demo DEFINITION.
PUBLIC SECTION.
CLASS-METHODS main.
ENDCLASS.
CLASS demo IMPLEMENTATION.
METHOD main.
DELETE FROM demo_expressions.
INSERT demo_expressions FROM TABLE @( VALUE #(
( id = 'X'
char1 = ' 0123'
char2 = 'aAaA' ) ) ).
SELECT SINGLE
char1 AS text1,
char2 AS text2,
CONCAT( char1,char2 ) AS concat,
CONCAT_WITH_SPACE( char1,char2, 1 ) AS concat_with_space,
INSTR( char1,'12' ) AS instr,
LEFT( char1,3 ) AS left,
LENGTH( char1 ) AS length,
LOWER( char2 ) AS lower,
LPAD( char1,10,'x' ) AS lpad,
LTRIM( char1,' ' ) AS ltrim,
REPLACE( char1,'12','__' ) AS replace,
RIGHT( char1,3 ) as right,
RPAD( char1,10,'x' ) AS rpad,
RTRIM( char1,'3' ) AS rtrim,
SUBSTRING( char1,3,3 ) AS substring,
UPPER( char2 ) AS upper
FROM demo_expressions
INTO @DATA(result).
cl_demo_output=>display( result ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
demo=>main( ).
6,文字列編集用機能(String Functions)一覧
文字列項目処理用の機能概要を以下一覧にまとめます。
| 機能 | 説明 |
|---|---|
| LOWER | 対象値内の1バイト英大文字を英小文字に変換 |
| UPPER | 対象値内の1バイト英小文字を英大文字に変換 |
| CONCAT | 2項目の文字列結合。各項目の後ろの1バイトスペースは無視される。 ※3項目以上の場合はネストする |
| CONCAT_WITH_SPACE | CONCATと同様だが、文字列間に1バイトスペースを指定数分設定する |
| LEFT | 対象値の左側から、文字数分の内容を取得 |
| LPAD | 対象値の左側から、指定した長さまで指定文字で埋める |
| LTRIM | 対象値の左側から、指定文字を除去 |
| RIGHT | 対象値の右側から、文字数分の内容を取得 |
| RPAD | 対象値の右側から、指定した長さまで指定文字で埋める |
| RTRIM | 対象値の右側から、指定文字を除去 |
| INSTR | 対象値の中で指定値が最初に発生する位置を返す ※位置が1文字目の場合は1 |
| LENGTH | 文字列の文字数を取得 |
| REPLACE | 対象値内にある変換前値すべてを、変換後値に変換 |
| SUBSTRING | 対象値の指定位置から、指定文字数分の内容を取得 |
7,条件分岐
7-1、CASEによる条件分岐
①
CASE kwmeng "演算値、編集加工値なども使用可能
WHEN 0 THEN 0 "WHENは最低1つ必要。THENが必要
WHEN 1 THEN netwr "2つめ以降のWHENは省略可能
ELSE division( netwr , kwmeng, 3 ) "ELSE省略可能
END AS calc2, "ENDCASEではなくENDに
②
CASE "何も書かない
WHEN matnr is initial THEN 'MATERIAL IS BLANK' "各判定条件をWHENの後に記述
WHEN matnr = 'DUMMY' and TYPE = 'DUNNY' THEN 'DUMMY MATERIAL' "複数の判定条件を書くことが可能
WHEN matnr <> 'DUMMY' and TYPE = 'DUMMY' THEN 'INVALID DATA'
WHEN matnr = 'DUMMY' and TYPE <> 'DUMMY' THEN 'INVALID DATA'
else 'VALID DATA'
END AS ERRMSG1
7‐2,COALESCEによる条件分岐
COALESCE( A, B, C, D ) as FIELD1
上記の場合、A、B、Cの順番で値が確認され、最初にNull値でない値があるとその値がFIELD1に設定されます。
もし、すべての値がNullの場合は、最後に設定されたdの値が設定されます。
上記をCASEで書き換えると以下のようになります。
7‐3、CASTによる型変換
DELETE FROM demo_expressions.
INSERT demo_expressions FROM @( VALUE #(
id = 'X'
num1 = 111 "INT4型
numlong1 = '12345678' "INT8型
dec3 = '123.456' "DEC型
dats2 = sy-datum "DATS型
char1 = 'ABCDEFGHIJ' "CHAR型
char2 = '0000123456' "NUMC型
) ).
SELECT SINGLE
FROM demo_expressions
FIELDS
CAST( num1 AS CHAR( 20 ) ) AS col1,
CAST( numlong1 AS DEC( 12, 3 ) ) AS col2,
CAST( dec3 AS CURR( 10, 2 ) ) AS col3,
CAST( dats2 AS CHAR( 20 ) ) AS col4,
CAST( char1 AS CHAR( 4 ) ) AS col5,
CAST( char2 AS NUMC( 5 ) ) AS col6,
CAST( concat( @sy-datlo, @sy-timlo ) AS char( 20 ) ) AS col7
WHERE id = 'X'
INTO @DATA(results).
cl_demo_output=>display( results ).
変換前型と変換後型の組み合わせで一部制限があり、下記SAPHELPにて一覧化されています。
8,構造(ワークエリア)
8-1、項目設定
<ABAP7.4より前>
* データ型定義
TYPES:
BEGIN OF ty_data,
comp1 TYPE i,
comp2 TYPE string,
END OF ty_data.
* 構造定義
DATA:
wa_data TYPE ty_data.
* 構造へデータ設定
wa_data-comp1 = 1.
wa_data-comp2 = 'name1'.
<ABAP7.4以降>
①
* データ型定義
TYPES:
BEGIN OF ty_data,
comp1 TYPE i,
comp2 TYPE string,
END OF ty_data.
* 構造へデータ設定
DATA(wa_data) = VALUE ty_data( comp1 = 1 comp2 = 'name1' ).
②
* 構造へデータ設定 wa_data = VALUE #( comp1 = 1 comp2 = 'name1' ).
REPORT Z_ABAP_BP_CORRESPONDING.
CLASS DEMO_CORRESPONDING DEFINITION.
PUBLIC SECTION.
CLASS-METHODS main.
ENDCLASS.
CLASS DEMO_CORRESPONDING IMPLEMENTATION.
METHOD main.
TYPES: BEGIN OF line1,
Name TYPE C LENGTH 50,
age TYPE i,
salary TYPE P LENGTH 10 DECIMALS 2,
END OF line1,
BEGIN OF line2,
name TYPE C LENGTH 50,
age TYPE i,
END OF line2,
BEGIN OF line3,
name TYPE C LENGTH 50,
salary TYPE P LENGTH 10 DECIMALS 2,
END OF line3.
DATA: itab1 TYPE TABLE OF line1 WITH EMPTY KEY,
itab2 TYPE TABLE OF line2 WITH EMPTY KEY,
itab3 TYPE TABLE OF line3 WITH EMPTY KEY.
DATA(out) = cl_demo_output=>new( ).
itab1 = VALUE #(
( name = 'John' age = 32 salary = '3500')
( name = 'Mary' age = 33 salary = '3534') ).
out->write( itab1 ).
cl_abap_corresponding=>create(
source = itab1
destination = itab2
mapping = VALUE cl_abap_corresponding=>mapping_table( )
)->execute( EXPORTING source = itab1
CHANGING destination = itab2 ).
out->write( itab2 ).
cl_abap_corresponding=>create(
source = itab1
destination = itab2
mapping = VALUE cl_abap_corresponding=>mapping_table(
( level = 0 kind = 1 srcname = 'name' dstname = 'name' )
( level = 0 kind = 1 srcname = 'age' dstname = 'age' ) )
)->execute( EXPORTING source = itab1
CHANGING destination = itab2 ).
out->write( itab2 ).
cl_abap_corresponding=>create(
source = itab1
destination = itab3
mapping = VALUE cl_abap_corresponding=>mapping_table( )
)->execute( EXPORTING source = itab1
CHANGING destination = itab3 ).
out->write( itab3 ).
out->display( ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
demo_corresponding=>main( ).
See the results:
Topへ
おわりに
ここで紹介した以外にも、ABAP7.4で登場した構文は色々あります。以下のブログがよくまとまっていておすすめなので興味のある方は読んでみてください。
ABAP 7.40 Quick Reference
参考
ABAP News for Release 7.40 – What is ABAP 7.40?
ABAP News for 7.40, SP08 – More for Internal Tables
ABAP to the Future
ABAP 7.40 Quick Reference


浙公网安备 33010602011771号