ABAP Help Document(19):9.4内表类型运算

9.4Internal Tables

          内表,带表头行内表已经弃用。

          Tcode: RZ11,查看Profile Parameter, 参数:ztta/max_memreq_MB,内表最大内存空间;

          内表种类:Standard Table,拥有唯一primary table index; Sorted tables,使用primary table key排序,默认按照大小升序,table key可以是唯一也可以非唯一;Hashed tables,使用hash 表达式作为键值;

          Field Symbel使用时,Type any table,实际可以是三种table,Type Index table,实际可以是standard table,sorted table;

Internal Table Category:

          Standard Table,通过Append添加记录,查询效率随着记录数线性增加,通过排序,使用Binary Search二分查找法可以提高查询效率;

          Sorted Table,已经在创建时排好顺序,通过Insert插入记录,查询时自动使用二分查找;

          Hashed table,使用hash表达式作为键值,查询每条记录效率相同;

          内表都拥有primary key和最多15个可选的secondary table keys,如果不指定,Standard Table会创建默认key,可能primary table key为空,但是Sorted Table,Hashed table不能为空。

Primary table key:

          Primary table key,通过定义DATA,TYPE时,指定UINQUE|NON-UNIQUE KEY。Standard key,内表行所有字符类型和字节类型字段作为key值。

Empty table key:

          目前只能隐式定义Standard Table的primary table key为空,未来支持显示使用EMPTY KEY定义primary table key为空。

Secondary keys:

          当插入,删除内表记录时,唯一Secondary keys会自动更新,非唯一Secondary keys,会在下一次使用key时更新。类:CL_ABAP_ITAB_UTILITIES,提供方法更新secondary keys。

          在非常大的内表,基本上为读取操作,可以使用Secondary keys,提高效率;secondary hash keys不能有太多的components,secondary sort keys可以有大量components;

          不适合使用Secondary keys,内表行小于50,有大量写操作内表,若非强烈需求内表项次唯一性,不使用secondary hash keys。

          key,sorted key,hashed key效能比较示例:DEMO_READ_TABLE_USING_KEY。

示例1:READ

"内表
FORM f_character_process_itab1.
  "读取内表:1.READ TABLE;2.LOOP AT;3.AT
  "添加数据:1.INSERT;2.COLLECT;3.APPEND
  "修改删除排序:1.MODIFY;2.DELETE;3.SORT
  "查找,替换操作:1.FIND IN TABLE;2.REPLACE IN TABLE
  "间隔连接:PROVIDE
"read table
*READ TABLE itab { table_key
*                | free_key
*                | index } result.
"table_key
*{ FROM wa [USING KEY keyname] }
*  | { WITH TABLE KEY [keyname COMPONENTS]
*                     {comp_name1|(name1)} = dobj1
*                     {comp_name2|(name2)} = dobj2 } ... .
"free_key
*WITH KEY { comp1 = dobj1 comp2 = dobj2 ... [BINARY SEARCH] }
* | { keyname COMPONENTS comp1 = dobj1 comp2 = dobj2 ... }.
"index
*INDEX idx [USING KEY keyname]

