SAP-ABAP 语法-内表&数据库表操作
内表&数据库表操作
·
一、内表定义
*---------------------------带表头-----------------------------
DATA: BEGIN OF itab OCCURS 0,
matnr LIKE mara-matnr,
werks LIKE marc-werks,
END OF itab .
DATA: otab LIKE TABLE OF itab WITH HEADER LINE.
DATA: BEGIN OF itab OCCURS 0.
INCLUDE STRUCTURE ztmm001. "表内包含其他结构或表
DATA: str(10) TYPE c.
DATA: END OF itab.
*---------------------------无表头-----------------------------
DATA: BEGIN OF itab OCCURS 0,
matnr LIKE mara-matnr,
werks LIKE marc-werks,
END OF itab .
TYPES: BEGIN OF gs_alv. "结构
INCLUDE STRUCTURE ztmm001.
TYPES: zterm TYPE dzterm,
sel TYPE c.
TYPES: END OF gs_alv.
二、内表&数据库表常用语句
*---------------------------Insert----------------------------
***插入数据到数据库表
INSERT db_table FROM TABLE itab ACCEPTING DUPLICATE KEYS.
INSERT db_table FROM TABLE itab.
INSERT dbtab FROM wa.
INSERT into dbtab values wa.
COMMIT WORK.
***插入数据到内表
INSERT wa INTO TABLE itab.
INSERT wa INTO itab INDEX n.
INSERT LINES OF itab1 INTO TABLE itab2 INDEX 1.
INSERT sy-index INTO TABLE itab.
*---------------------------Append-----------------------------
APPEND LINES OF itab_temp TO itab. "多行
APPEND LINES OF itab_temp FROM 2 TO 3 TO itab. "多行-指定行
APPEND itab_temp TO itab. "单行
*---------------------------Delete-----------------------------
***删除数据库表数据
DELETE FROM ztco33_sr WHERE gjahr = p_gjahr "按条件删除
AND monat IN s_monat.
DELETE ztco33_sr FROM wa.
DELETE ztco33_sr FROM TABLE itab[]. "按主键删除
COMMIT WORK AND WAIT.
***删除内表数据
LOOP AT gt_item INTO gs_item .
DELETE gtitem[] . "删除内表当前行
ENDLOOP .
DELETE TABLE itab FROM wa. "按主键删除
DELETE gt_item INDEX 20 . "不建议在loop循环中使用,会影响内表的行索引
DELETE itab WHERE matnr NOT IN s_matnr.
SORT itab BY werks matnr.
DELETE ADJACENT DUPLICATES FROM itab COMPARING werks matnr. "删除重复行,保留第一条数据
*---------------------------Modify-----------------------------
***修改数据库
MODIFY dbtab FROM wa.
MODIFY dbtab FROM TABLE itab[]. "按主键决定是更新还是插入
COMMIT WORK.
***修改内表-Loop外
MODIFY TABLE itab FROM wa. "工作区修改内表必须有主键,按主键修改
***修改内表-Loop内
MODIFY itab.
MODIFY itab FROM wa.
MODIFY itab FROM wa INDEX 1. "修改行
MODIFY itab FROM wa TRANSPORTING f1 f2 f3 WHERE f = '1235' . "按工作区某个字段值更新内表
WA_MATNR-LGORT = 'SP02'.
APPEND WA_MATNR TO EX_TAB.
CLEAR WA_MATNR.
WA_MATNR-MATNR = IM_MATNR.
MODIFY EX_TAB FROM WA_MATNR TRANSPORTING MATNR WHERE MATNR IS INITIAL.
**用指针修改
LOOP AT gt_alv ASSIGNING FIELD-SYMBOL(<fs_alv>) WHERE SELXXX eq 'X' .
<fs_alv>-LES_DEL = 'X'. "内表更新
UPDATE ZTSD0010 SET LES_DEL = 'X' WHERE ID = <fs_alv>-ID. "透明表更新
ENDLOOP.
COMMIT WORK AND WAIT.
*---------------------------Update-----------------------------
UPDATE dbtab FROM wa.
UPDATE dbtab FROM TABLE itab[].
UPDATE db_table
SET matnr = t_flag
chgby = sy-uname
WHERE werks = c_value1.
COMMIT WORK.
*---------------------------Read-----------------------------
READ TABLE itab INTO gs_itab WITH KEY matnr = '1001' werks = '1000'.
READ TABLE itab INDEX 1.
**二分法(使用前一定要先排序,二分法查找会反复将查找区间对半划分)
SORT itab BY matnr werks.
READ TABLE itab INTO DATA(gs_itab) WITH KEY matnr = '1001' werks = '1000' BINARY SEARCH.
*---------------------------Collect-----------------------------
SORT itab_temp BY matnr.
LOOP AT itab_temp.
COLLECT itab_temp INTO itab_col.
ENDLOOP.
三、数据库表常用查询语句
-------------------------------------获取一笔数据-----------------------------------------
SELECT SINGLE * FROM t001w WHERE werks = itab-werks.
SELECT SINGLE verpr peinh INTO (itab-verpr,itab-peinh)
FROM mbew
WHERE matnr = itab-matnr
AND bwkey = itab-werks
AND ( lfgja < g_lfgja OR ( lfgja = g_lfgja AND lfmon <= g_lfmon ) ) .
SELECT SINGLE *
INTO CORRESPONDING FIELDS OF TABLE itab
FROM ztmm_config.
SELECT
EKPO~NETPR "按数量单位的价格
EKPO~PEINH "数量单位
EKKO~WAERS
EKKO~AEDAT
EKPO~EBELN
EKPO~EBELP
INTO (Z_NETPR,Z_PEINH,Z_WAERS,Z_AEDAT,Z_EBELN,Z_EBELP)
FROM EKPO INNER JOIN EKKO ON EKKO~EBELN = EKPO~EBELN
UP TO 1 ROWS
WHERE EKKO~BUKRS = ZBUKRS
AND EKKO~EKORG = I_TAB1-EKORG
AND EKKO~LIFNR = I_TAB1-LIFNR
AND EKPO~MATNR = I_TAB1-MATNR
AND EKKO~AEDAT >= Z_DATE "当年1月1号
AND EKPO~LOEKZ <> 'X' "删除
AND EKPO~RETPO <> 'X' "退货
ORDER BY EKKO~AEDAT ASCENDING. "获取创建日期最小的一笔
ENDSELECT.
---------------------------------------获取多笔数据---------------------------------------
IF ITAB_TEMP2[] IS NOT INITIAL.
SELECT MBLNR MJAHR ZEILE EBELN EBELP MATNR MENGE BWART
FROM MSEG
INTO CORRESPONDING FIELDS OF TABLE ITAB_MSEG
FOR ALL ENTRIES IN ITAB_TEMP2 "for all entries in ...
WHERE EBELN = ITAB_TEMP2-EBELN
AND EBELP = ITAB_TEMP2-EBELP.
ENDIF.
SELECT werks matnr
INTO CORRESPONDING FIELDS OF TABLE itab
FROM marc
WHERE werks = '1000'.
SELECT werks matnr
INTO CORRESPONDING FIELDS OF itab
FROM marc
WHERE werks = '1000'.
APPEND itab.
CLEAR itab.
ENDSELECT.
SELECT * INTO TABLE it_pl FROM dd07t
WHERE domname = 'ZZBDPL'
AND ddlanguage = 1
AND domvalue_l NOT IN ('C00','C99','C12','C13','C14','C88')
AND domvalue_l NOT LIKE 'CZ%'.
SELECT * INTO TABLE lt_data FROM zthr_swmx "屏幕输入月份 - 1
WHERE zoaid IN s_zoaid
AND gjahr = lv_gjahr
AND monat = lv_monat
AND bukrs IN s_bukrs
AND zbm IN s_zbm
AND ( zrzxz LIKE 'YT%' or zrzxz LIKE 'YL%' )
AND zdflag <> 'D'.
----------------------------------多表连接-----------------------------------------------
SELECT b~matnr a~lifnr b~ebelp b~ebeln
INTO (itab-matnr,itab-lifnr,itab-ebelp,itab-ebeln)
FROM ekko AS a INNER JOIN ekpo AS b ON a~ebeln = b~ebeln
WHERE b~werks IN s_werks
AND b~matnr IN s_matnr
AND a~lifnr IN s_lifnr.
------------------------------------数量汇总---------------------------------------------
SELECT SUM( menge ) SUM( wemng )
INTO (l_menge,l_wemng)
FROM eket
WHERE ebeln = itab-ebeln
AND ebelp = itab-ebelp.
------------------------------------取最大值--------------------------------------------
SELECT MAX( budat ) INTO p_budat "取最后一笔入库的时间
FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
AND mkpf~mjahr = mseg~mjahr
WHERE mseg~matnr = itab-matnr
AND mseg~werks = p_werks
AND mseg~lifnr <> ''
AND mseg~bwart IN ('103','105').
--------------------------------------Range---------------------------------------------
RANGES: p_auart FOR aufk-auart.
SELECT value INTO p_auart-low
FROM ztmm_config
WHERE werks IN i_werks
AND catgy = 'ZMMR013_01'.
p_auart-sign = 'I'.
p_auart-option = 'EQ'.
APPEND p_auart.
CLEAR p_auart.
ENDSELECT.
四、字符串处理
CONCATENATE year1 month1 day1 INTO p_date1 SEPARATED BY '/'. "拼接
SEARCH p_string FOR x. "查找字符
CONDENSE p_string NO-GAPS. "去空格
REPLACE 'ST' WITH 'PC' INTO p_string. "用PC替换ST
SPLIT c1 AT c2 INTO c3 c4 c5 c6. "分割字符串
SPLIT p_name AT '/' INTO name1 name2. "分割字符串到字段
SPLIT lv_string AT ',' INTO TABLE lt_table. "分割字符串到内表
CONCATENATE LINES OF itab INTO result SEPARATED BY ','. "将内表用符号分割到字段(内表只有一个字段)
p_len = STRLEN( p_name ). "获取字符串长度
SHIFT p_name BY 35 PLACES LEFT. "去掉字符串的前n个位置的字符(LEFT:从左边截断;RIGHT:从右边截断)
SHIFT p_name UP TO 'S' LEFT. "去掉字符串中在字母S左边之前的字符
SHIFT P_LINE LEFT DELETING LEADING '0'. "去除左侧前导零
SHIFT P_LINE RIGHT DELETING TRAILING '0'. "去除右侧后缀零
TRANSLATE p_name TO UPPER CASE. "转换成大写
TRANSLATE p_name TO LOWER CASE. "转换成小写
五、指针常见用法
-----------------------------------语法-------------------------------------------
*分配某个变量给指针
ASSIGN var TO <fs>.
*分配结构中的某个字段的地址给指针
ASSIGN COMPONENT pos OF STRUCTURE struc TO <fs>.
*分配整个内表行给指针(指针必须定义为有栏位结构的类型)
READ TABLE itab INDEX/WITH KEY .. ASSIGNING <fs>.
LOOP AT itab
ASSIGNING <fs>.
ENDLOOP.
*分配类的方法或接口给指针
ASSIGN dref->* TO <fs>.
--------------------------------用指针修改内表字段的值--------------------------------
FIELD-SYMBOLS <FA1> TYPE ANY. "定义指针
DATA: Z_FIELD1 TYPE STRING.
LOOP AT GT_OUT.
READ TABLE LT_OUT INTO LS_OUT WITH KEY ZTYPE = GT_OUT-ZTYPE ZXH = GT_OUT-ZXH.
IF SY-SUBRC = 0.
CONCATENATE 'LS_OUT-ZJE' Z_MON INTO Z_FIELD1.
ASSIGN (Z_FIELD1) TO <FA1>.
IF SY-SUBRC = 0.
<FA1> = GT_OUT-ZJE. "金额
ENDIF.
MODIFY LT_OUT FROM LS_OUT INDEX GT_OUT-ZXH.
ENDIF.
ENDLOOP.
-------------------------------用指针修改屏幕字段的值---------------------------------
FIELD-SYMBOLS: <FS> TYPE ANY. "定义指针
DATA: LV_FIELD TYPE STRING.
DATA: Z_ISM04 TYPE I VALUE 10.
LV_FIELD = '(SAPLXCOF)AFRUD_IMP-ISM04'. "字段名称
ASSIGN (LV_FIELD) TO <FS>.
IF <FS> IS ASSIGNED.
<FS> = Z_ISM04. "给指针赋值,修改屏幕字段值
ENDIF.
**&---------------------------------------------------------------------*
* * * 指针定义
**&---------------------------------------------------------------------*
FIELD-SYMBOLS: <FS_TABLE> TYPE STANDARD TABLE,
<FS_AREA> TYPE ANY,
<FS_FIELD> TYPE ANY.
FIELD-SYMBOLS: <FS_TABLE_ALV> TYPE STANDARD TABLE,
<FS_AREA_ALV> TYPE ANY,
<FS_FIELD_ALV> TYPE ANY.
IT_WAGE[] = <FS_TABLE>.
LOOP AT <FS_TABLE> INTO <FS_AREA>.
ASSIGN COMPONENT 'ZOAID' OF STRUCTURE <FS_AREA> TO <FS_FIELD>.
IF <FS_FIELD>+0(1) = '0'.
SHIFT <FS_FIELD> BY 1 PLACES LEFT. "去除左边第一位0
ENDIF.
MOVE-CORRESPONDING <FS_AREA> TO IT_YFGS.
IF IT_YFGS-ZRZXZ+0(2) = 'YT'.
MOVE-CORRESPONDING IT_YFGS TO IT_05.
APPEND IT_05.
ENDIF.
MODIFY <FS_TABLE> FROM <FS_AREA>.
CLEAR: IT_YFGS,IT_05.
ENDLOOP.
MODIFY (P_TAB) FROM TABLE <FS_TABLE>.
六、使用指针FIELD-SYMBOLS)定义动态内表
1. 基本动态内表定义
DATA: lv_tabname TYPE tabname VALUE 'MARA'.
FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE. "定义表指针
"创建动态内表
CREATE DATA lr_data TYPE TABLE OF (lv_tabname).
ASSIGN lr_data->* TO <fs_table>. "将指针指向动态内表
2. 完全动态内表(结构和字段都动态)
DATA: lt_fields TYPE TABLE OF dfies,
lr_struct TYPE REF TO data,
lr_table TYPE REF TO data.
"获取表结构(例如从数据字典)
CALL FUNCTION 'DDIF_FIELDINFO_GET'
EXPORTING
tabname = 'MARA'
TABLES
dfies_tab = lt_fields.
"创建动态结构
CALL METHOD cl_alv_table_create=>create_dynamic_table
EXPORTING
it_fieldcatalog = lt_fields
IMPORTING
ep_table = lr_table.
"分配给字段符号
FIELD-SYMBOLS: <fs_dyn_table> TYPE ANY TABLE.
ASSIGN lr_table->* TO <fs_dyn_table>.
3. 基于类型描述的动态内表
DATA: lr_type TYPE REF TO cl_abap_structdescr,
lr_table TYPE REF TO data.
"获取类型描述
lr_type ?= cl_abap_structdescr=>describe_by_name( 'MARA' ).
"创建动态表类型
DATA(lr_table_type) = cl_abap_tabledescr=>create( lr_type ).
"创建动态内表
CREATE DATA lr_table TYPE HANDLE lr_table_type.
"分配给字段符号
FIELD-SYMBOLS: <fs_dyn_tab> TYPE ANY TABLE.
ASSIGN lr_table->* TO <fs_dyn_tab>.
4. 动态内表操作示例
"填充动态内表
SELECT * FROM (lv_tabname) INTO TABLE <fs_table> UP TO 10 ROWS.
"读取动态内表数据
FIELD-SYMBOLS: <fs_line> TYPE any.
LOOP AT <fs_table> ASSIGNING <fs_line>.
"访问动态字段
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_field>).
IF sy-subrc = 0.
WRITE: / <fs_field>.
ENDIF.
ENDLOOP.
5. 动态内表与ALV结合使用
DATA: lo_alv TYPE REF TO cl_salv_table.
"创建ALV显示动态内表
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = <fs_dyn_table> ).
CATCH cx_salv_msg.
ENDTRY.
"显示ALV
lo_alv->display( ).
6. 动态内表字段操作
"动态访问内表字段
ASSIGN COMPONENT 'FIELDNAME' OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<fs_value>).
"动态修改字段值
IF sy-subrc = 0.
<fs_value> = 'New Value'.
ENDIF.
7. 高级用法:动态内表与RTTS
DATA: lo_struct TYPE REF TO cl_abap_structdescr,
lo_table TYPE REF TO cl_abap_tabledescr,
lr_data TYPE REF TO data.
"创建动态结构
lo_struct ?= cl_abap_structdescr=>describe_by_name( 'BSEG' ).
"创建动态表类型
lo_table = cl_abap_tabledescr=>create( p_line_type = lo_struct ).
"创建动态内表
CREATE DATA lr_data TYPE HANDLE lo_table.
FIELD-SYMBOLS: <fs_dyn_tab> TYPE ANY TABLE.
ASSIGN lr_data->* TO <fs_dyn_tab>.
持续更新~~

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)