ABAP 開發系列(05): ABAP 內表與內表結構
2.內表和內表結構
2.1.1 結構體的定義
ABAP 中可以定義結構來包含多個基本型別,便於整理及操作;
結構體不屬於資料字典物件(資料字典中可以定義結構體,但不能儲存資料),在程式執行時會被作為臨時物件儲存在記憶體空間;
在建立內表時,可參考直接定義的結構體作為內表結構。
結構體的定義,可以通過兩種方式實現:
1.第一種方式
語法:
DATA: BEGIN OF <name>
<field1> . . .
<field2> . . .
. . .
END OF <name>.
如:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 |
TABLES : TABNA.
DATA :
BEGIN OF
ADDRESS,
FLAG
TYPE C,
ID
LIKE TABNA- ID ,
NAME1
LIKE TABNA-NAME1,
CITY
LIKE TABNA-CITY,
END
OF ADDRESS.
* 為結構體欄位賦值
MOVE
'X' TO
ADDRESS-FLAG.
MOVE
'0001' TO
ADDRESS- ID .
MOVE
'Smith' TO
ADDRESS-NAME1.
MOVE
'Philadelphia' TO
ADDRESS-CITY. WRITE
ADDRESS.
|
2.第二種方式
語法:
TYPES: BEGIN OF <name1>,
<field1> . . . ,
<field2> . . . ,
. . . ,
END OF <name1>.
DATA: <name2> TYPE <name1>.
如:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 |
TYPES :
BEGIN OF
ADDR,
FLAG,
ID
LIKE EMPLOYEE- ID ,
NAME1
LIKE EMPLOYEE-NAME1, CITY
LIKE EMPLOYEE-CITY,
END
OF ADDR.
DATA : ADDRESS
TYPE ADDR.
MOVE :
'X'
TO ADDRESS-FLAG,
'00001'
TO ADDRESS- ID ,
'Smith'
TO ADDRESS-NAME1,
'Philadelphia'
TO ADDRESS-CITY.
WRITE
ADDRESS.
|
2.1.2 結構體的賦值
相同結構體之間可以通過 MOVE … TO … 語句進行賦值;
如若存在型別差異的結構體,則可以通過 MOVE-CORRESSPONDING … TO … 語句將兩個結構體之間相同欄位自動匹配賦值:
與基本變數定義類似,結構體的初始化操作也可以通過 CLEAR 語句實現。
如:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 |
TABLES : employee.
DATA :
BEGIN OF
address,
flag,
id
LIKE employee-id,
name
LIKE employee-name1,
city
LIKE employee-city,
END
OF ADDRESS.
SELECT
* FROM employee.
MOVE - CORRESPONDING
employee TO
address.
WRITE : / address-flag, address-id,
address-name, address-city.
CLEAR
address.
ENDSELECT .
|
內表與結構體基本類似,同樣在程式執行過程中儲存在臨時建立的記憶體空間,它是一個可以儲存多條記錄的資料表。
2.2.1 內表的定義
通過關鍵字DATA定義內表,可以直接參考結構體或者其他內表及透明表結構,也可以直接定義結構欄位。
語法:
①.DATA <NAME> TYPE <STRUCTURE> WITH [UNIQUE|NON-UNIQUE] [INITIAL SIZE n] [WITH HEADER LINE].
②.DATA <NAME> LIKE TABLE OF <TABLE> WITH [UNIQUE|NON-UNIQUE] [INITIAL SIZE n] [WITH HEADER LINE].
③.DATA: BEGIN OF itab OCCURS n,
<field>
<field>
END OF itab.
其中,關鍵字說明如下:
[UNIQUE|NON-UNIQUE]: 指定關鍵字,只用於排序表,使用NON-UNIQUE關鍵字的話,排序表資料記錄允許重複關鍵字欄位;
[INITIAL SIZE n]:指定初始化內表大小,比較少用,一般預設即可;
[WITH HEADER LINE]: 定義內表是否帶表頭;
01 02 03 04 05 06 07 08 09 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 |
*--------------------------------------------------------------------*
* 通過定義結構體並參考該結構定義內表
*--------------------------------------------------------------------*
TABLES : employee.
"參考某一透明表,必須先引用定義
TYPES :
BEGIN OF
emp,
id
LIKE employee-id,
name1
LIKE employee-name1,
country
LIKE employee-country,
END
OF emp.
*--------------------------------------------------------------------*
* 參考EMP 結構定義一個初始化大小為10,並有HEADER LINE的內表
*--------------------------------------------------------------------*
DATA : emptab
TYPE STANDARD
TABLE OF
emp INITIAL SIZE
10 WITH
HEADER LINE .
*--------------------------------------------------------------------*
* 參考EMPTAB內表,重新定義沒有HEADER LINE的內表
*--------------------------------------------------------------------*
DATA : emptab_n
LIKE STANDARD
TABLE OF
emptab.
*--------------------------------------------------------------------*
* 定義一個允許重複KEY,並且沒有HEADER LINE的排序表
*--------------------------------------------------------------------*
DATA : emptab_s
TYPE SORT
TABLE OF
emp WITH NON - UNIQUE
KEY id.
*--------------------------------------------------------------------*
* 通過第三種方式定義的內表,可指定具體欄位,預設內表存在HEADER LINE
*--------------------------------------------------------------------*
TYPES :
BEGIN OF
emp OCCURS
0,
id
LIKE employee-id,
name1
LIKE employee-name1,
country
LIKE employee-country,
END
OF emp.
|
2.2.2 內表有無 HEADER LINE 的區別
對於有HEADER LINE的內表,可以通過填充HEADER LINE資料後或通過 向內表儲存空間中追加資料。
對於沒有HEADER LINE的內表,只能通過 來傳遞資料:
語法:
①.APPEND [<Work Area> INTO] <ITAB>.
如:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
TABLES : employee.
TYPES :
BEGIN OF
emp,
id
LIKE employee-id,
name1
LIKE employee-name1,
country
LIKE employee-country,
END
OF emp.
* 有 HEADER LINE 的內表
DATA : emptab
TYPE STANDARD
TABLE OF
emp INITIAL SIZE
10 WITH
HEADER LINE .
* 沒有 HEADER LINE 的內表
DATA : emptab2
TYPE STANDARD
TABLE OF
emp INITIAL SIZE
10,
* Work Area
emptab_wa
TYPE emp.
SELECT
* FROM employee.
MOVE - CORRESPONDING
employee TO
emptab.
APPEND
emptab.
MOVE - CORRESPONDING
employee TO
emptab_wa.
APPEND
emptab_wa TO
emptab2.
ENDSELECT .
|
由於沒有HEADER LINE的內表通過Work Area 傳遞資料在效能上會優於HEADER LINE直接填充HEADER LINE,
所以,一般基本都使用沒有 HEADER LINE 的內表。
除非一些特殊情況,才會使用 HEADER LINE 內表。
2.2.3 內表資料處理
1. 遍歷讀取內表資料 (LOOP … ENDLOOP.)
01 02 03 04 05 06 07 08 09 10 11 |
LOOP
AT emptab WHERE
country BETWEEN
‘A’ AND
‘D’.
WRITE : / emptab-country, emptab-name1, emptab-sales.
ENDLOOP .
IF
sy-subrc NE 0.
WRITE : / ‘ NO
ENTRIES ’.
ENDIF .
|
解析:
a.LOOP 語句後,允許使用WHERE語句篩選資料。
b.程式中,出現 sy-subrc 變數,這是系統全域性變數,用於檢查是否符合條件,
如若符合條件 sy-subrc 返回0 ,如果不符合,則返回4.
2. 讀取內表資料 (READ TABLE …)
在資料內表,可以通過READ TABLE關鍵字根據具體行數或主鍵欄位讀取內表中的某行記錄:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 |
TABLES : employee.
TYPES :
BEGIN OF
emp,
country
LIKE employee-country,
name1
LIKE employee-name1,
END
OF emp.
DATA : emptab
TYPE STANDARD
TABLE OF
emp INITIAL SIZE
10 WITH
HEADER LINE .
SELECT
* FROM EMPLOYEE.
MOVE - CORRESPONDING
employeeTO emptab.
APPEND
EMPTAB.
ENDSELECT .
READ
TABLE ….
|
READ TABLE 選項:
1) READ TABLE <EMPTAB>.
2) READ TABLE <EMPTAB> WITH KEY <k1> = <v1>… <kn> = <vn>.
3) READ TABLE <EMPTAB> WITH TABLE KEY <k1> = <v1> … <kn> = <vn>.
4) READ TABLE <EMPTAB> WITH KEY = <value>.
5) READ TABLE <EMPTAB> WITH KEY . . . BINARY SEARCH.
6) READ TABLE <EMPTAB> INDEX <i>.
7) READ TABLE <EMPTAB> COMPARING <f1> <f2> . . . .
8) READ TABLE <EMPTAB> COMPARING ALL FIELDS.
9) READ TABLE <EMPTAB> TRANSPORTING <f1> <f2> . . . .
10) READ TABLE <EMPTAB> TRANSPORTING NO FIELDS.
關鍵字說明:
[KEY|TABLE KEY]: 通過內表的主鍵欄位查詢
[BINARY SEARCH]: 二分法查詢,使用該方法時,在READ TABLE之前,必須對內表排序
[INDEX]: 根據內表索引查詢
[COMPARING]:只查詢設定的欄位
[COMPARING ALL FIELDS]:查詢內表所有的欄位
[TRANSPORTING]: 只輸出設定的欄位資料
[TRANSPORTING NO FIELDS]: 不輸出任何資料
3. 內表排序
對內表進行排序,指定具體排序的排序欄位、排序方式(升序/降序)
預設情況下,為升序。
語法:
SORT itab [BY <f1> <f2> …] [ASCENDING|DESCENDING]
4. 內表分類彙總(COLLECT TABLE …)
通過COLLECT TABLE關鍵字,可以對內表中相同記錄合併,若有數字型別(I、P、F)的欄位,會將其合併彙總。
語法:
COLLECT [<work area> INTO] itab.
01 02 03 04 05 06 07 08 09 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 |
TABLES : EMPLOYEE.
TYPES :
BEGIN OF
EMP,
COUNTRY
LIKE EMPLOYEE-COUNTRY,
SALES
LIKE EMPLOYEE-SALES,
END
OF EMP.
DATA : EMPTAB
TYPE STANDARD
TABLE OF
EMP INITIAL SIZE
10 WITH
HEADER LINE ,
EMPTAB_C
TYPE STANDARD
TABLE OF
EMP INITIAL SIZE
10 WITH
HEADER LINE .
DATA : EMPTAB_WA
TYPE EMP.
* 賦值
EMPTAB-COUNTRY =
'D' .
EMPTAB-SALES = 400.
APPEND
EMPTAB.
EMPTAB-COUNTRY =
'USA' .
EMPTAB-SALES = 1000.
APPEND
EMPTAB.
EMPTAB-COUNTRY =
'GB' .
EMPTAB-SALES = 500.
APPEND
EMPTAB.
EMPTAB-COUNTRY =
'D' .
EMPTAB-SALES = 7800.
APPEND
EMPTAB.
SORT
EMPTAB BY COUNTRY.
LOOP
EMPTAB.
MOVE - CORRESPONDING
EMPTAB TO
EMPTAB_WA.
COLLECT
EMPTAB INTO
EMPTAB_C.
ENDLOOP .
|
輸出結果:
D 8200
GB 500
USA 1000
或者直接從資料表取數彙總:
01 02 03 04 05 06 07 08 09 10 11 12 |
SELECT
* FROM EMPLOYEE.
MOVE - CORRESPONDING
EMPLOYEE TO
EMPTAB.
COLLECT
EMPTAB.
ENDSELECT .
LOOP
AT EMPTAB.
WRITE : / EMPTAB-COUNTRY, EMPTAB-SALES.
ENDLOOP .
|
5.系統欄位 SY-TABIX
與前面提到的 SY-SUBRC 欄位一樣,SY-TABIX 也為系統的全域性變數;
用於在迴圈遍歷內表時,當前記錄的索引值:
1 2 3 4 5 6 7 8 |
SELECT
* FROM EMPLOYEE
INTO
CORRESPONDING FIELDS
OF TABLE
EMPTAB.
LOOP
AT EMPTAB.
WRITE : / SY-TABIX, EMPTAB-COUNTRY, EMPTAB-NAME1.
ENDLOOP .
|
2.2.4 維護內表資料
1.通過索引值維護內表
語法:
INSERT <EMPTAB> INDEX <i>.
MODIFY <EMPTAB> INDEX <i>.
DELETE <EMPTAB> INDEX <i>.
說明:
INSERT: 向內表資料I處插入資料記錄
MODIFY:修改內表資料I處記錄
DELETE:刪除內表I處資料記錄
如:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 |
SELECT
* FROM EMPLOYEE.
MOVE - CORRESPONDING
EMPLOYEE TO
EMPTAB.
APPEND
EMPTAB.
ENDSELECT .
READ
TABLE EMPTAB INDEX
1.
MOVE
'ABC' TO EMPTAB-NAME1.
MODIFY
EMPTAB INDEX SY-TABIX.
* 每次執行完之後,判斷SY-SUBRC是否為0
IF
SY-SUBRC NE 0.
WRITE : / ‘Attempt
to modify failed.’.
ELSE .
WRITE : / EMPTAB-COUNTRY, EMPTAB-NAME1.
ENDIF .
INSERT
EMPTAB INDEX 1.
DELETE
EMPTAB INDEX SY-TABIX.
|
2. 維護沒有HEADER LINE的內表
APPEND <work area> TO <internal table>.
COLLECT <work area> INTO <internal table>.
INSERT <work area> INTO <internal table>.
MODIFY <internal table> FROM <work area>.
READ TABLE <internal table> INTO <work area>.
LOOP AT <internal table> INTO <work area>.
說明:
APPEND: 向內表追加資料
COLLECT:內表資料分類彙總
INSERT:向內表插入資料
MODIFY:修改內表資料
READ TABLE:讀取內表資料
LOOP AT:遍歷內表資料
3. 清空內表
清空內表有4種方式:
CLEAR <internal table> :僅清空HEADER LINE,對內表資料儲存空間不影響
REFRESH <internal table>:清空內表資料儲存空間,對HEADER LINE不影響
FREE <internal table>:清空內表資料儲存空間,對HEADER LINE不影響
4.獲取內表資訊
可以通過 DESCRIBE 關鍵字獲取內表的相關資訊。
語法:
DESCRIBE TABLE <internal table> [LINES <var1>] [OCCURS <var2>].
說明:
LINES: 獲取內表儲存記錄數
OCCURS:獲取內表儲存空間大小
原著地址:http://www.sapjx.com/abap-internal-table-and-data-structure.html