ABAP學習(4):內表


ABAP內表

    ABAP內表類似於一個結構體,可以用來保存從數據庫表中查出來的數據。內表只是在內存中作為操作表數據載體,在java等語言中使用對象保存一條數據庫記錄,對象列表保存多條記錄。ABAP中使用內表保存數據庫表中的一條或多條記錄。

1內表定義

    方式1:

    使用types定義結構類型:定義內表行結構

  Types:begin of <結構名>,

            <變量名> type|like <類型>,

            …………

            end of <結構名>.

    定義內表:

    Data:<內表名> type ( table| sorted table | hashed table ) of <結構名>

    [with non-unique default key]

    [initial size <記錄數>]

    [with header line]

示例:

*"定義linetype

TYPES: BEGIN OF firstLine,

      id(8) type C,

      name(20) type C,

      age type I,

      addr(30) type C,

      end of firstLine.

"定義內表(不指定talbe類型默認標准table,標准表只能使用  with NON-UNIQUE DEFAULT KEY
Data: firstTab TYPE TABLE OF firstLine

      with NON-UNIQUE DEFAULT KEY

      INITIAL SIZE 20

      WITH HEADER LINE

"定義sorted table  WITH UNIQUE KEY,或with non-unique default key 指定是否使用重復key field
Data: firstTab1 type SORTED TABLE OF firstLine

      INITIAL SIZE 20

      WITH HEADER LINE

      WITH NON-UNIQUE DEFAULT KEY.

"定義hash table 必須指定 WITH UNIQUE key,key field不重復
Data: firstTab2 TYPE HASHED TABLE OF firstLine

      WITH UNIQUE KEY id.

      INITIAL SIZE 20

      WITH HEADER LINE.

 

 

    方式2:

    使用data定義結構體:定義行結構

    Data:begin of <結構體名>,

            <變量名> type|like <數據類型>,

            …………

         end of <結構體名>.

  定義內表:語法類似,只是將type關鍵字換成like關鍵字

示例:

"使用data定義結構體

DATA: BEGIN OF firstLine1,

      id(8) type C,

      name(20) type C,

      age type I,

      addr(30) type C,

      end of firstLine1.

"定義內表必須使用like table of 
DATA:firstTab3 LIKE TABLE OF firstLine1.

DATA:firstTab4 LIKE SORTED TABLE OF firstLine1 WITH NON-UNIQUE DEFAULT KEY.

DATA:firstTab5 LIKE HASHED TABLE OF firstLine1 WITH UNIQUE KEY id.

 

 

   方式3:直接使用data定義內表

    Data:begin of <內表名> occurs <數字>,

            <變量名> type|like <數據類型>,

            …………

         end of <內表名>.

示例:

"直接定義內表,帶header line

DATA:BEGIN OF t_people OCCURS 0,

    name type string,

    age type I,

    END OF t_people.

   

方式4:定義數據庫表,結構體類型的內表:

    Data:<內表名> ( type | like ) [<類型>] table of  ( 數據庫表名 | 結構體名 )

    [with header line]

示例:

"type:ABAP中使用types定義類型需使用type;ABAP提供的基本類型,結構體,數據庫表,感覺和like區別不大

"like : 程序員定義類型,數據庫表名

"根據數據庫表定義內表

DATA:t_spfli LIKE TABLE OF spfli.

DATA:t_spfli1 TYPE TABLE OF spfli.

"有表頭行

DATA:t_spfli2 LIKE TABLE OF spfli WITH HEADER LINE.

DATA:t_spfli3 TYPE TABLE OF spfli WITH HEADER LINE.

"可以是自己定義的數據庫表,結構體,z_spfli 為自定義數據庫表,結構體

DATA:t_test LIKE  TABLE OF Z_SPFLI.

DATA:t_test TYPE  TABLE OF Z_SPFLI.

2內表表頭行

    根據內表是否具有表頭行,我們的操作也不同。判斷內表是否具有表頭行我們一般判斷定義內表時,是否有with header line 關鍵詞,occurs定義的內表,具有表頭行。

    帶表頭行內表插入操作:直接使用append <內表>語句插入

    不帶表頭行內表插入操作:需要先定義一個結構體類型的工作區,然后將工作區賦值,通過append <工作區數據> to <內表>

示例:

"直接定義內表,帶header line