"result
*  { INTO wa [transport_options] }
*  | { ASSIGNING <fs> [CASTING] }
*  | { REFERENCE INTO dref }
*  | { TRANSPORTING NO FIELDS }.
"[transport_options]
*[COMPARING { {comp1 comp2 ...}|{ALL FIELDS}|{NO FIELDS} }]
*[TRANSPORTING { {comp1 comp2 ...}|{ALL FIELDS} }]
   DATA:lt_sflight TYPE HASHED TABLE OF sflight
         WITH UNIQUE KEY carrid connid fldate
         WITH NON-UNIQUE SORTED KEY k_occ COMPONENTS seatsocc.
   DATA:ls_sflight LIKE LINE OF lt_sflight.

   DATA:lt_sflight1 TYPE SORTED TABLE OF sflight
         WITH UNIQUE KEY carrid connid fldate.
   DATA:ls_sflight1 LIKE LINE OF lt_sflight1.
   DATA:ls_sflight1_ref TYPE REF TO sflight.
   FIELD-SYMBOLS:<fs_sflight1> LIKE LINE OF lt_sflight1.

   "两句代码差异?
   SELECT * FROM sflight INTO TABLE lt_sflight.
   "SELECT * INTO TABLE lt_sflight FROM sflight.
   SELECT * FROM sflight INTO TABLE lt_sflight1.
   "读取记录with key
   "这个并不是内表第一条,而是按照k_ooc处理后第一条数据
   READ TABLE lt_sflight INDEX 1 USING KEY k_occ INTO ls_sflight.
   WRITE:/ sy-tabix,ls_sflight-carrid,ls_sflight-connid,
    ls_sflight-fldate,ls_sflight-seatsocc.

   "读取记录到wa
   READ TABLE lt_sflight1 INDEX 2 INTO ls_sflight1.
   IF sy-subrc = 0.
     "修改内表记录
     ls_sflight1-seatsocc = 20.
     MODIFY lt_sflight1 FROM ls_sflight1 INDEX sy-tabix.
   ENDIF.

   "读取记录到field symbol
   READ TABLE lt_sflight1
    WITH TABLE KEY carrid = 'AZ' connid = '555' fldate = '20131030'
    ASSIGNING <fs_sflight1>.
   "直接修改内表行数据
   <fs_sflight1>-seatsocc = 20.

   "读取记录到reference
   READ TABLE lt_sflight1 INDEX 1
    REFERENCE INTO ls_sflight1_ref.
   IF sy-subrc = 0.
     "直接修改内表行数据
     ls_sflight1_ref->seatsocc = 20.
   ENDIF.

  "读取记录,不保存
  READ TABLE lt_sflight1 INDEX 1
    TRANSPORTING NO FIELDS.
  IF sy-subrc = 0.
    "只检查读取数据是否存在于内表
    "sy-tabix,数据id
  ENDIF.

  "Comparing比较字段
  "Transporting key比较字段
  "工作区指定比较字段
  ls_sflight1-seatsocc = 2.
  READ TABLE lt_sflight1
   INTO ls_sflight1
   WITH KEY carrid = 'AZ'
            connid = '555'
            fldate = '20131030'
   COMPARING seatsocc
   "transporting只指定carrid,connid,只读取key值符合的一笔记录
   "fldate条件不会考虑
   TRANSPORTING carrid connid.
  "当comparing和key都符合,sy-subrc  = 0
  "当comparing指定字段不符合时,sy-subrc = 2
  IF sy-subrc = 0.
   WRITE:/ sy-subrc,ls_sflight1-carrid,ls_sflight1-connid,
    ls_sflight1-fldate,ls_sflight1-seatsocc,
    ls_sflight1-price.
  ELSEIF sy-subrc = 2.
   WRITE:/ sy-subrc,ls_sflight1-carrid,ls_sflight1-connid,
    ls_sflight1-fldate,ls_sflight1-seatsocc,
    ls_sflight1-price.
  ELSE.
    WRITE:/ sy-subrc.
  ENDIF.
ENDFORM.

示例2:LOOP

FORM f_character_process_itab2.
"loop循环
*  LOOP AT itab result [cond].
*  ...
*  ENDLOOP.
"result
* { INTO wa }
*| { ASSIGNING <fs> [CASTING] }
*| { REFERENCE INTO dref }
*| { TRANSPORTING NO FIELDS }
"[cond]
*[USING KEY keyname]
*[FROM idx1] [TO idx2]
*[WHERE log_exp|(cond_syntax)]
  DATA:lt_sflight TYPE STANDARD TABLE OF sflight
        WITH NON-UNIQUE KEY PRIMARY_KEY
        COMPONENTS carrid connid fldate
        WITH UNIQUE SORTED KEY k_sort
        COMPONENTS carrid connid fldate
        WITH NON-UNIQUE SORTED KEY k_seatsocc
        COMPONENTS seatsocc.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  TYPES:s_char20 TYPE C LENGTH 20.
  DATA:lt_where TYPE TABLE OF s_char20.
  DATA:ls_where LIKE LINE OF lt_where.

  SELECT * INTO TABLE lt_sflight FROM sflight WHERE carrid = 'AA'.
  "会按照对应key对内表顺序调整
  LOOP AT lt_sflight INTO ls_sflight USING KEY primary_key.
    WRITE:/ 'primary key',ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate,
      ls_sflight-price.
  ENDLOOP.
  LOOP AT lt_sflight INTO ls_sflight USING KEY k_seatsocc.
    WRITE:/ 'seatsocc key',ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate,
      ls_sflight-price,ls_sflight-seatsocc.
  ENDLOOP.
  "指定范围,idx1<idx2
  LOOP AT lt_sflight INTO ls_sflight FROM 1 TO 2.
    WRITE:/ 'from to',ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate.
  ENDLOOP.
  "where条件,最好比较值类型相同
  LOOP AT lt_sflight INTO ls_sflight WHERE CONNID = '0017'.
    WRITE:/ 'where',ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate.
  ENDLOOP.
  "动态where条件
  ls_where = 'CONNID = ''0017'''.
  APPEND ls_where TO lt_where.
  ls_where = 'AND PRICE = ''11.00'''.
  APPEND ls_where TO lt_where.
  LOOP AT lt_sflight INTO ls_sflight WHERE (lt_where).
    WRITE:/ 'dyn where',ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate.
  ENDLOOP.
