相比較於一般的數據類型(例如 I, P, F, N, C, D, T等)的變量,Field Symbol和Data Reference類型的變量是ABAP中兩個相關複雜的類型。理解和使用這兩種變量,對於編寫高性能、高靈活性的ABAP程序是十分重要的。
1.含義解析
- Field Symbol:類似於C語言中的“指針”。初始狀態爲Unassigned。Field Symbol類型的變量自身並不對佔用存儲空間,僅“指向”被Assgined變量的地址空間。
- Data Reference: 一種變量類型。初始狀態爲Initial。當被創建(實例化)成具體的類型時,系統會爲其分配相應的存儲空間。通過 ‘ ->* ’ 的方式訪問,將值從地址空間傳輸到變量中(顯示)。若要改變Data Reference變量中的值,需要配合Field Symbol使用。即使用Field Symbol指向Data Reference變量所存儲的地址空間,並用Field Symbol對其進行操作。
下圖給出了配合Field Symbol操作Data Reference的一個例子 -
2. 使用Field Symbol提升訪問效率
因爲Field Symbol並不會佔用內存空間,因此在操作變量時,可以使用Field Symbol來提升運行效率。常用的Field Symbol的場景有以下幾種 -
- Read table < itab > assigning < fs >
- Loop at < itab > assigning < fs >
- Assign < data object > to < fs >
- Assign component <component name/component index> to < fs >
- Append initial line to < itab > assigning < fs >
**********************************************************************
* Field Symbol to prioritize the accessing of internal table
**********************************************************************
DATA: lt_sflight TYPE STANDARD TABLE OF sflight,
ls_sflight TYPE sflight.
FIELD-SYMBOLS: <ls_sflight> TYPE sflight.
SELECT * FROM sflight INTO TABLE lt_sflight UP TO 10 ROWS.
* extra effort to copy data into variable ls_sflight
LOOP AT lt_sflight INTO ls_sflight.
WRITE: / ls_sflight-carrid, ls_sflight-connid, ls_sflight-fldate.
ENDLOOP.
* access the address directly
LOOP AT lt_sflight ASSIGNING <ls_sflight>.
WRITE: / <ls_sflight>-carrid, <ls_sflight>-connid, <ls_sflight>-fldate.
ENDLOOP.
3.使用Data Reference動態創建變量
使用Data Reference的主要場景是針對於unknown的變量類型,用於ABAP的動態編程。創建所需要的變量時並不能確定具體的類型(但這裏並不是指“漫無邊際”的不確定,需要變量/結構/內表是確定的,而所需要的具體類型是不確定的) -
- 創建時,並無法確定具體類型的“變量 variable”
- 創建時,並無法確定具體類型的“結構 structure”
- 創建時,並無法確定具體類型的“內表 internal table”
下面給出了,三個不同場景的具體例子:
**********************************************************************
* 1. Un known data reference(creation of data variable)
**********************************************************************
PARAMETERS: p_var TYPE string DEFAULT 'I'.
DATA: lr_data TYPE REF TO data.
CREATE DATA lr_data TYPE (p_var).
FIELD-SYMBOLS: <fs> TYPE any.
ASSIGN lr_data->* TO <fs>.
IF sy-subrc = 0.
<fs> = '100'.
ENDIF.
WRITE: <fs>.
**********************************************************************
* 2. Un known data reference(creation of structure)
**********************************************************************
PARAMETERS: p_var TYPE string DEFAULT 'SFLIGHT'.
DATA: lr_data TYPE REF TO data.
CREATE DATA lr_data TYPE (p_var).
FIELD-SYMBOLS: <fs> TYPE any.
ASSIGN lr_data->* TO <fs>.
IF sy-subrc = 0.
SELECT SINGLE * FROM (p_var) INTO <fs>.
IF sy-subrc = 0.
FIELD-SYMBOLS: <fs_field> TYPE any.
DO .
ASSIGN COMPONENT sy-index OF STRUCTURE <fs> TO <fs_field>.
IF sy-subrc = 0.
WRITE: / <fs_field>.
ELSE.
EXIT.
ENDIF.
ENDDO.
ENDIF.
ENDIF.
**********************************************************************
* 3. Un known data reference(creation of table)
**********************************************************************
PARAMETERS: p_var TYPE string DEFAULT 'SFLIGHT'.
DATA: lr_data TYPE REF TO data.
CREATE DATA lr_data TYPE TABLE OF (p_var).
FIELD-SYMBOLS: <ft_table> TYPE ANY TABLE.
ASSIGN lr_data->* TO <ft_table>.
IF sy-subrc = 0.
SELECT * FROM (p_var) INTO TABLE <ft_table> UP TO 10 ROWS.
IF sy-subrc = 0.
cl_salv_table=>factory( IMPORTING r_salv_table = DATA(lr_salv)
CHANGING t_table = <ft_table> ).
lr_salv->display( ).
ENDIF.
ENDIF.