跳转至

ABAP WTF

记录一些 ABAP 开发 WTF 的时刻

你使用一门编程语言一段时间后你总会看到它的局限性,不管你是否热爱它;不同的编程被创造可能是不同时代有不同热爱造轮子的人,而留下的且被社区使用的编程语言都是能在各自领域能解决实际问题的。

2020-08-14 0x01

FIELD-SYMBOLS <gdyn_table> TYPE any table.
FIELD-SYMBOLS <gdyn_wa> TYPE any.

CREATE DATA gdy_table TYPE TABLE OF (gv_tabname_zk).
ASSIGN gdy_table->* TO <gdyn_table>.
CREATE DATA gdy_line  TYPE  (gv_tabname_zk).
ASSIGN gdy_line->* TO <gdyn_wa>.

" select some stuffs into <gfs_table>

LOOP AT <gfs_table> ASSIGN <gfs_wa>.
  " do something
ENDLOOP.

IF <gfs_wa> IS ASSIGN.
  " never run here
ENDIF.

2020-08-14 0x2

  • 字符类型与字符串类型的区别
  • 字符类型的压缩
IF 'A' EQ 'A '.
  WRITE 'True'.
ENDIF.

IF 'A' EQ ' A'.
  WRITE 'Flase'.
ENDIF.

IF  ' A' EQ ' A '.
  WRITE 'True'.
ENDIF.

IF '' EQ abap_false AND ' ' EQ abap_false AND ` ` EQ abap_flase.
  WRITE 'True'.
ENDIF.

2020-08-14 0x3

DATA(time) = sy-datum.

WRITE time - 1. " WTF

2020-08-21 0x01

" LVC_FIELDCATALOG_MERGE - I_INTERNAL_TABNAME does not work

2020-08-25 0x01

IMPORT 语法的时候会默认输入参数名称

IMPORT p_memory FROM MEMORY ID 'XXX'.

" =>

IMPORT p_memory = p_memory FROM MEMORY ID 'XXX'.

2020-08-27 0x01

字符型日期与日期类型

DATA datum_date TYPE datum.
datum_date = datum_date - 7. " 2020-02-02
DATA(datum_string) = sy-datum - 7. " 71456  

2020-08-28 0x01

使用 ST05 监控 FOR ALL ENTRIES IN 语法执行的 SQL 语句

FOR 两个条件加 OR 正常的条件

SELECT PARTNER,
       NAME,
       bu_group
  FROM but000
  UP TO 10 ROWS
  INTO TABLE @DATA(lt_itab).


IF lt_itab[] IS NOT INITIAL.

  SELECT LIFNR,
         LAND1
    FROM lfa1
    FOR ALL ENTRIES IN @lt_itab
    WHERE LIFNR EQ @lt_i ta b-PARTNER
      AND KTOKK EQ @lt_itab-bu_group
      OR LAND1 NE 'CN'
    INTO TABLE @DATA(lt_lfa1).

  BREAK-POINT.
ENDIF.
 SELECT
   /* FDA WRITE */
   DISTINCT "LFA1" . "LIFNR" , "LFA1" . "LAND1"
 FROM
   "LFA1" , ? AS "t_00" ("C_0" NVARCHAR(10), "C_1" NVARCHAR(4))
 WHERE
   "LFA1" . "MANDT" = ? AND ( "LFA1" . "LIFNR" = "t_00" . "C_0" 
   AND "LFA1" . "KTOKK" = "t_00" . "C_1" OR "LFA1" . "LAND1" <> ? ) WITH RANGE_RESTRICTION
   ('CURRENT')

FOR 空的条件

SELECT PARTNER,
       NAME,
       bu_group
  FROM but000
  UP TO 10 ROWS
  INTO TABLE @DATA(lt_itab).


IF lt_itab[] IS NOT INITIAL.

  CLEAR lt_itab[].

  SELECT LIFNR,
         LAND1
    FROM lfa1
    FOR ALL ENTRIES IN @lt_itab
    WHERE LIFNR EQ @lt_itab-PARTNER
      AND KTOKK EQ @lt_itab-bu_group
    INTO TABLE @DATA(lt_lfa1)
    UP TO 100 ROWS..

  BREAK-POINT.
ENDIF.
 SELECT
   DISTINCT "LIFNR" , "LAND1"
 FROM
   "LFA1"
 WHERE
   "MANDT" = ?
 LIMIT  100
   WITH RANGE_RESTRICTION('CURRENT')

FOR 一个条件