DATA:BEGIN OF t_people OCCURS 0,

    name type string,

    age type I,

    END OF t_people.

"帶headline的內表賦值

t_people-name = 'tang'.

t_people-age  = 11.

"添加記錄到t_people

APPEND t_people.

 

"沒有表頭行內表賦值

DATA:BEGIN OF l_people,

    name TYPE string,

    age TYPE I,

     END OF l_people.

"如果上面是使用types定義type,還需要定義一個工作區

"DATA:wa_people LIKE LINE OF l_people.

DATA:t_people LIKE TABLE OF l_people.

"內表賦值

l_people-name = 'tang'.

l_people-age = 10.

APPEND l_people to t_people.

3內表賦值

內表初始化:使用refresh <內表>

內表和其他類型變量:

內表使用clear <內表>[];

clear <內表> 工作區初始化

clear <變量名>

釋放內存空間:free <變量>

"初始化內表

"清空內表,不能用於其他類型變量初始化

refresh firstTab.

"clear可以用於其他類型變量初始化

"如果內表有表頭行,清空表頭工作區。

CLEAR firstTab.

"refresh功能,清空內表

CLEAR firstTab[].

"clear,refresh不會釋放內存,free釋放內表所占內存

FREE firstTab.

 

兩個內表之間賦值,需要在循環中逐條賦值:

將內表表頭行A賦值給B內表表頭行

語法:move-corresponding <內表A表頭行> to <內表B表頭行>

語法:append <內表B表頭行>

這個也可以用於兩個工作區之間賦值

DATA:firstTab TYPE TABLE OF firstLine  WITH HEADER LINE.

DATA:firstTab1 TYPE TABLE OF firstLine WITH HEADER LINE.

firstTab-id = 1.

firstTab-name = '113'.

APPEND firstTab.

 

firstTab-id = 2.

firstTab-name = '114'.

APPEND firstTab.

 

"table之間賦值,這個語句必須兩個都是具有表頭行內表

LOOP AT firstTab.

  "這句只是將工作區值加入目標內表工作區,三種寫法都可

    MOVE-CORRESPONDING firstTab to firstTab1.

*   firstTab1[] = firstTab[].

*   MOVE firstTab[] to firstTab1[].


*   firstTab1 = firstTab[].     "這種寫法只有firstTab1是不帶表頭行的內表才有效

*   MOVE firstTab to firstTab1[]."這句報錯

  "將工作區保存到內表

   APPEND firstTab1.

ENDLOOP.

 DATA:wa_line LIKE LINE OF firstTab1.

 LOOP AT firstTab1 INTO wa_line.

   WRITE:/ wa_line-id,wa_line-name.

 ENDLOOP.

 

內表插入數據:

    根據前面示例,可以使用append語句,標准表中使用append,hash和sorted表不能使用append,默認都是標准表。

    語法:insert <工作區> into table <內表>

    insert <內表名> into table <內表>,帶表頭行的內表,可以直接使用內表賦值插入數據。

示例:

DATA:BEGIN OF firstTab1 OCCURS 0,

      id TYPE I,

      name TYPE String,

      age TYPE I,

      addr TYPE String,

     END OF firstTab1.

"insert語句

firstTab1-id = '001'.

firstTab1-name = 'li'.

firstTab1-age = 30.

firstTab1-addr = 'gudong'.

insert firstTab1 into table firstTab1.

 

TYPES:BEGIN OF firstTab2,

      id TYPE I,

      name TYPE String,

     END OF firstTab2.

DATA:wa_firstTab2 LIKE LINE OF firstTab2.

DATA:t_firstTab2 LIKE TABLE OF firstTab2.

"不帶表頭行,使用工作區插入內表

wa_firstTab2-id = 1.

wa_firstTab2-name = 'tang'.

INSERT wa_firstTab2 INTO TABLE t_firstTab2.

 

"多條數據插入

data:testTab01 TYPE TABLE OF firstLine WITH HEADER LINE.

DATA:testTab02 TYPE TABLE OF firstLine WITH HEADER LINE.

 

testTab01-id = '001'.

testTab01-name = 'li1'.

testTab01-age = 32.

testTab01-addr = 'gudong1'.

append testTab01.

 

testTab01-id = '002'.

testTab01-name = 'li2'.

testTab01-age = 33.

testTab01-addr = 'gudong2'.

append testTab01.

 

testTab01-id = '003'.