ENDFORM

示例3:AT

FORM f_character_process_itab3.
*LOOP AT itab result ...
*  [AT FIRST.
*  ENDAT.]
*    [AT NEW comp1.
*     ENDAT.
*       [AT NEW comp2.
*       ENDAT.
*       AT END OF comp2.
*       ENDAT.]
*     AT END OF comp1.
*     ENDAT.]
*  [AT LAST.
*  ENDAT.]
*ENDLOOP.
  DATA:lt_sflight TYPE TABLE OF sflight.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  SELECT * INTO TABLE lt_sflight FROM sflight.
  LOOP AT lt_sflight INTO ls_sflight.
    AT FIRST.
      WRITE:/ 'begining'.
    ENDAT.
    AT NEW carrid.
      WRITE:/ ls_sflight-carrid.
    ENDAT.
    AT NEW connid.
      WRITE:/ ls_sflight-carrid,ls_sflight-connid.
    ENDAT.
    AT END OF connid.
      SUM.
      WRITE:/ ls_sflight-price.
    ENDAT.
    AT END OF carrid.
      SUM.
      WRITE:/ ls_sflight-price.
    ENDAT.
    AT LAST.
      WRITE:/ 'ending'.
    ENDAT.
  ENDLOOP.
ENDFORM

示例4:INSERT

FORM f_character_process_itab4.
"insert
*INSERT line_spec INTO itab_position [result].
"line_spec
* wa
*| {INITIAL LINE}
*| {LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]}
"itab_position
*{TABLE itab}
*| {itab INDEX idx}
*| {itab}
"[result],保留插入行数据
*{ ASSIGNING <fs> [CASTING] }
*| { REFERENCE INTO dref }.
  DATA:lt_sflight TYPE TABLE OF sflight
        WITH UNIQUE SORTED KEY k_carr
        COMPONENTS carrid.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  FIELD-SYMBOLS:<fs_sflight> TYPE sflight.
  "插入初始行,assigning 获取插入行数据
  INSERT INITIAL LINE INTO lt_sflight INDEX 1 ASSIGNING <fs_sflight>.
  "一笔记录
  SELECT SINGLE * INTO ls_sflight FROM sflight WHERE carrid = 'AA'.
  "insert语句:
  "insert wa into itab index idx
  "insert wa into table itab
  "在loop循环中insert wa into itab
  INSERT ls_sflight INTO TABLE lt_sflight.
  LOOP AT lt_sflight INTO ls_sflight.
    WRITE:/ sy-tabix,ls_sflight-carrid,ls_sflight-connid.
    "如果有定义unique key,插入重复key报错
    IF sy-tabix = 1.
      "插入在第一条之前
      ls_sflight-carrid = 'AB'.
      INSERT ls_sflight INTO lt_sflight.
    ENDIF.
  ENDLOOP.
ENDFORM

示例5:COLLECT

FORM f_character_process_itab5.
"collect
*COLLECT wa INTO itab [result].
"[result]
*{ ASSIGNING <fs> [CASTING] }
*| { REFERENCE INTO dref }.
"默认所有字符型,字节型字段为键值,数据型字段相加
  TYPES:BEGIN OF s_sflight,
         carrid TYPE C LENGTH 2,
         connid TYPE C LENGTH 4,
         price TYPE P LENGTH 8 DECIMALS 2,
        END OF s_sflight.
  DATA:lt_sflight TYPE TABLE OF s_sflight
        WITH UNIQUE SORTED KEY k_carr
        COMPONENTS carrid.
  DATA:ls_sflight LIKE LINE OF lt_sflight.

  ls_sflight-carrid = 'AA'.
  ls_sflight-connid = '0011'.
  ls_sflight-price = 1.
  COLLECT ls_sflight INTO lt_sflight.
  "如果指定UNIQUE key
  "carrid,connid必须和已有一致
  "否则例如:AA,0012不允许插入,报错:键值重复
  ls_sflight-carrid = 'AA'.
  ls_sflight-connid = '0011'.
  ls_sflight-price = 1.
  COLLECT ls_sflight INTO lt_sflight.
  ls_sflight-carrid = 'AB'.
  ls_sflight-connid = '0010'.
  ls_sflight-price = 1.
  COLLECT ls_sflight INTO lt_sflight.
  LOOP AT lt_sflight INTO ls_sflight.
    WRITE:/ ls_sflight-carrid,ls_sflight-connid,ls_sflight-price.
  ENDLOOP.