SELECT partner,
       NAME,
       bu_group
  FROM but000
  UP TO 10 ROWS
  INTO TABLE @DATA(lt_itab).


IF lt_itab[] IS NOT INITIAL.

  SELECT lifnr,
         land1
    FROM lfa1
    FOR ALL ENTRIES IN @lt_itab
    WHERE lifnr EQ @lt_itab-partner
    INTO TABLE @DATA(lt_lfa1)
    UP TO 100 ROWS..

  BREAK-POINT.
ENDIF.
SELECT
  DISTINCT "LIFNR" , "LAND1"
FROM
  "LFA1"
WHERE
  "MANDT" = ? AND "LIFNR" IN ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )
LIMIT  100
  WITH RANGE_RESTRICTION('CURRENT')

FOR 两个条件 BETWEEN OR

SELECT partner,
       NAME,
       bu_group
  FROM but000
  UP TO 10 ROWS
  INTO TABLE @DATA(lt_itab).


IF lt_itab[] IS NOT INITIAL.

  SELECT lifnr,
         land1
    FROM lfa1
    FOR ALL ENTRIES IN @lt_itab
    WHERE lifnr EQ @lt_itab-partner
       OR ktokk EQ @lt_itab-bu_group
    INTO TABLE @DATA(lt_lfa1)
    UP TO 100 ROWS..

  BREAK-POINT.
ENDIF.
 SELECT
   /* FDA WRITE */
   DISTINCT "LFA1" . "LIFNR" , "LFA1" . "LAND1"
 FROM
   "LFA1" , ? AS "t_00" ("C_0" NVARCHAR(10), "C_1" NVARCHAR(4))
 WHERE
   "LFA1" . "MANDT" = ? AND ( "LFA1" . "LIFNR" = "t_00" . "C_0" OR "LFA1" .
   "KTOKK" = "t_00" . "C_1" )
 LIMIT  100
   WITH RANGE_RESTRICTION('CURRENT')

FOR 两个条件加 OR

SELECT partner,
       NAME,
       bu_group
  FROM but000
  UP TO 10 ROWS
  INTO TABLE @DATA(lt_itab).


IF lt_itab[] IS NOT INITIAL.

  SELECT lifnr,
         land1
    FROM lfa1
    FOR ALL ENTRIES IN @lt_itab
    WHERE lifnr EQ @lt_itab-partner
       OR ktokk EQ @lt_itab-bu_group
      AND land1 NE ''
    INTO TABLE @DATA(lt_lfa1)
    UP TO 100 ROWS..

  BREAK-POINT.
ENDIF.
 SELECT
   /* FDA WRITE */
   DISTINCT "LFA1" . "LIFNR" , "LFA1" . "LAND1"
 FROM
   "LFA1" , ? AS "t_00" ("C_0" NVARCHAR(10), "C_1" NVARCHAR(4))
 WHERE
   "LFA1" . "MANDT" = ? AND ( "LFA1" . "LIFNR" = "t_00" . "C_0" OR "LFA1" .
   "KTOKK" = "t_00" . "C_1" AND "LFA1" . "LAND1" <> ? )
 LIMIT  100
   WITH RANGE_RESTRICTION('CURRENT')

总之注意判断非空以及使用括号

2020-09-03 0x01

lmd => 1md

2020-09-16 0x01

FORM frm_upload_excel_by_index_correct
  TABLES t_intern TYPE STANDAR TABLE OF zalsmex_tabline 
  USING uv_end_row TYPE i
        uv_index TYPE i.
  ...
ENDFORM.

PERFORM TABLES excel ???excel??? USING 32 1.

---

FORM frm_upload_excel_by_index_correct
  TABLES t_intern STRUCTURE zalsmex_tabline 
  USING uv_end_row TYPE i
        uv_index TYPE i.
  ...
ENDFORM.

PERFORM TABLES excel USING 32 1.

2020-09-17 0x01

METHOD quote.
  out = `'` &&  replace( val  = val
                         sub  = `'`
                         with = `''`
                         occ  = 0 )  && `'`.
ENDMETHOD.

METHOD quote_str.
  out = ```` &&  replace( val  = val
                          sub  = ````
                          with = ``````
                          occ  = 0 )    && ````.
ENDMETHOD.

2020-11-25 0x01

You can use BT option in abap select option. You can use GT to replace >.

2020-11-25 0x02

exit from loop, return this program

SELECT *
  FROM spfli
  INTO TABLE @DATA(itab)
  UP TO 10 ROWS.

BREAK-POINT.