testTab01-name = 'li2'.

testTab01-age = 33.

testTab01-addr = 'gudong2'.

append testTab01.

 

testTab02-id = '00223'.

testTab02-name = 'li3'.

testTab02-age = 35.

testTab02-addr = 'gudong3'.

append testTab02.

 

testTab02-id = '00224'.

testTab02-name = 'li3'.

testTab02-age = 35.

testTab02-addr = 'gudong3'.

append testTab02.

"將1到2條數據插入testTab2,內表行號從1開始,index指定插入位置

*INSERT LINES OF testTab01 from 1 to 2 into testTab02 INDEX 1.

"index值范圍1到內表數據條數+1

INSERT LINES OF testTab01 INTO testTab02 INDEX 3.

 

 

Collect語句

    語法:collect <內表名>,這是帶表頭行的內表。內表名代表表頭行。

    語法:collect <工作區> into <內表>,不帶表頭行的內表操作

示例:

"Collect語句

"collect也是將元素加入內表,但是他會將非數字字符相同的行合並,並且數字列相加。

Data:BEGIN OF testTable OCCURS 20,

      col2 type I,

      col1(20) type C,

    END OF testTable.

 

testTable-col1 = 'a'.

testTable-col2 = 20.

COLLECT testTable.

 

testTable-col1 = 'b'.

testTable-col2 = 39.

COLLECT testTable.

 

testTable-col1 = 'a'.

testTable-col2 = 19.

COLLECT testTable.

 

"不帶表頭行的內表,collect操作

Data:BEGIN OF wa_testTable,

      col2 type I,

      col1(20) type C,

    END OF wa_testTable.

DATA:testTable1  LIKE TABLE OF wa_testTable.

 

wa_testTable-col2 = 1.

wa_testTable-col1 = 'he'.

COLLECT wa_testTable INTO testTable1.

 

wa_testTable-col2 = 12.

wa_testTable-col1 = 'he'.

COLLECT wa_testTable INTO testTable1.

 

wa_testTable-col2 = 1.

wa_testTable-col1 = 'ha'.

COLLECT wa_testTable INTO testTable1.

 

LOOP AT testTable1 INTO wa_testTable.

  WRITE:/ wa_testTable-col2,wa_testTable-col1.

ENDLOOP.

 

 

4內表循環遍歷

    一般內表數據訪問需要循環內表。

    語法:loop at <內表> [into wa].

            <訪問內表屬性>

          endloop.

    沒有表頭行的內表需要使用into,將內表循環到工作區,通過工作區訪問對應屬性。

    讀取內表符合條件的記錄

    語法:read table <內表> with key <列名>=<值>

          read table <內表> index <數字>

    查找符合條件的記錄,只查找一條。Index是內部記錄對應行,行號從1開始。

示例:

"帶表頭行直接使用內表名可以直接訪問屬性

LOOP AT testTable.

  WRITE:/ testTable-col1,testTable-col2.

ENDLOOP.

 

"不帶表頭行的內表,使用工作區

DATA:wa_testTable LIKE LINE OF testTable.

LOOP AT testTable INTO wa_testTable.

  WRITE:/ wa_testTable-col1,testTable-col2.

ENDLOOP.

 

"循環出符合條件記錄

loop AT testTable WHERE col2 = 39.

  WRITE :/ 'col1=',testTable-col1,'col2=',testTable-col2.

ENDLOOP.

 

**read讀取內表數據

"查找符合條件記錄

READ TABLE testTable WITH KEY col2 = 19."找到一個就結束查找

"讀取對應行的記錄,行號從1開始

READ TABLE testTable INDEX 3.

5刪除內表記錄

    語法:delete table <內表> from <工作區>

    刪除工作區對應的那一條內表記錄。刪除成功sy-subrc = 0,刪除失敗sy-subrc = 4。

    語法:delete <內表> where <列名> = <值> [and | or <列名> = <值>].

示例:

"使用工作區刪除記錄

DATA:wa_testTable LIKE LINE OF testTable.

wa_testTable-col1 = 'a'.

wa_testTable-col2 = 20.

wa_testTable-col3 = 'cd'.

"刪除的記錄每個域值必須和內表對應域值相等

DELETE TABLE testTable FROM wa_testTable.

 

"直接條件刪除記錄,對應符合條件多條記錄刪除

DELETE testTable where col1 = 'a'.