ENDFORM

示例6:APPEND

FORM f_character_process_itab6.
"append
*APPEND line_spec TO itab [SORTED BY comp] [result].
"line_spec
*wa
*| {INITIAL LINE}
*| {LINES OF jtab [FROM idx1] [TO idx2] [USING KEY keyname]}
"和Insert类似,Hash table不能使用append
  DATA:lt_sflight TYPE TABLE OF sflight INITIAL SIZE 1.
  DATA:lt_sflight1 TYPE TABLE OF sflight.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  "append initial line
  APPEND INITIAL LINE TO lt_sflight.
  "append line of itab
  SELECT * INTO TABLE lt_sflight1 FROM sflight.
  APPEND LINES OF lt_sflight1 FROM 1 TO 2 TO lt_sflight.
  "append wa
  ls_sflight-carrid = 'AB'.
  ls_sflight-connid = '0011'.
  APPEND ls_sflight TO lt_sflight.
  "sort by生效只在内表定义INITIAL SIZE大于0
  "降序排列,但是把原有一条记录替换掉了?
  ls_sflight-carrid = 'AC'.
  ls_sflight-connid = '0021'.
  APPEND ls_sflight TO lt_sflight SORTED BY carrid.
  LOOP AT lt_sflight INTO ls_sflight.
    WRITE:/ ls_sflight-carrid,ls_sflight-connid,ls_sflight-price.
  ENDLOOP.
ENDFORM

示例7:MODIFY

FORM f_character_process_itab7.
"modify
*MODIFY { itab_line | itab_lines }.
"itab_line
* { table_key  | index } FROM wa
* [TRANSPORTING comp1 comp2 ...]
* [result].
  "table_key
  "  TABLE itab [USING KEY keyname]
  "index
  "{ itab INDEX idx [USING KEY keyname] }
  "| { itab [USING KEY loop_key]}
"itab_lines
*itab FROM wa [USING KEY keyname]
* TRANSPORTING comp1 comp2 ... WHERE log_exp|(cond_syntax).
  DATA:lt_sflight TYPE SORTED TABLE OF sflight
        WITH UNIQUE KEY primary_key
          COMPONENTS carrid connid fldate
        WITH NON-UNIQUE SORTED KEY k_connid
          COMPONENTS connid.
  DATA:lt_sflight1 TYPE TABLE OF sflight.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  SELECT * INTO TABLE lt_sflight FROM sflight.
  SELECT * INTO TABLE lt_sflight1 FROM sflight.
  "modify table itab [using key xxx] from wa [transporting comp].
  "modify itab index idx [using key xxx] from wa [transporting comp].
  "循环中,modify itab [using key loop_key] from wa [transporting comp].
  "modify itab from wa [USING KEY keyname] [transporting comp] [where].
  LOOP AT lt_sflight INTO ls_sflight USING KEY k_connid WHERE connid = '0017'.
    ls_sflight-price = 20.
    MODIFY lt_sflight USING KEY loop_key FROM ls_sflight TRANSPORTING price.
  ENDLOOP.

  CLEAR ls_sflight.
  ls_sflight-carrid = 'AA'.
  ls_sflight-connid = '0017'.
  ls_sflight-fldate = '20140108'.
  ls_sflight-price = 30.
  "需要指定key域值
  "MODIFY TABLE lt_sflight FROM ls_sflight USING KEY primary_key.
  "如果wa值,不能确定唯一记录不更新
  MODIFY TABLE lt_sflight FROM ls_sflight.

  CLEAR ls_sflight.
  ls_sflight-carrid = 'AA'.
  ls_sflight-connid = '0017'.
  ls_sflight-price = 40.
  "不指定transporting,会全部更新
  MODIFY lt_sflight1 INDEX 1 FROM ls_sflight TRANSPORTING price.
ENDFORM.

示例8:DELETE