LOOP AT itab INTO DATA(line).
  IF line-CARRID = `DL`.
    EXIT.
  ENDIF.
ENDLOOP.


LOOP AT itab INTO line.
  IF line-CARRID = `DL`.
    RETURN.
  ENDIF.
ENDLOOP.

2020-11-25 0x03

you can't do this

SELECT COUNT(*)
  FROM (lv_tabname_zt)
  INTO @DATA(lv_count)
 WHERE /1md/ztzland EQ @iv_data-zprel_id
   AND usmd_active EQ '1' .

you must do like this

DATA lv_count TYPE i.

SELECT COUNT(*)
  FROM (lv_tabname_zt)
  INTO lv_count
 WHERE /1md/ztzland EQ iv_data-zprel_id
   AND usmd_active EQ '1' .

2020-12-09 0x01

CALL FUNCTION - IN BACKGROUND TASK MUST COMMIT WORK before next time!!!

2020-12-10 0x01

IF exits NE abap_true

如果字符的类型是 C(40) 这种类型

lv_str = '1234'.
strlen( lv_str ) = 4  " true
lv_str CN '1234' " flase
在使用操作符时 c(40) 会补空格占位
CONDENSE 无效

2021-04-15 0x01

 DATA lv_count TYPE int8.  

* hana SQL is same  
SELECT SINGLE COUNT(*)  
  FROM cdpos INTO @lv_count  
  WHERE objectid = '****'.  

*SELECT  
*  COUNT(*)  
*FROM  
*  "CDPOS"  
*WHERE  
*  "MANDANT" = ? AND "OBJECTID" = N  
*  '****' WITH  
*  RANGE_RESTRICTION('CURRENT').  
WRITE: lv_count.  

*SELECT COUNT(*)  
*  FROM cdpos INTO @lv_count  
*  WHERE objectid = '****'.  
*  
* SELECT  
*   COUNT(*)  
* FROM  
*   "CDPOS"  
* WHERE  
*   "MANDANT" = ? AND "OBJECTID" = N  
*   '****' WITH  
*   RANGE_RESTRICTION('CURRENT').  
WRITE: lv_count.  

* hana SQL is same, but first is FDA READ and quicklier  
SELECT SINGLE objectid  
  FROM cdpos INTO @DATA(lv_objecyid)  
  WHERE objectid = '****'.  

*  SELECT  
*    "OBJECTID"  
*  FROM  
*    "CDPOS"  
*  WHERE  
*    "MANDANT" = ? AND "OBJECTID" = N  
*    '****'  
*  LIMIT  1  
*    WITH RANGE_RESTRICTION('CURRENT')  

WRITE lv_objecyid.  


SELECT objectid  
  FROM cdpos INTO TABLE @DATA(lt_objecyid)  
  UP TO 1 ROWS  
  WHERE objectid = '****'.  

*  SELECT  
*    /* FDA READ */  
*    "OBJECTID"  
*  FROM  
*    "CDPOS"  
*  WHERE  
*    "MANDANT" = ? AND "OBJECTID" = N  
*    '****'  
*  LIMIT  1  
*    WITH RANGE_RESTRICTION('CURRENT')  
WRITE lines( lt_objecyid ).

2021-06-08 0x01

ABAP RFC 定义的类型和长度必须一致,不然反序列化后前一个字段的值会影响后面的字段(比如导致上溢)

2021-07-08 0x01

DATA: BEGIN OF test,
  " a TYPE n LENGTH 4,
  a TYPE string, " WTF: 888 > 1001

DATA itab LIKE STANDARD TABLE OF test WITH EMPTY KEY.

APPEND VALUE #( a = '888' ) TO itab.
APPEND VALUE #( a = '44' ) TO itab.
APPEND VALUE #( a = '888' ) TO itab.
APPEND VALUE #( a = '1001' ) TO itab.

SORT itab BY a DESCENDING.

2021-07-08 0x01

" Table field: wrf1-lonr type c len 12
" Table field: ekko-reswk type c len 4

" WTF: 当在 SE11 中查询 2000 时会把表 wrf1 中的 000000002000 查询出来,但是当你在 inner join 表的时候是无法关联的

2021-09-09 0x01

WRITE lines( s_range ). " 10000
DELETE itab WHERE field IN s_range. " it's low

" Instead of
LOOP itab INTO DATA(line) WHERE field NOT IN s_range.
  APPEND line TO itab_extend.
EMDLOOP.

最后更新: 2021-09-17
创建日期: 2021-06-08