"直接條件刪除記錄,對應符合條件多條記錄刪除

DELETE testTable where col1 = 'a' AND col2 = 20 OR col2 = 39.

 

6修改內表記錄

    更新內表記錄。

    語法:modify <內表> transporting  <列名> [列名……] where <列名> = <值> [ and | or <列名> = <值>].

    語法:modefy <內表>

    如果內表有表頭行,直接在循環中更新內表屬性值。

    語法:modefy <內表> from <wa>

    如果內表沒有表頭行,需要使用工作區,將要更新內容寫入。

示例:

testTable-col1 = 'd'.

testTable-col2 = 40.

testTable-col3 = 'hello'.

"使用transporting指定修改列,where條件篩選列

modify testTable TRANSPORTING col1 col2 col3 WHERE col1 = 'a'.

 

"測試循環 modify

Data:BEGIN OF testTable OCCURS 0,

      name TYPE String,

      desc TYPE String,

    END OF testTable.

testTable-name  = 'tang'.

APPEND testTable.

LOOP AT testTable.

  testTable-desc = sy-uname.

  MODIFY testTable.

ENDLOOP.

 

"沒有表頭行操作

Data:BEGIN OF testTable,

      name TYPE String,

      desc TYPE String,

    END OF testTable.

DATA:t_testTable LIKE TABLE  OF testTable.

 

testTable-name = 'hello'.

APPEND testTable TO t_testTable.

testTable-name = 'hello1'.

APPEND testTable TO t_testTable.

LOOP AT t_testTable INTO testTable.

  testTable-desc = sy-uname.

  MODIFY t_testTable FROM testTable.

ENDLOOP.

 

"所有字段重新賦值

LOOP AT t_testTable INTO testTable.

  testTable-strs = 'hello'.

  testTable-desc = sy-uname.

  testTable-name = 'tang'.

  MODIFY t_testTable FROM testTable.

ENDLOOP.

 

7Range Table

ABAP的Range Table:

    Range Table相當於一個內表,由 sign,option,low,high四個字段組成。

seltab結構:

DATA: BEGIN OF <seltab>,

         SIGN(1),

         OPTION(2)

         LOW  LIKE <f>,

         HIGH LIKE <f>,

      END OF <seltab>.

 

定義Range Table:

    語法:<變量名> ( type|like ) range of <數據類型>

      [INITIAL SIZE n]

      [WITH HEADER LINE]

      [VALUE IS INITIAL]

      [READ-ONLY].

    語法:ranges: <變量名> for <數據類型>

      [OCCURS n].

Sign取值:

‘I’表示在區間內;

‘E’表示在區間外;

Option取值:

‘EQ’:等於,單值;

‘NE’:不等於,單值;

‘GT’:大於,單值;

‘LT’:小於,單值;

‘GE’:大於等於,單值;

‘LE’:小於等於,單值;

‘CP’: 包含,當字符串使用了*和+字符,*代替字符串,+代替單個字符;

‘NP’:不包含

‘BT’:位於,high有值,在范圍中;

‘NB’:不位於,hight有值,不在范圍中;

示例:

"定義一個range類型

DATA:t_range LIKE RANGE OF spfli-carrid WITH HEADER LINE.

"定義range類型

RANGES: t_range1 FOR spfli-carrid OCCURS 0.

 

設置值Range Table:

示例:

* 宏定義

DEFINE set_range.

  wa_range-sign   = 'I'.

  wa_range-option = 'EQ'.

  wa_range-low    = &1.

  append wa_range to t_range.

END-OF-DEFINITION.

 

set_range 'DL'.

 

8內表記錄排序

使用Sort關鍵字,將內表記錄進行排序。

語法:SORT <內表名> BY <欄位> [ASCENDING|DESCENDING]

[<欄位> [ASCENDING|DESCENDING]…………].

示例:

"內表定義

DATA:test_spfli LIKE TABLE OF spfli WITH HEADER LINE.

"查詢數據

SELECT * FROM spfli INTO CORRESPONDING FIELDS OF TABLE test_spfli.

 

"排序,指定按照connid升序

SORT test_spfli BY connid ASCENDING.

"排序,指定按照某欄位升序,某欄位降序,從左到右依次匹配

SORT test_spfli BY connid ASCENDING FLTIME DESCENDING.

 

9內表去除重復記錄