FORM f_character_process_itab8.
"DELETE { itab_line | itab_lines | duplicates }.
"itab_line
*{TABLE itab table_key}
*| {itab INDEX idx [USING KEY keyname]}
*| {itab [USING KEY loop_key]}.
"table_key
*{ FROM wa [USING KEY keyname] }
*| { WITH TABLE KEY [keyname COMPONENTS]
*    {comp_name1|(name1)} = dobj1
*    {comp_name2|(name2)} = dobj2}
"itab_lines
*itab [USING KEY keyname] [FROM idx1] [TO idx2]
* [WHERE log_exp|(cond_syntax)] ... .
"duplicates
*ADJACENT DUPLICATES FROM itab [USING KEY keyname]
* [COMPARING {comp1 comp2 ...}|{ALL FIELDS}]... .
  DATA:lt_sflight TYPE SORTED TABLE OF sflight
        WITH UNIQUE KEY primary_key
          COMPONENTS carrid connid fldate
        WITH NON-UNIQUE SORTED KEY k_connid
          COMPONENTS connid.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  SELECT * INTO TABLE lt_sflight FROM sflight.
  "单笔删除
  "delete table itab from wa [using key xxx].
  "delete table itab with table key xxx components comp.
  "delete itab index idx [using key xxx].
  "delete itab [using key loop_key]
  ls_sflight-carrid = 'AA'.
  ls_sflight-connid = '0017'.
  ls_sflight-fldate = '20140108'.
  "wa必须指定所有键值
  "DELETE TABLE lt_sflight FROM ls_sflight USING KEY primary_key.
  "DELETE TABLE lt_sflight FROM ls_sflight.
  "DELETE TABLE lt_sflight WITH TABLE KEY primary_key
  " COMPONENTS carrid = 'AA' connid = '0017' fldate = '20140108'.
  "非unique键,删除符合条件一笔
  "DELETE TABLE lt_sflight WITH TABLE KEY k_connid
  " COMPONENTS connid = '0017'.
  "按照index删除
  DELETE lt_sflight INDEX 1.
  "DELETE lt_sflight INDEX 1 USING KEY primary_key.
  "循环中删除,loop如果指定using key,delete必须有using key loop_key
  LOOP AT lt_sflight INTO ls_sflight USING KEY k_connid WHERE connid = '0017'.
    DELETE lt_sflight USING KEY loop_key.
  ENDLOOP.

  "多笔删除
  "delete itab [using key xxx] from idx to idx.
  "delete itab where.
  DELETE lt_sflight USING KEY primary_key FROM 1 to 2.
  DELETE lt_sflight WHERE carrid = 'AZ' AND connid = '0555'.

  "删除重复
  DELETE ADJACENT DUPLICATES FROM lt_sflight COMPARING ALL FIELDS.
  DELETE ADJACENT DUPLICATES FROM lt_sflight COMPARING carrid connid.
ENDFORM

示例9:SORT

FORM f_character_process_itab9.
"sort
*SORT itab [STABLE]
*{ { [ASCENDING|DESCENDING] [AS TEXT]
* [BY {comp1 [ASCENDING|DESCENDING] [AS TEXT]}
* {comp2 [ASCENDING|DESCENDING] [AS TEXT]}] }
* | { [BY (otab)] } }.
"stable,稳定排序,相同键值相对位置不变
"默认asc
"as text,text比较,否则转换为对应hex比较,convert text类似
"otab
*结构:ABAP_SORTORDER_TAB,行结构:ABAP_SORTORDER
"NAME of type SSTRING;
"DESCENDING of the type CHAR of a length 1;
"ASTEXT of type CHAR with length 1
  DATA:lt_sflight TYPE HASHED TABLE OF sflight
        WITH UNIQUE KEY primary_key
          COMPONENTS carrid connid fldate
        WITH NON-UNIQUE SORTED KEY k_connid
          COMPONENTS connid.
  DATA:ls_sflight LIKE LINE OF lt_sflight.
  SELECT * INTO TABLE lt_sflight FROM sflight.

  "排序
  "sorted table不能sort
  SORT lt_sflight STABLE DESCENDING BY carrid ASCENDING connid DESCENDING fldate ASCENDING.
  LOOP AT lt_sflight INTO ls_sflight.
    WRITE:/ ls_sflight-carrid,ls_sflight-connid,ls_sflight-fldate,ls_sflight-price.
  ENDLOOP.
ENDFORM.

示例10:FIND,REPLACE IN TABLE

