1. 程式人生 > >ABAP 開發系列(05): ABAP 內表與內表結構

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 … 語句將兩個結構體之間相同欄位自動匹配賦值:

abap_05_Structure_Set_Value

與基本變數定義類似,結構體的初始化操作也可以通過 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.                           "參考某一透明表,必須先引用定義 TYPESBEGIN 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 *--------------------------------------------------------------------* TYPESBEGIN 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資料後或通過 向內表儲存空間中追加資料。

abap_05_Internal_Table_With_Header_Line

對於沒有HEADER LINE的內表,只能通過 來傳遞資料:

abap_05_Internal_Table_Without_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. TYPESBEGIN 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. TYPESBEGIN 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