一般將內表記錄進行排序,然后按照指定欄位去除重復記錄,不指定欄位那么就是比較全部欄位相同的去掉重復內容。

示例:

"刪除所有欄位都相同的記錄

*DELETE ADJACENT DUPLICATES FROM test_spfli.

"刪除所有欄位都相同的記錄

*DELETE ADJACENT DUPLICATES FROM test_spfli COMPARING ALL FIELDS.

"去重指定欄位相同記錄

DELETE ADJACENT DUPLICATES FROM test_spfli COMPARING connid .

"去重指定欄位相同的記錄,只保留一筆比較欄位相同的記錄

DELETE ADJACENT DUPLICATES FROM test_spfli COMPARING carrid connid .

 

10動態內表

    創建動態內表,我們需要在程序執行過程中獲取內表或結構體的字段屬性。

類CL_ABAP_TYPEDESCR和它的子類的結構圖:

CL_ABAP_TYPEDESCR

  |

  |--CL_ABAP_DATADESCR

  |     |

  |     |--CL_ABAP_ELEMDESCR

  |     |--CL_ABAP_REFDESCR

  |     |--CL_ABAP_COMPLEXDESCR

  |         |

  |         |--CL_ABAP_STRUCTDESCR

  |         |--CL_ABAP_TABLEDESCR

  |

  |--CL_ABAP_OBJECTDESCR

        |

        |--CL_ABAP_CLASSDESCR

        |--CL_ABAP_INTFDESCR

 

通過CL_ABAP_TABLEDESCR類可以獲取到內表的結構字段,

通過CL_ABAP_TYPEDESCR類可以獲取結構體工作區結構字段,

通過CL_ABAP_STRUCTDESCR類可以保存獲取的結構字段。

 

示例1

獲取程序定義中內表字段結構

FORM get_struct.

  "sflight內表

  DATA:t_sflight like sflight OCCURS 0 .

  "cl_abap_tabledescr類獲取內表結構

  DATA:l_tabledescr_ref TYPE REF TO cl_abap_tabledescr,

       l_descr_ref      TYPE REF TO cl_abap_structdescr.

  "字段結構

  DATA:wa_struct TYPE ABAP_COMPDESCR.

  "cl_abap_typedescr程序運行的時候取得某個內表或者某個結構它的屬性或者它的字段的屬性

  "獲取sflight內表結構

  l_tabledescr_ref ?= cl_abap_typedescr=>describe_by_data( t_sflight ).

  "cl_abap_tabledescr獲取表頭結構

  l_descr_ref ?= l_tabledescr_ref->get_table_line_type( ).

  LOOP AT l_descr_ref->components INTO wa_struct .

    WRITE:/ wa_struct-name .

  ENDLOOP.

 

   "people結構

  TYPES:BEGIN OF s_people,

        name TYPE String,

        age TYPE I,

        addr TYPE String,

        END OF s_people.

  "people類型工作區

  DATA:wa_people TYPE s_people.

  FIELD-SYMBOLS:<wa_struct> TYPE ABAP_COMPDESCR.

  "cl_abap_typedescr獲取工作區結構

  l_descr_ref  ?=  cl_abap_typedescr=>describe_by_data( wa_people ).

  "使用指針方式

  LOOP AT l_descr_ref->components ASSIGNING <wa_struct> .

    WRITE:/ <wa_struct>-name .

  ENDLOOP.

 

ENDFORM.
View Code

 

示例2

根據數據庫表,獲取對應動態內表結構,創建動態內表

PARAMETERS p_name TYPE tabname.  "數據庫表名

 

"*************************************************

"TYPE REF TO 和 Field Symbol 都可以指定指針類型

"      定義

"       Type Ref To 有兩種初始化的方法:

"          第一種是用 CREATE DATA 動態開辟內存;

"          第二種是用 GET REFERENCE OF 指向已經存在的內存變量.

"      Field Symbol 的初始化,則只能指向已經存在的內存變量。

*        CREATE DATA ref TYPE ty_ym.        "指定類型

*        CREATE DATA ref LIKE LINE OFit_ym.  "指定結構,like line

*        CREATE DATA ref LIKE wa_ym.

*        CREATE DATA ref LIKE ym.

*        GET REFERENCE OF wa_ym INTO ref. "TypeRef To的初始化,效果相當於指向 wa_ym

*        GET REFERENCE OF v_ym INTO ref.  "Type Ref To的初始化,效果相當於指向 v_ym