FORM f_character_process_itab10.
*FIND [{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF] pattern
*  IN TABLE itab [table_range]
*  [IN {CHARACTER|BYTE} MODE]
*  [find_options].
"table_range
*[FROM lin1 [OFFSET off1]] [TO lin2 [OFFSET off2]]
"[find_options]
*[{RESPECTING|IGNORING} CASE]
*[MATCH COUNT  mcnt]
*{ {[MATCH LINE   mlin]
*   [MATCH OFFSET moff]
*   [MATCH LENGTH mlen]}
*  | [RESULTS result_tab|result_wa] }
*[SUBMATCHES s1 s2 ...]

*REPLACE [{FIRST OCCURRENCE}|{ALL OCCURRENCES} OF] pattern
*        IN TABLE itab [table_range] WITH new
*        [IN {CHARACTER|BYTE} MODE]
*        [replace_options].
"[replace_options]
* [{RESPECTING|IGNORING} CASE]
*[REPLACEMENT COUNT rcnt]
*{ {[REPLACEMENT LINE rlin]
*   [REPLACEMENT OFFSET roff]
*   [REPLACEMENT LENGTH rlen]}
*| [RESULTS result_tab|result_wa] }

"itab必须是标准表,不能有复杂结构(多列)
  TYPES:BEGIN OF s_struc,
          name TYPE C LENGTH 20,
        END OF s_struc.
  DATA:lt_test TYPE TABLE OF s_struc.
  DATA:ls_test LIKE LINE OF lt_test.
  DATA:lv_count TYPE I.
  DATA:lv_line TYPE I.
  DATA:lv_off TYPE I.
  DATA:lv_len TYPE I.
  DATA:lt_result TYPE match_result_tab.
  DATA:ls_result TYPE match_result.
  DATA:lt_result_repl TYPE repl_result_tab.
  DATA:ls_result_repl TYPE repl_result.

  ls_test-name = 'ha-abc-a'.
  APPEND ls_test TO lt_test.
  ls_test-name = 'h-abc-b'.
  APPEND ls_test TO lt_test.
  ls_test-name = 'wa-abc-c'.
  APPEND ls_test TO lt_test.

  "查找
  FIND ALL OCCURRENCES OF REGEX 'abc-.*'
    IN TABLE lt_test
    "内表第1到2行
    FROM 1 TO 2
    IN CHARACTER MODE
    "byte mode不能和respecting case,ignoring case同时
    RESPECTING CASE
    "匹配次数
    MATCH COUNT lv_count
    "最后一次匹配行
    MATCH LINE lv_line
    "最后一次匹配偏移
    MATCH OFFSET lv_off
    MATCH LENGTH lv_len.
  WRITE:/ lv_count,lv_line,lv_off,lv_len.

  FIND ALL OCCURRENCES OF REGEX 'abc-.*'
    IN TABLE lt_test
    RESPECTING CASE
    RESULTS lt_result.
  LOOP AT lt_result INTO ls_result.
    WRITE:/ ls_result-line,ls_result-offset,ls_result-length.
  ENDLOOP.

  REPLACE ALL OCCURRENCES OF REGEX 'abc-'
    IN TABLE lt_test
    FROM 1 TO 2
    WITH '****'
    IN CHARACTER MODE
    RESPECTING CASE
    "替换次数
    REPLACEMENT COUNT lv_count
    "最后一次替换行
    REPLACEMENT LINE lv_line
    "最后一次替换偏移
    REPLACEMENT OFFSET lv_off
    "替换字符串长度
    REPLACEMENT LENGTH lv_len.
  WRITE:/ 'replace:',lv_count,lv_line,lv_off,lv_len.

  REPLACE ALL OCCURRENCES OF REGEX 'abc-'
    IN TABLE lt_test
    WITH '****'
    RESULTS lt_result_repl.
  LOOP AT lt_result_repl INTO ls_result_repl.
    WRITE:/ 'replace1:',ls_result_repl-line,ls_result_repl-offset,ls_result_repl-length.
  ENDLOOP.
ENDFORM

示例11:PROVIDE

 

FORM f_character_process_itab11.
*PROVIDE FIELDS {*|{comp1 comp2 ...}}
*               FROM itab1 INTO wa1 VALID flag1
*               BOUNDS intliml1 AND intlimu1
*               [WHERE log_exp1]
*        FIELDS {*|{comp1 comp2 ...}}
*               FROM itab2 INTO wa2 VALID flag2
*               BOUNDS intliml2 AND intlimu2
*               [WHERE log_exp2]
*               ...
*        BETWEEN extliml AND extlimu
*        [INCLUDING GAPS].
*  ...
*ENDPROVIDE.
  DATA: BEGIN OF wa1,
         col1 TYPE i,
         col2 TYPE i,
         col3 TYPE string,
       END OF wa1.
  DATA: BEGIN OF wa2,
          col1 TYPE i,
          col2 TYPE i,
          col3 TYPE string,
        END OF wa2.
  DATA: itab1 LIKE STANDARD TABLE OF wa1,
        itab2 LIKE STANDARD TABLE OF wa2.
  DATA: flag1(1) TYPE c,
        flag2(1) TYPE c.

  wa1-col1 = 1.
  wa1-col2 = 6.
  wa1-col3 = 'Itab1 Int1'.
  APPEND wa1 TO itab1.
  wa1-col1 = 9.
  wa1-col2 = 12.
  wa1-col3 = 'Itab1 Int2'.
  APPEND wa1 TO itab1.
  wa2-col1 = 4.
  wa2-col2 = 11.
  wa2-col3 = 'Itab2 Int1'.
  APPEND wa2 TO itab2.

  PROVIDE FIELDS col3 FROM itab1 INTO wa1
                                 VALID flag1
                                 BOUNDS col1 AND col2
          FIELDS col3 FROM itab2 INTO wa2
                                 VALID flag2
                                 BOUNDS col1 AND col2
          BETWEEN 2 AND 14.
    WRITE: / wa1-col1, wa1-col2, wa1-col3, flag1.
    WRITE: / wa2-col1, wa2-col2, wa2-col3, flag2.
    SKIP.
  ENDPROVIDE.
ENDFORM

9.5Attributes of Data Objects

          使用DESCRIBE关键词,获取Data Objects属性。

示例:

"确定数据对象属性
FORM f_attribute_object.
"1. DESCRIBE FIELD
*DESCRIBE FIELD dobj
*  [TYPE typ [COMPONENTS com]]
*  [LENGTH ilen IN {BYTE|CHARACTER} MODE]
*  [DECIMALS dec]
*  [OUTPUT-LENGTH olen]
*  [HELP-ID hlp]
*  [EDIT MASK mask].
"2. DESCRIBE TABLE
*DESCRIBE TABLE itab [KIND knd] [LINES lin] [OCCURS n].
"3. DESCRIBE DISTANCE
*DESCRIBE DISTANCE BETWEEN dobj1 AND dobj2 INTO dst
*                          IN {BYTE|CHARACTER} MODE.
  TYPES:BEGIN OF s_struc1,
        name TYPE string,
        age TYPE I,
        address TYPE C LENGTH 30,
        acount TYPE P LENGTH 7 DECIMALS 3,
        carrid TYPE spfli-carrid,
        fldate TYPE sflight-fldate,
        END OF s_struc1.
  DATA:lt_info TYPE TABLE OF s_struc1.
  DATA:ls_info LIKE LINE OF lt_info.
  DATA:lt_sflight TYPE TABLE OF sflight INITIAL SIZE 2.
  SELECT * INTO TABLE lt_sflight FROM sflight.
  "类型id
  DATA:lv_type TYPE C LENGTH 1.
  "结构体components数量
  DATA:lv_comp TYPE I.
  "长度
  DATA:lv_len TYPE I.
  "精度
  DATA:lv_dec TYPE I.
  "输出长度
  DATA:lv_outlen TYPE I.
  "help id
  DATA:lv_help TYPE string.
  "mask
  DATA:lv_mask TYPE string.
  "类型id:
  "b=>b;s=>s;i=>I;p=>P;decfloat16=>a;decfloat34=>e;f=>F
  "c=>c;string=>g;n=>N;d=>D;t=>T;x=>X;xstring=>y
  "Data reference=>l;Object referenc=>r
  "Flat Structure=>u;Deep Structure=>v
  "Internal Table=>h
  "type = h,component = 0
  DESCRIBE FIELD lt_info TYPE lv_type COMPONENTS lv_comp.
  "type = v,compnent = 3
  DESCRIBE FIELD ls_info TYPE lv_type COMPONENTS lv_comp.
  WRITE:/ lv_type,lv_comp.
  "len只对C,N,D,T类型有效
  "len = 60
  DESCRIBE FIELD ls_info-address LENGTH lv_len IN BYTE MODE.
  "len = 30
  DESCRIBE FIELD ls_info-address LENGTH lv_len IN CHARACTER MODE.
  WRITE:/ lv_len.
  "dec = 3
  DESCRIBE FIELD ls_info-acount DECIMALS lv_dec.
  WRITE:/ lv_dec.
  "out_len = 15,P类型(length * 2 + 1)
  DESCRIBE FIELD ls_info-acount OUTPUT-LENGTH lv_outlen.
  WRITE:/ lv_outlen.
  "hlp
  "SPFLI-CARRID
  DESCRIBE FIELD ls_info-carrid HELP-ID lv_help.
  WRITE:/ lv_help.
  "edit mask
  DESCRIBE FIELD ls_info-fldate EDIT MASK lv_mask.
  WRITE:/ lv_mask.

  "表类型
  "T:standard table;S:sorted table;H:hashed table;
  "sydes_kind-standard;sydes_kind-sorted;sydes_kind-hashed in type group SYDES.
  DATA:lv_kind TYPE C LENGTH 1.
  DATA:lv_line TYPE I.
  "INITIAL SIZE
  DATA:lv_initial TYPE I.
  "table
  "kind = T;line = 110;occurs = 2
  DESCRIBE TABLE lt_sflight KIND lv_kind LINES lv_line OCCURS lv_initial.
  WRITE:/ lv_kind,lv_line,lv_initial.
ENDFORM.

RTTS,Run Time Type Servive。运行过程中,动态创建数据类型对象。

类层级结构:

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

示例:

"RTTS,动态
FORM f_attribute_object_rtts.
  DATA:lo_typedesc TYPE REF TO cl_abap_typedescr.
  DATA:lv_p TYPE P LENGTH 8 DECIMALS 3.

  lo_typedesc = cl_abap_typedescr=>describe_by_data( lv_p ).
  "\TYPE=%_T00006S00000000O000000015
  WRITE:/ lo_typedesc->absolute_name.
  "3
  WRITE:/ lo_typedesc->decimals.
  "E
  WRITE:/ lo_typedesc->kind.
  "8
  WRITE:/ lo_typedesc->length.
  "P
  WRITE:/ lo_typedesc->type_kind.
ENDFORM

9.6Streaming

Streaming类和接口结构

 

Streaming抽象类

CL_ABAP_MEMORY_C_READER

CL_ABAP_MEMORY_C_WRITER

CL_ABAP_MEMORY_X_READER

CL_ABAP_MEMORY_X_WRITER

Streaming for String类:

CL_ABAP_STRING_C_READER

CL_ABAP_STRING_C_WRITER

CL_ABAP_STRING_X_READER

CL_ABAP_STRING_X_WRITER

Streaming for itab类:

CL_ABAP_ITAB_C_READER

CL_ABAP_ITAB_C_WRITER

CL_ABAP_ITAB_X_READER

CL_ABAP_ITAB_X_WRITER

示例1:

FORM f_streaming_string.
  DATA:string_writer TYPE REF TO cl_abap_string_c_writer,
       string_reader TYPE REF TO if_abap_c_reader.
  DATA snippet TYPE c LENGTH 4.
  CREATE OBJECT string_writer TYPE cl_abap_string_c_writer.

  DO 10 TIMES.
    string_writer->write( |{ sy-index - 1 }| ).
  ENDDO.
  string_writer->close( ).
  CREATE OBJECT string_reader TYPE cl_abap_string_c_reader
    EXPORTING
      str = string_writer->get_result_string( ).
  "跳到第三个
  string_reader->skip( 3 ).
  WHILE string_reader->data_available( ) = 'X'.
    "每两个字符读取
    snippet = string_reader->read( 2 ).
    WRITE / snippet.
  ENDWHILE.
  string_reader->close( ).
ENDFORM.

示例2:

FORM f_streaming_itab.
  DATA:itab TYPE TABLE OF string,
       text TYPE string.
  DATA itab_reader TYPE REF TO if_abap_c_reader.

  APPEND `abc` TO itab.
  APPEND `def` TO itab.
  APPEND `ghi` TO itab.
  CREATE OBJECT itab_reader TYPE cl_abap_itab_c_reader
    EXPORTING
      itab = itab.
  WHILE itab_reader->data_available( ) = 'X'.
    "字符长度读取
    text = itab_reader->read( 2 ).
    WRITE / text.
  ENDWHILE.
  itab_reader->close( ).
ENDFORM
posted @ 2021-04-22 21:14  渔歌晚唱  阅读(248)  评论(0编辑  收藏  举报