*

 

*       "定義指針類型

*       FIELD-SYMBOLS :

*         <dyn_table> TYPE table,  "指定類型table

*         <dyn_wa> TYPE ANY,       "不指定類型

*       Field Symbol初始化

*       ASSIGN wa_ym TO < fs >."Field Symbol的初始化,效果相當於指向wa_ym

*       ASSIGN v_ym TO < fs >.  "Field Symbol的初始化,效果相當於指向v_ym

 

"*****************************************************

 

DATA: d_ref TYPE REF TO data,    "不指定特定類型和結構, 保存表字段結構

lt_alv_cat TYPE TABLE OF lvc_s_fcat,

ls_alv_cat LIKE LINE OF lt_alv_cat.

 

DATA: lt_table LIKE TABLE OF dntab.  "獲取表的natab,表的結構表

DATA: ls_table TYPE dntab.

 

DATA: dyn_table TYPE REF TO data.

DATA: dyn_wa TYPE REF TO data.

 

"定義指針類型

FIELD-SYMBOLS :

  <dyn_table> TYPE table,  "指定類型

  <dyn_wa> TYPE ANY,       "不指定類型

  <dyn_field> TYPE ANY,

  <fs_str> TYPE ANY.

 

*取出表結構的字段目錄

CALL FUNCTION 'NAMETAB_GET'

     EXPORTING

          langu          = sy-langu

          tabname        = p_name

     TABLES

          nametab        = lt_table

     EXCEPTIONS

          no_texts_found = 1.

 

*根據取出的字段目錄生成參考字段目錄

LOOP AT lt_table INTO ls_table.

  ls_alv_cat-fieldname = ls_table-fieldname.

  ls_alv_cat-ref_table = p_name.

  ls_alv_cat-ref_field = ls_table-fieldname.

  APPEND ls_alv_cat TO lt_alv_cat.

  CLEAR ls_alv_cat.

ENDLOOP.

 

*動態內表創建

CALL METHOD cl_alv_table_create=>create_dynamic_table

  EXPORTING

    it_fieldcatalog = lt_alv_cat

  IMPORTING

    ep_table = d_ref.   "生成內表

 

*指定生成的內表到指針

ASSIGN d_ref->* TO <dyn_table>.

*創建動態工作區結構

CREATE DATA dyn_wa LIKE LINE OF <dyn_table>.

*創建動態工作區

ASSIGN dyn_wa->* TO <dyn_wa>.

 

 

 

*從動態表中取數到動態內表中

SELECT * INTO CORRESPONDING FIELDS OF TABLE <dyn_table> UP TO 10 ROWS FROM (p_name).

 

*******************動態編輯數據********************************新增行

  IF P_NAME = 'T001'."這里以公司代碼表為例

    ASSIGN COMPONENT 'BUKRS' OF STRUCTURE <dyn_wa> TO <fs_str>.

    <fs_str> = '9998'.

    append <dyn_wa> to <dyn_table>.

    <fs_str> = <fs_str> + 1.

    append <dyn_wa> to <dyn_table>.

  ENDIF.

 

*顯示內表中的數據

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'

     EXPORTING

          i_structure_name = p_name

     TABLES

          t_outtab         = <dyn_table>

     EXCEPTIONS

          program_error    = 1

          OTHERS           = 2.

 

IF sy-subrc <> 0.

  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

ENDIF.
View Code

 

示例3

完全自定義創建動態內表,自己自定義內表數據類型,欄位名

"create dynamic table with any fields

DATA:lt_comp TYPE cl_abap_structdescr=>component_table.

DATA:ls_comp LIKE LINE OF lt_comp.

DATA:new_type TYPE REF TO cl_abap_structdescr.

DATA:new_table TYPE REF TO cl_abap_tabledescr.

DATA:t_data TYPE REF TO data.

"alv fieldcat

DATA:lt_fieldcat TYPE SLIS_T_FIELDCAT_ALV.

DATA:ls_fieldcat LIKE LINE OF lt_fieldcat.

DATA:col_pos TYPE I.

 

FIELD-SYMBOLS:

         <lt_dyntable> TYPE STANDARD TABLE,

         <ls_newline> TYPE ANY,

         <filed> TYPE ANY.

 

define d_filed_add.

" Field name

  ls_comp-name = &1.

 

**   Element Description

*        lo_element ?= cl_abap_elemdescr=>describe_by_name( &2 ).

 

*   Field type

  case &2.

    when 'P'."包裝類型

 

      ls_comp-type = cl_abap_elemdescr=>get_p(

                        p_length   = &3

                        p_decimals = &4 ).

    when 'C'."字符型

 

      ls_comp-type = cl_abap_elemdescr=>get_c(

                        p_length   = &3 ).

    when 'I'."整型 4字節

 

      ls_comp-type = cl_abap_elemdescr=>get_i( ).

 

    when 'D'."日期類型,8個字符

 

      ls_comp-type = cl_abap_elemdescr=>get_d( ).

 

    when 'T'."時間類型,6個字符

 

      ls_comp-type = cl_abap_elemdescr=>get_t( ).

 

    when 'N'."數字字符串

 

      ls_comp-type = cl_abap_elemdescr=>get_n(

                        p_length   = &3 ).

 

    when 'S'.  "String類型

 

      ls_comp-type = cl_abap_elemdescr=>get_string( ).

 

  endcase.

 

  append ls_comp to lt_comp.

  clear: ls_comp.

end-OF-DEFINITION.

 

DEFINE d_fieldcat.

  clear ls_fieldcat.

  add 1 to col_pos.

  clear ls_fieldcat.

  ls_fieldcat-col_pos      = col_pos.        "column position

  ls_fieldcat-fieldname    = &1.             "顯示的字段

  ls_fieldcat-reptext_ddic = &2.             "顯示欄目名

 

  append ls_fieldcat to lt_fieldcat.

END-OF-DEFINITION.

 

"creat dynamic table with any fields

"初始化表

CLEAR lt_comp[].

"構建內表字段結構

d_filed_add 'NAME' 'C' 10 space.

d_filed_add 'AGE' 'I' space space.

d_filed_add 'ADDR' 'S' space space.

d_filed_add 'TEL' 'C' 15 space.

d_filed_add 'REJIST_DATE' 'D' space space.

 

"根據結構創建Type

new_type = cl_abap_structdescr=>create( lt_comp ).

 

"根據Type創建table type

new_table = cl_abap_tabledescr=>create(

                  p_line_type  = new_type

                  p_table_kind = cl_abap_tabledescr=>tablekind_std

                  p_unique     = abap_false ).

 

"根據table type 創建內表

CREATE DATA t_data TYPE HANDLE new_table.

"將內表賦給指針

ASSIGN t_data->* to <lt_dyntable>.

 

"創建內表相應工作區

DATA:ls_newline TYPE REF TO data.

CREATE DATA ls_newline LIKE LINE OF <lt_dyntable>.

ASSIGN ls_newline->* to <ls_newline>.

 

"動態添加數據

ASSIGN COMPONENT 'NAME' OF STRUCTURE <ls_newline> to <filed>.

IF sy-subrc = 0.

  <filed> = '張三'.

ENDIF.

 

ASSIGN COMPONENT 'AGE' OF STRUCTURE <ls_newline> to <filed>.

IF sy-subrc = 0.

  <filed> = 12.

ENDIF.

 

ASSIGN COMPONENT 'ADDR' OF STRUCTURE <ls_newline> to <filed>.

IF sy-subrc = 0.

  <filed> = '四川'.

ENDIF.

 

 

ASSIGN COMPONENT 'TEL' OF STRUCTURE <ls_newline> to <filed>.

IF sy-subrc = 0.

  <filed> = '18938893339'.

ENDIF.

 

ASSIGN COMPONENT 'REJIST_DATE' OF STRUCTURE <ls_newline> to <filed>.

IF sy-subrc = 0.

  <filed> = '20180902'.

ENDIF.

 

APPEND <ls_newline> to <lt_dyntable>.

CLEAR <ls_newline>.

 

"alv 字段

d_fieldcat 'NAME' '姓名'.

d_fieldcat 'AGE' '年齡'.

d_fieldcat 'ADDR' '地址'.

d_fieldcat 'TEL' '電話'.

d_fieldcat 'REJIST_DATE' '注冊時間' .

 

*顯示內表中的數據

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'

     EXPORTING

          it_fieldcat      = lt_fieldcat[]

     TABLES

          t_outtab         = <lt_dyntable>

     EXCEPTIONS

          program_error    = 1

          OTHERS           = 2.

 

IF sy-subrc <> 0.

  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno

  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

ENDIF.

 

 

"動態創建結構 create dynamic structure

form create_dynamic_structure.

"創建動態structure

DATA:lt_comp1 TYPE cl_abap_structdescr=>component_table.

DATA:lwa_comp1 TYPE abap_componentdescr.

DATA:lo_strucdesc TYPE REF TO cl_abap_structdescr.

DATA:lo_struc TYPE REF TO data.

FIELD-SYMBOLS: <fs_struc> TYPE ANY.

 

CLEAR lt_comp1[].

lwa_comp1-name = 'NAME'.

lwa_comp1-type = cl_abap_elemdescr=>get_c( 10 ).

APPEND lwa_comp1 to lt_comp1.

CLEAR lwa_comp1.

 

lwa_comp1-name = 'AGE'.

lwa_comp1-type = cl_abap_elemdescr=>get_i( ).

APPEND lwa_comp1 to lt_comp1.

clear lwa_comp1.

 

"創建動態結構

 lo_strucdesc  = CL_ABAP_STRUCTDESCR=>create( P_COMPONENTS = lt_comp1 ).

 CREATE DATA lo_struc TYPE HANDLE lo_strucdesc.

 ASSIGN lo_struc->* to <fs_struc>.

 

ENDFORM.
View Code

 

示例4

FORM method3.

  DATA:t_spfli LIKE TABLE OF spfli WITH HEADER LINE.

  SELECT * INTO CORRESPONDING FIELDS OF TABLE t_spfli FROM spfli WHERE CARRID = 'AA'.

 

  LOOP AT t_spfli.

    WRITE:/ t_spfli-carrid,t_spfli-connid,t_spfli-countryfr,t_spfli-cityfrom.

  ENDLOOP.

 

  "指針變量

  DATA: dyn_wa TYPE REF TO data.

  "定義指針類型

  FIELD-SYMBOLS :

  <dyn_wa> TYPE ANY,       "不指定類型

  <dyn_field> TYPE ANY.

 

  "創建動態工作區,分配內存

  CREATE DATA dyn_wa LIKE LINE OF t_spfli.

  "將指針變量賦給field symbol

  ASSIGN dyn_wa->* TO <dyn_wa>.

  "填充數據

  LOOP AT t_spfli INTO <dyn_wa>.

     ASSIGN COMPONENT 'CONNID' OF STRUCTURE <dyn_wa> TO <dyn_field>.

     WRITE:/ <dyn_field>.

  ENDLOOP.

ENDFORM.

 

11內表前后內容變更比較

    使用Function, CTVB_COMPARE_TABLES可以比較前后兩個內表記錄變更情況。

輸入參數:

    TABLE_OLD:傳入修改之前記錄內表;

    TABLE_NEW: 傳入修改之后記錄內表;

    KEY_LENGTH:關鍵字欄位數,前面多少欄位是關鍵字欄位;

    IF_SORTED:是否比較內表排好序

輸出參數:

    NO_CHANGES:是否有改變;

    TABLE_DEL:被刪除記錄;

    TABLE_ADD:新增記錄;

    TABLE_MOD:被修改記錄;

注意:傳入table類型參數必須加[]。

示例:

DATA:old_tab LIKE TABLE OF spfli WITH HEADER LINE.

DATA:new_tab LIKE TABLE OF spfli WITH HEADER LINE.

DATA:chg_tab LIKE TABLE OF spfli WITH HEADER LINE.

DATA:NO_CHANGES TYPE  FLAG.

SELECT * INTO CORRESPONDING FIELDS OF TABLE old_tab FROM spfli WHERE CARRID = 'AA'.

 

LOOP AT old_tab.

  MOVE-CORRESPONDING old_tab to new_tab.

  IF old_tab-connid = '55'.

    new_tab-connid = '66'.

  ENDIF.

  APPEND new_tab.

ENDLOOP.

"比較兩個內表

CALL FUNCTION 'CTVB_COMPARE_TABLES'

  EXPORTING

    TABLE_OLD        = old_tab[]

    TABLE_NEW        = new_tab[]

    KEY_LENGTH       = 2

    IF_SORTED        = 'X'

  IMPORTING

*   TABLE_DEL        =

*   TABLE_ADD        =

    TABLE_MOD        = chg_tab[]

    NO_CHANGES       = NO_CHANGES.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM