- 隨著 ABAP 的迭代升級,產生了許多新語法,為了在以后的作業中提高作業效率,也為了能夠看懂大佬寫的代碼,這邊對新語發進行了一些總結,以便于學習和回顧.
*&---------------------------------------------------------------------* *& Report YTEST_ZJ009 *&---------------------------------------------------------------------* *&new為最新理解 *&---------------------------------------------------------------------* REPORT YTEST_ZJ009. *TABLES TABLES:ytest_ng. TYPES: BEGIN OF ty_data. INCLUDE TYPE ytest_ng. TYPES: flag TYPE char1, END OF ty_data. CONSTANTS:c_name2(4) VALUE '王明', c_gender2(1) VALUE '男', c_education2(2) VALUE '專科', c_rank1(4) VALUE '銷售主管', c_rank2(4) VALUE '銷售雇員', c_name3(4) VALUE 'LISA', c_gender3(1) VALUE '女', c_education3(2) VALUE '本科', c_name4(4) VALUE 'TOM'. *&---------------------------------------------------------------------- * 練習一:行內宣告 * 語法:DATA(...) ,ASSIGNING FILED-SYMBOL(…) * ALPHA conversion * Concatenation 串聯 *&---------------------------------------------------------------------* cl_demo_output=>write( '練習一:行內宣告' ). *1>取數ytest_ng表 第1 行資料到內表 并輸出 SELECT * FROM ytest_ng INTO TABLE @DATA(gt_data) UP TO 1 ROWS. cl_demo_output=>write( gt_data ). *3> 定義結構,讀取內表第一行 并輸出 READ TABLE gt_data INTO DATA(gs_data) INDEX 1. IF sy-subrc EQ 0. cl_demo_output=>write( gs_data ). CLEAR gs_data. ENDIF. *4> 定義指標并修改000001人員職級為銷售主管 CONSTANTS: c_xszg(10) VALUE '銷售主管'. LOOP AT gt_data ASSIGNING FIELD-SYMBOL(<fs_data>) . <fs_data>-rank = c_xszg. "修改職級 ENDLOOP. cl_demo_output=>write( gt_data ). *4> 定義變數將000001工號去除前導0賦值給變數,并輸出 DATA(lv_id) = |{ <fs_data>-id ALPHA = OUT }|. cl_demo_output=>write( lv_id ). *5> 定義變數輸出去年的明天,并輸出(使用新語法連接字串) DATA(lv_date) = |{ sy-datum(4) - 1 }{ sy-datum+4 + 1 } |. *DATA(lv_date1) = ( sy-datum(4) - 1 ) && ( sy-datum+4 + 1 ). cl_demo_output=>write( lv_date ). *&---------------------------------------------------------------------- * 練習二:構造運算式 * 1. 值構造: VALUE - 創建一個型別為dypee的資料 * 2.1 構造結構 * 語法: ... VALUE dtype | #( [BASE dobj] comp1 = dobj1 comp2 = dobj2 ... ) ... * 2.2 構造內表 : * 語法: ... VALUE dtype | #( [BASE itab] ( (line1-com1 = dobj1) ( line2 ..) ... ) ... * note: dytpe可接具體型別或者# ,接#資料型別必須確定 * 可以嵌套使用; * 內表賦值不能帶表頭; *&---------------------------------------------------------------------* cl_demo_output=>write( '練習二:構造運算式' ). *1> 結構賦值 (id :2 name :王明 gender:男 education:專科 rank:銷售雇員)/輸出 gs_data = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/VALUE #( id = 2 name = c_name2 gender = c_gender2 education = c_education2 rank = c_rank2 ). DATA(gw_data) = VALUE ty_data( id = 2 name = c_name2 gender = c_gender2 education = c_education2 rank = c_rank2 ). cl_demo_output=>write( gs_data ). *2> 結構內附加王明薪資資訊為6000/輸出 gs_data = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/VALUE #( BASE gs_data salary = 6000 ). cl_demo_output=>write( gs_data ). *3> 結構內修改王明薪資為5000,更新至內表/輸出內表 gs_data = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/VALUE #( BASE gs_data salary = 5000 ). APPEND gs_data TO gt_data. cl_demo_output=>write( gt_data ). *4> 內表基礎上附加額外資料之后,更新TABLE:YTEST_NG *id :3 name :LISA gender:女 education:本科 rank:銷售雇員 *id :4 name :TOM gender:男 education:專科 rank:銷售雇員 gt_data = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/VALUE #( BASE gt_data ( id = 3 name = c_name3 gender = c_gender3 education = c_education3 rank = c_rank2 salary = 4300 ) ( id = 4 name = c_name4 gender = c_gender2 education = c_education2 rank = c_rank2 salary = 4400 ) ). cl_demo_output=>write( gt_data ). *4.1new>內表基礎上附加額外資料 APPEND VALUE #( id = 9 ) TO gt_data. MODIFY ytest_ng FROM TABLE gt_data. *5> 定義Range 表并賦值 id = 1 和 id>=3 DATA: r_range TYPE RANGE OF ytest_ng-id. r_range = VALUE #( sign = 'I' ( option = 'EQ' low = 1 ) ( option = 'GE' low = 3 ) sign = 'E' ( option = 'EQ' low = 2 ) ). cl_demo_output=>write( r_range ). *&---------------------------------------------------------------------- * 練習三:內表操作 * 1. 內表運算式- 相當于READ TABLE * 語法:… itab[ … ] … * note: 如果未找到對應的記錄就會拋出CX_SY_ITAB_LINE_NOT_FOUND例外,SY-SUBRC不會記錄 * 可以通過line_exists預定義函式改進 * 2. 內表預定義函式 * 2.1 line_exists( ) - 判斷記錄是否存在 * 2.2 line_index( ) - 獲取符合記錄的索引值 * 3. 內表篩選-FILTER -篩選內表中的資料 * 語法: FILTER type( itab [EXCEPT] [IN ftab] [USING KEY keyname ] * WHERE c1 op f1 [AND c2 op f2 [...] ] ) ... * note: WHERE對應過濾的條件,是必須要指定的,注意有些運算子是不能在WHERE中使用的,如:OR , NOT 等 * EXCEPT如果不指定則表示滿足條件的找出來,如果指定則表示不滿足條件的找出來 * 4. 內表縮減 * 語法: ... REDUCE type( * [let_exp] * INIT {x1 = rhs1}|{<x1> = wrexpr1}|{x1|<x1> TYPE dtype1} * {x2 = rhs2}|{<x2> = wrexpr2}|{x2|<x2> TYPE dtype2} * ... * FOR for_exp1 * FOR for_exp2 * ... * NEXT ... * {x1 = rhs1}|{<x1> = wrexpr1} * {x2 = rhs2}|{<x2> = wrexpr2} * ... ) ... *&---------------------------------------------------------------------* cl_demo_output=>write( '練習三:內表操作' ). *1> 判斷內表第3行是否存在,若存在,定義結構獲取第3行記錄/輸出,定義變數獲取第3行員工姓名/輸出 IF line_exists( gt_data[ 3 ] ). "獲取第3行記錄 TRY. DATA(ls_data) = gt_data[ 3 ]. CATCH cx_sy_itab_line_not_found. ENDTRY. "獲取第3行員工姓名 TRY. DATA(lv_name) = gt_data[ 3 ]-name. CATCH cx_sy_itab_line_not_found. ENDTRY. cl_demo_output=>write( ls_data ). cl_demo_output=>write( lv_name ). ENDIF. *1.1new>讀取內表 *data(ls_data3) = gt_data[ id = '10' ]. "若讀不到會dump,一般處理方式為try catch data(ls_data3) = VALUE #( gt_data[ id = 10 ] OPTIONAL ). "加上VALUE…OPTIONAL,如果讀不到的話,就是一個新定義的,所以為空 *1.2new>DEFAULT如果讀不到就為默認值 data(wa_def) = VALUE ty_data( id = 10 name = 'rr'). CLEAR ls_data3. ls_data3 = VALUE #( gt_data[ id = 10 ] DEFAULT wa_def ). *2> 獲取id=3,名字是1>中員工姓名的索引值,并輸出其下一行人員資訊 DATA(lv_index) = line_index( gt_data[ id = 1 name = '李華' ] ). IF lv_index NE 0 . CLEAR ls_data. TRY. ls_data = gt_data[ lv_index + 1 ]. CATCH cx_sy_itab_line_not_found. ENDTRY. cl_demo_output=>write( ls_data ). ENDIF. *3> 將gt_data用銷售主管和銷售雇員分別放到兩個內表并輸出(使用FILTER關鍵字語法) "使用多個值篩選 DATA: gt_filter TYPE SORTED TABLE OF CHAR10 WITH NON-UNIQUE KEY table_line. ***INitialize filter Table gt_filter = VALUE #( ( c_xszg ) )."可以寫多個 "找出滿足條件的資料 DATA(gt_out) = FILTER #( gt_data IN gt_filter WHERE rank = table_line ) . cl_demo_output=>write( gt_out ). "找出不滿足條件的資料 DATA(gt_out_t) = FILTER #( gt_data EXCEPT IN gt_filter WHERE rank = table_line ) . cl_demo_output=>write( gt_out_t ). *new3.1>FILTER語法-使用SORT表 TYPES: BEGIN OF ty_001, code TYPE char2, value TYPE char10, END OF ty_001. DATA :itab TYPE SORTED TABLE OF ty_001 WITH NON-UNIQUE KEY code value. DATA :itabs TYPE STANDARD TABLE OF ty_001 WITH NON-UNIQUE SORTED KEY cod COMPONENTS code value. "初始化內表,此時被FILTER表應為SORT 或 HASH表 itab = VALUE #( ( code = '01' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test01') ( code = '01' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test001') ( code = '02' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test02') ( code = '03' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test003') ( code = '02' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test021') ( code = '03' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test031') ). "直接Filter"找出滿足條件的資料 DATA(it_filter) = FILTER #( itab WHERE code = '01' ). "使用excpt 陳述句 DATA(it_exp) = FILTER #( itab EXCEPT WHERE code = '01' ). *new3.2>FILTER語法 "標準表賦值 itabs = VALUE #( ( code = '01' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test01') ( code = '01' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test001') ( code = '02' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test02') ( code = '03' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test003') ( code = '02' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test021') ( code = '03' value = https://www.cnblogs.com/ap-ad-java-abap/archive/2022/08/04/'test031') ). "直接Filter"找出滿足條件的資料 DATA(it_filters) = FILTER #( itabs USING KEY cod WHERE code = '01' ). "顯示資料 cl_demo_output=>new( )->next_section( |初始化內表| )->write( itab )->next_section( |直接Filter| )->write( it_filter )->next_section( |使用excpt 陳述句| )->write( it_exp )->next_section( |標準表賦值| )->write( itabs )->next_section( |標準表Filter| )->write( it_filters )->display( ). *----------------------------------------------------------------------* *4> a,內表行數 * b,內表中男性員工有幾位 * c,累計內表gt_data中銷售雇員工資之和 * d,定義結構將銷售雇員工資總和、最大值、平均工資、員工個數輸出 "內表行數 DATA(lv_lines) = lines( gt_data ). "內表中男性員工有幾位 -- 計數 DATA(lv_lines_nan) = REDUCE i( INIT x = 0 FOR ls_man IN gt_data WHERE ( gender = '男' ) NEXT x = x + 1 ). cl_demo_output=>write( lv_lines ). cl_demo_output=>write( lv_lines_nan ). "累計內表gt_data中銷售雇員工資之和 --簡單匯總 TYPES: ty_sal TYPE p DECIMALS 2 . DATA(lv_sum_salary) = REDUCE ty_sal( INIT sum_sal = VALUE ty_sal( ) FOR wa IN gt_data WHERE ( rank = c_rank2 ) NEXT sum_sal = sum_sal + wa-salary ). cl_demo_output=>write( lv_sum_salary ). TYPES:BEGIN OF ty_result, sum TYPE p DECIMALS 2, "總和 max TYPE p DECIMALS 2, "最大值 min TYPE p DECIMALS 2, "最小值 avg TYPE p DECIMALS 2, "平均 cunt TYPE i, "記錄數 END OF ty_result. DATA(ls_result) = REDUCE ty_result( INIT res = VALUE ty_result( min = 999999999 max = 0 ) "給一個最大值0,給一個最小值相對大的資料,然后再NEXT中比較大小 FOR <fs_data1> IN gt_data WHERE ( rank = c_rank2 ) NEXT res-sum = res-sum + <fs_data1>-salary "工資總和 res-max = nmax( val1 = res-max val2 = <fs_data1>-salary )"最高工資 res-min = nmin( val1 = res-min val2 = <fs_data1>-salary )"最di工資 res-cunt = res-cunt + 1 "幾個銷售雇員 ). ls_result-avg = ls_result-sum / ls_result-cunt. "平均工資 cl_demo_output=>write( ls_result ). *4.1>復雜匯總 -- 按照group匯總與at new ,at end ,loop group by類似 TYPES: BEGIN OF ty_002, code type char2, group type char1, quan type i, end of ty_002. DATA itab1 TYPE TABLE OF ty_002 WITH NON-UNIQUE SORTED KEY grp COMPONENTS group. itab1 = VALUE #( ( code = '1' group = 'A' quan = 1 ) ( code = '1' group = 'A' quan = 3 ) ( code = '3' group = 'A' quan = 2 ) ( code = '2' group = 'C' quan = 4 ) ( code = '2' group = 'A' quan = 5 ) ( code = '3' group = 'B' quan = 8 ) ( code = '3' group = 'A' quan = 4 ) ( code = '1' group = 'C' quan = 2 ) ). "按照group匯總 DATA itabg TYPE TABLE OF ty_002. LOOP AT itab1 INTO data(ls_itab1). DATA(ls_check) = VALUE #( itabg[ group = ls_itab1-group ] OPTIONAL ). IF ls_check is NOT INITIAL. CONTINUE. ENDIF. data(ls_itabg) = ls_itab1. CLEAR ls_itabg-code. ls_itabg-quan = REDUCE i( INIT v = 0 FOR ls IN FILTER #( itab1 USING KEY grp WHERE group = ls_itabg-group ) NEXT v = v + ls-quan ). APPEND ls_itabg TO itabg. CLEAR: ls_itabg,ls_check,ls_itab1. ENDLOOP. *4.2>復雜匯總 -- 按照code與group匯總 DATA itab2 TYPE TABLE OF ty_002 WITH NON-UNIQUE SORTED KEY cod COMPONENTS code group WITH NON-UNIQUE SORTED KEY grp COMPONENTS group. itab1 = VALUE #( ( code = '1' group = 'A' quan = 1 ) ( code = '1' group = 'A' quan = 3 ) ( code = '3' group = 'A' quan = 2 ) ( code = '2' group = 'C' quan = 4 ) ( code = '2' group = 'A' quan = 5 ) ( code = '3' group = 'B' quan = 8 ) ( code = '3' group = 'A' quan = 4 ) ( code = '1' group = 'C' quan = 2 ) ). "按照group匯總 DATA itabcg TYPE TABLE OF ty_002. LOOP AT itab1 INTO ls_itab1. ls_check = VALUE #( itabcg[ code = ls_itab1-code group = ls_itab1-group ] OPTIONAL ). IF ls_check is NOT INITIAL. CONTINUE. ENDIF. data(ls_itabcg) = ls_itab1. CLEAR ls_itabg-code. ls_itabg-quan = REDUCE i( INIT v = 0 FOR ls IN FILTER #( itab2 USING KEY cod WHERE code = ls_itabcg-code AND group = ls_itabcg-group ) NEXT v = v + ls-quan ). APPEND ls_itabcg TO itabcg. CLEAR: ls_itabcg,ls_check,ls_itab1. ENDLOOP. *&---------------------------------------------------------------------- * 練習四:OPEN SQL *&---------------------------------------------------------------------* cl_demo_output=>write( '練習四:' ). *1> 工資大于等于1000為 * ... CASE WHEN sql_cond1 THEN result1 * [WHEN sql_cond2 THEN result2] * [WHEN sql_cond3 THEN result3] * ... * [ELSE resultn] * END ... SELECT id,name,salary, CASE WHEN salary GE 10000 THEN 'A' WHEN salary GE 5000 AND salary LT 9999 THEN 'B' WHEN salary LT 5000 THEN 'C' ELSE ' ' END AS salary_1 FROM ytest_ng * GROUP BY id,name,salary INTO TABLE @DATA(gt_out_s). cl_demo_output=>write( gt_out_s ). SELECT rank, SUM( CASE WHEN education = '本科' THEN 1 ELSE 0 END ) AS sum_ben_num , "--本科人數 SUM( CASE WHEN education = '專科' THEN 1 ELSE 0 END ) AS sum_zhuan_num "--專科人數 FROM ytest_ng GROUP BY rank INTO TABLE @DATA(gt_out_e). cl_demo_output=>write( gt_out_e ). *&---------------------------------------------------------------------* *CORRESPONDING關鍵字 *關鍵字MAPPING指定不同的欄位賦值 *關鍵字EXCEPT排除某個欄位不賦值 *&---------------------------------------------------------------------* "1.作業區中相同欄位賦值,可以省去不同欄位賦值的陳述句 DATA:BEGIN OF ls_data1, fd1 TYPE char10, fd2 TYPE char10, fd3 TYPE char10, END OF ls_data1. DATA:BEGIN OF ls_data2, fd1 TYPE char10, fd2 TYPE char10, fd4 TYPE char10, END OF ls_data2. ls_data1 = VALUE #( fd1 = |First| fd2 = |Second| fd3 = |Third| ). "類似MOVE-CORRESPONDING ls_data2 = CORRESPONDING #( ls_data1 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同欄位賦值的基礎上,指定把ls_data1-fd3賦值給ls_data2-fd4 ls_data2 = CORRESPONDING #( ls_data1 MAPPING fd4 = fd3 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同欄位賦值的基礎上,排除fd2初始化 ls_data2 = CORRESPONDING #( ls_data1 EXCEPT fd2 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. SKIP. "相同欄位賦值的基礎上,指定把ls_data1-fd3賦值給ls_data2-fd4,fd2初始化 ls_data2 = CORRESPONDING #( ls_data1 MAPPING fd4 = fd3 EXCEPT fd2 ). WRITE: / |FD1:|,ls_data2-fd1,|FD2:|,ls_data2-fd2,|FD4:|,ls_data2-fd4. "2.內表相同欄位賦值,可以省去LOOP中READ資料再賦值,只需要將不同的欄位指定好 *DATA: LT_T001 TYPE STANDARD TABLE OF ACDOCA. * *SELECT * BUKRS, * BELNR, * GJAHR, * BUZEI * FROM BSEG * UP TO 3 ROWS * INTO TABLE @DATA(LT_BSEG). * *"CORRESPONDING *LT_T001 = CORRESPONDING #( LT_BSEG MAPPING RBUKRS = BUKRS * DOCLN = BUZEI ). * *3.CORRESPONDING構造RANGE表,省去回圈賦值,提高代碼速度 RANGES: lr_rank FOR ytest_ng-rank. lr_rank[] = CORRESPONDING #( gt_data[] MAPPING low = rank EXCEPT * ). SORT lr_rank BY LOW. DELETE ADJACENT DUPLICATES FROM lr_rank COMPARING LOW. DELETE lr_rank WHERE low is INITIAL. lr_rank-sign = 'I'. lr_rank-option = 'EQ'. MODIFY lr_rank TRANSPORTING sign option WHERE low IS NOT INITIAL. SELECT * from ytest_ng INTO TABLE gt_data WHERE rank in lr_rank. *LCL_ALV->DISPLAY( ). BREAK-POINT. *--------------------------------------------------------------------* *COND SWITCH 運算子 *在新語法中,可以使用COND、SWITCH來根據邏輯運算式或情況的不同確定指定變數的結果, *COND SWITCH可以理解為IF CASE的替代語法,提高了代碼可讀性、簡潔性 *--------------------------------------------------------------------* DATA(time) = COND string( WHEN sy-timlo < '120000' THEN |{ sy-timlo TIME = ISO } AM| WHEN sy-timlo > '120000' THEN |{ CONV t( sy-timlo - 12 * 3600 ) TIME = ISO } PM| WHEN sy-timlo = '120000' THEN |High noon| * ELSE ). WRITE: time. DATA: LV_STRING TYPE STRING VALUE 's'. "舊 IF LV_STRING is INITIAL. LV_STRING = ' inittial'. ELSEIF LV_STRING = 'K'. LV_STRING = 'is k'. *ELSE. ENDIF. LV_STRING = COND #( WHEN LV_STRING IS INITIAL THEN ' inittial' WHEN LV_STRING = 'K' THEN 'is k' ELSE LV_STRING "如果前面條件均不滿足,一定要回寫LV_STRING值,否則LV_STRING值將被回寫的空值覆寫 ). WRITE: LV_STRING. *WHNE后面只能跟變數,類似 CASE 變數 when不同的值 DATA(a) = 11. DATA(text) = SWITCH #( a WHEN '11' THEN '11yyagd' WHEN '12' THEN '12dkdkkd' * ELSE ). WRITE: text. DATA: LV_STRING1 TYPE STRING VALUE 's'. lv_string1 = switch #( lv_string1 "如果非a b c,lv_string將被回傳的空值覆寫; WHEN 'a' THEN 'is a' WHEN 'b' THEN 'is b' WHEN 'c' THEN 'is c' ). WRITE: LV_STRING. TYPES: BEGIN OF result, operand TYPE string, result TYPE string, fdpos TYPE sy-fdpos, END OF result. DATA results TYPE STANDARD TABLE OF result WITH EMPTY KEY. DATA: f1 TYPE c LENGTH 5 VALUE 'BD ', f2 TYPE c LENGTH 5 VALUE 'ABCDE'. cl_demo_input=>new( )->add_field( CHANGING field = f1 )->add_field( CHANGING field = f2 )->request( ). results = VALUE #( BASE results ( operand = 'CO' result = COND #( WHEN f1 CO f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CN' result = COND #( WHEN f1 CN f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CA' result = COND #( WHEN f1 CA f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NA' result = COND #( WHEN f1 NA f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CS' result = COND #( WHEN f1 CS f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NS' result = COND #( WHEN f1 NS f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'CP' result = COND #( WHEN f1 CP f2 THEN abap_true ) fdpos = sy-fdpos ) ). results = VALUE #( BASE results ( operand = 'NP' result = COND #( WHEN f1 NP f2 THEN abap_true ) fdpos = sy-fdpos ) ). cl_demo_output=>new( )->write( |'{ f1 WIDTH = 5 }' operand '{ f2 WIDTH = 5 }'| )->display( results ). *用于BAPI輸出訊息時,可用于拼接于一行顯示的訊息回傳結果中 * CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST' * EXPORTING * DOCUMENTHEADER = LS_DOCUMENTHEADER * IMPORTING ** OBJ_TYPE = * OBJ_KEY = LV_KEY ** OBJ_SYS = * TABLES * ACCOUNTGL = LT_ACCOUNTGL * ACCOUNTRECEIVABLE = LT_ACCOUNTRECEIVABLE ** ACCOUNTPAYABLE = LT_ACCOUNTPAYABLE * CURRENCYAMOUNT = LT_CURRENCYAMOUNT * EXTENSION2 = LT_EXTENSION2 * RETURN = LT_RETURN. * * LOOP AT LT_RETURN INTO DATA(LS_RETURN) WHERE TYPE CA 'AEX'. * LS_OUT-MESSAGE = * COND #( WHEN LS_OUT-MESSAGE = SPACE THEN LS_RETURN-MESSAGE * ELSE |{ LS_OUT-MESSAGE }/{ LS_RETURN-MESSAGE }| ). * ENDLOOP. *--------------------------------------------------------------------* *LOOP……GROUP BY *--------------------------------------------------------------------* DATA BEGIN OF gs_data1. DATA: sss TYPE CHAR1, char TYPE char1, num TYPE i , end of gs_data1. DATA: gt_data1 LIKE TABLE OF gs_data1. DATA LV_COUNT TYPE I. *內部追加賦值 gt_data1 = VALUE #( base gt_data1 ( sss = '1' char = 'A' ) ( sss = '1' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '3' char = 'A' ) ( sss = '4' char = 'C' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '2' char = 'A' ) ( sss = '3' char = 'B' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ( sss = '5' char = 'A' ) ). *--------------------------------------------------------* "按照相同sss,char的分組排序編號給num欄位賦值 *--------------------------------------------------------* SORT gt_data1 by sss char. LOOP AT gt_data1 INTO gs_data1 GROUP BY ( sss = gs_data1-sss "回圈時gs_data沒有資料,資料通過分組到<L_MEMBER>,如果給gt_data賦值,也是用<L_MEMBER>,指標不用MODIFY char = gs_data1-char size = GROUP SIZE "size是本組條目數量 index = GROUP INDEX ) "INDEX組索引 ASCENDING ASSIGNING FIELD-SYMBOL(<l_group>). "雙擊可以看到,size,index以及按條件分組的條件欄位值 CLear lv_count. LOOP AT GROUP <l_group> ASSIGNING FIELD-SYMBOL(<l_member>). lv_count = lv_count + 1. <l_member>-num = lv_count. ENDLOOP. ENDLOOP. BREAK-POINT. *--------------------------------------------------------* "按照相同sss,char為一組,累加資料欄位,并合并重復項 *--------------------------------------------------------* DATA :gt_data_temp LIKE gt_data1, gs_data_temp LIKE gs_data1. SORT gt_data1 by sss char. LOOP AT gt_data1 INTO gs_data1 GROUP BY ( sss = gs_data1-sss char = gs_data1-char size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING <l_group>. CLear lv_count. LOOP AT GROUP <l_group> ASSIGNING <l_member>. lv_count = <l_member>-num + lv_count. gs_data_temp = <l_member>. ENDLOOP. gs_data_temp-num = lv_count. APPEND gs_data_temp to gt_data_temp. CLEAR gs_data_temp. ENDLOOP. BREAK-POINT. DATA lv_netwr TYPE vbak-netwr. DATA: BEGIN OF lt_vbak_temp OCCURS 0, vkgrp LIKE vbak-vkgrp, vkbur LIKE vbak-vkbur, netwr LIKE vbak-netwr, waerk LIKE vbak-waerk, END OF lt_vbak_temp. *DATA lt_vbak_temp TYPE TABLE OF vbak WITH HEADER LINE. SELECT * FROM vbak INTO TABLE @DATA(lt_vbak) UP TO 100 ROWS. SORT lt_vbak BY vkgrp vkbur. LOOP AT lt_vbak INTO DATA(ls_vbak) GROUP BY ( vkgrp = ls_vbak-vkgrp vkbur = ls_vbak-vkbur waerk = ls_vbak-waerk size = GROUP SIZE index = GROUP INDEX ) ASCENDING ASSIGNING FIELD-SYMBOL(<group>). LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<member>). TRY. ADD <member>-netwr TO lv_netwr. CATCH cx_sy_arithmetic_error. ENDTRY. MOVE-CORRESPONDING <member> TO lt_vbak_temp. ENDLOOP. lt_vbak_temp-netwr = lv_netwr. APPEND lt_vbak_temp. CLEAR: lt_vbak_temp,lv_netwr,ls_vbak. ENDLOOP. cl_demo_output=>write( lt_vbak_temp[] ). cl_demo_output=>display( ). *&---------------------------------------------------------------------* *& Report YTEST_NEW_GRAMMAR_AN2 *&---------------------------------------------------------------------* *&SAP SQL雜項函式 *select 與 case結合使用最大的好處有兩點,一是在顯示查詢結果時可以靈活 *的組織格式,二是有效避免了多次對同一個表或幾個表的訪問 *&---------------------------------------------------------------------* REPORT ytest_new_grammar_an2. *連接字串的兩種寫法 DATA(lv_date1) = sy-datum && sy-uzeit. DATA(lv_date2) = |{ sy-datum(4) - 1 }{ sy-datum+4 + 1 }|. *cl_demo_output=>write( lv_date1 ). *cl_demo_output=>write( lv_date2 ). SELECT COUNT( DISTINCT carrid ) FROM spfli WHERE cityto = 'NEW YORK' INTO @DATA(count). *cl_demo_output=>write( count ). SELECT * FROM scustom USING CLIENT '100' INTO TABLE @DATA(lt_customers). *cl_demo_output=>write( lt_customers ). *1. ... CASE operand * WHEN operand1 THEN result1 * [WHEN operand2 THEN result2] * ... * [ELSE resultn] * END ... DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'x' char1 = 'aaaaa' char2 = 'bbbbb' ) ( id = 'y' char1 = 'xxxxx' char2 = 'yyyyy' ) ( id = 'z' char1 = 'mmmmm' char2 = 'nnnnn' ) ) ) ACCEPTING DUPLICATE KEYS. DATA(else) = 'fffff'. SELECT id, char1, char2, CASE char1 WHEN 'aaaaa' THEN concat( char1 , char2 ) WHEN 'xxxxx' THEN substring( char1,1,2 ) ELSE @else END AS text FROM demo_expressions INTO TABLE @DATA(lt_results1). *cl_demo_output=>write( lt_results1 ). "實際應用 SELECT c~bukrs, b~werks, a~budat, b~matnr, h~maktx, e~waers, c~lifnr, g~name1, g~land1, i~aplfz, b~meins, CASE b~kzabs WHEN 'X' THEN 'VMI' ELSE ' ' END AS kzabs1, CASE substring( c~zterm,1,1 ) WHEN 'B' THEN 'BWT' ELSE ' ' END AS zterm1, SUM( CASE a~shkzg WHEN 'S' THEN ( a~dmbtr ) WHEN 'H' THEN ( a~dmbtr * -1 ) END ) AS dmbtr1, SUM( CASE a~shkzg WHEN 'S' THEN ( b~menge ) WHEN 'H' THEN ( b~menge * -1 ) END ) AS menge, CASE e~waers WHEN 'KRW' THEN 100 WHEN 'JPY' THEN 100 WHEN 'VND' THEN 100 ELSE 1 END AS factor FROM ekbe AS a INNER JOIN ekpo AS b ON b~ebeln = a~ebeln AND b~ebelp = a~ebelp INNER JOIN ekko AS c ON c~ebeln = a~ebeln INNER JOIN t001k AS f ON f~bwkey = b~werks INNER JOIN t001 AS e ON e~bukrs = f~bukrs INNER JOIN lfa1 AS g ON g~lifnr = c~lifnr INNER JOIN makt AS h ON h~matnr = a~matnr INNER JOIN zm094v AS i ON i~lifnr = g~lifnr AND i~matnr = a~matnr AND i~werks = a~werks WHERE h~spras = 'E' AND b~mtart = 'ROH' GROUP BY c~bukrs, b~werks, a~budat, b~matnr, h~maktx, e~waers, c~lifnr, g~name1, g~land1, i~aplfz, b~meins, b~kzabs, c~zterm INTO TABLE @DATA(gt_vmi). *cl_demo_output=>write( gt_vmi ). *--------------------------------------------------------------------* *2. ... CASE WHEN sql_cond1 THEN result1 * [WHEN sql_cond2 THEN result2] * [WHEN sql_cond3 THEN result3] * ... * [ELSE resultn] * END ... *CASE WHEN可以用大于,小于,SUBSTRING,CONCAT,LIKE,BETWEEN,不能用IN ,EXISTS,等條件 DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'w' char1 = 'vvvvv' char2 = 'wwwww' dec1 = 1018 dec2 = '11.11') ( id = 'x' char1 = 'aaa77' char2 = 'bbbbb' dec1 = 1018 ) ( id = 'y' char1 = 'xxxxx' char2 = 'yyyyy' dec1 = 1118 ) ( id = 'z' char1 = 'mmmmm' char2 = 'nnnnn' dec1 = -1218 ) ( id = 'm' char1 = 'mmmmm' char2 = 'nnnnn' dec1 = 1318 dec2 = '12.12') ) ) ACCEPTING DUPLICATE KEYS. SELECT id , CASE WHEN char1 LIKE '%a77' "LIKE THEN ( char1 && char2 ) ELSE ( char2 && char1 ) END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77). *cl_demo_output=>write( lt_a77 ). SELECT id , CASE WHEN substring( char1,3,3 ) = 'a77' "SUBSTRING THEN ( char1 && char2 ) ELSE concat( char2 ,char1 ) "CONCAT END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77_sub). *cl_demo_output=>write( lt_a77_sub ). SELECT id , * case when ( char1 && '%' ) = 'aaa77%' CASE WHEN concat( char1 , '%' ) = 'aaa77%' THEN ( char1 && char2 ) ELSE concat( char2 , char1 ) END AS text FROM demo_expressions INTO TABLE @DATA(lt_a77_con). *cl_demo_output=>write( lt_a77_con ). SELECT id,ceil( dec2 ) AS dec2_ceil,floor( dec2 ) AS dec2_floor, CASE WHEN dec1 BETWEEN 1101 AND 1130 "ONLY Numerical type THEN 'BETWEEN' WHEN abs( dec1 ) = 1218 THEN 'ABS' ELSE 'others' END AS text_dec1, CASE WHEN ceil( dec2 ) = 12 THEN 'CEIL' WHEN floor( dec2 ) = 12 THEN 'FLOOR' ELSE 'OTHERS' END AS text_dec2 FROM demo_expressions INTO TABLE @DATA(lt_dec). *cl_demo_output=>write( lt_dec ). *--------------------------------------------------------------------* GET TIME STAMP FIELD DATA(gv_timestamp). DELETE FROM demo_expressions. INSERT demo_expressions FROM @( VALUE #( id = 'X' timestamp1 = gv_timestamp ) ). *--------------------------------------------------------------------* "CAST資料轉換函式& div|mod|*|/|substring|concat等嵌套使用 *--------------------------------------------------------------------* SELECT SINGLE FROM demo_expressions FIELDS CAST( CAST( div( timestamp1 , 1000000 ) AS CHAR ) AS DATS ) AS date, CAST( substring( CAST( timestamp1 AS CHAR ), 9, 6 ) AS TIMS ) AS time INTO @DATA(ls_expressions). *cl_demo_output=>write( ls_expressions ). *--------------------------------------------------------------------* "fields與SINGLE的區別 & 日期型別與char型別顯示的不同 *--------------------------------------------------------------------* SELECT SINGLE CAST( div( timestamp1 , 1000000 ) AS CHAR ) AS date, CAST( substring( CAST( timestamp1 AS CHAR ), 9, 6 ) AS TIMS ) AS time FROM demo_expressions INTO @DATA(ls_expressions1). *cl_demo_output=>write( ls_expressions1 ). DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'X' num1 = 111 ) ( id = 'Y' num1 = 222 ) ( id = 'Z' num1 = 333 ) ) ). *--------------------------------------------------------------------* "WHERE 中等號左右兩邊都可以使用CAST,SUBSTRING,CONCAT,*,+,-等 *--------------------------------------------------------------------* *SELECT FROM demo_expressions * FIELDS id, num1 * WHERE CAST( num1 AS CHAR ) LIKE '2%' * INTO TABLE @DATA(result). select t1~matnr, werks, charg, cuobj from mchb as t1 left outer join inob as t2 on substring( t2~objek , 1, 18 ) = t1~matnr "1-18位 是物料號 and substring( t2~objek, 41,10 ) = t1~charg "41~50位 是批次 where t2~klart = '023' into table @data(lt_mchb). SELECT * FROM bkpf "AS t1 WHERE substring( awkey , 1, 10 ) = '1' AND substring( awkey , 11, 4 ) = 1 INTO TABLE @data(gt_outt) . SELECT * FROM bkpf "AS t1 WHERE awkey = '___5555_' "假設共8位,想取4-7位資料為5555的 AND substring( awkey , 1, 4 ) = 1 INTO TABLE @data(gt_outtt) . "SELECT…聚合函式&CAST SELECT carrid, SUM( CAST( price AS DEC( 20,2 ) ) ) AS price1 FROM ysflight_oolav_1 WHERE carrid = 'JL' GROUP BY carrid INTO TABLE @DATA(lt_ysflight_oolav_1). *cl_demo_output=>write( lt_ysflight_oolav_1 ). *--------------------------------------------------------------------* *case…when& concat& substring& cast嵌套使用 *CAST,SUBSTRING,CONCAT,*,+,-等也可以在CASE WHEN,THEN,WHERE關鍵字等號左右兩邊均可使用, * CASE WHEN中小數怎么處理,可以給左邊取數乘以10 *CAST也可用于同型別修改長度 *--------------------------------------------------------------------* "Get Goal GET TIME STAMP FIELD data(lv_start_time)."獲取當前系統的時間戳 SELECT a~zcustg, b~name, a~goal_rate AS goal_deci, a~gjahr, " goal_rate = 0 CASE WHEN a~goal_rate = 0 THEN ' ' "goal_rate >=1 WHEN a~goal_rate >= 1 THEN concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,3 ), '%' ) "0 < goal_rate < 0.1 WHEN ( a~goal_rate * 10 ) < 1 AND a~goal_rate > 0 THEN concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,1 ), '%' ) "0.1 <= goal_rate < 1 ELSE concat( substring( CAST( ( a~goal_rate * 100 ) AS CHAR ), 1,2 ), '%' ) END AS goal FROM zsa6202 AS a INNER JOIN zsa6001 AS b ON a~zcustg = b~zcustg ORDER BY a~zcustg, b~name INTO TABLE @DATA(lt_data) . GET TIME STAMP FIELD data(lv_end_time). DATA(lv_rfc_time) = lv_end_time - lv_start_time. " GET TIME STAMP FIELD data(lv_start_time1)."獲取當前系統的時間戳 SELECT a~zcustg, b~name, a~goal_rate AS goal_deci, a~gjahr, a~goal_rate FROM zsa6202 AS a INNER JOIN zsa6001 AS b ON a~zcustg = b~zcustg ORDER BY a~zcustg, b~name INTO TABLE @DATA(lt_data1) . GET TIME STAMP FIELD data(lv_end_time1). DATA(lv_rfc_time1) = lv_end_time1 - lv_start_time1. " *cl_demo_output=>write( lt_data ). cl_demo_output=>write( lv_rfc_time ). cl_demo_output=>write( lv_rfc_time1 ). *--------------------------------------------------------------------* *除了CAST、CONCAT之外,ROUND, LPAD, LENGTH, REPLACE, RIGHT, RTRIM,SUBSTRING *等函式也可以使用,雜項函式COALESCE 也可以使用,但是最多255個運算式 *--------------------------------------------------------------------* "LPAD可用于補0,或者補任何字符 SELECT CONCAT( CONCAT( carrid, LPAD( carrname,30,' ' ) ), LPAD( url,40,' ' ) ) AS line FROM scarr INTO TABLE @DATA(result1). cl_demo_output=>write( result1 ). DELETE FROM demo_expressions. INSERT demo_expressions FROM TABLE @( VALUE #( ( id = 'X' char1 = ' 0123' char2 = ' 4567' ) ) ). SELECT SINGLE char1 AS text1, char2 AS text2, CONCAT( char1,char2 ) AS concat, LENGTH( char1 ) AS length, "字串長度,包含空格長度 "從左邊去除字串的所有空格,類似SHIFT <l_tbtco>-periode LEFT DELETING LEADING '0'.不止為0,可以為其他字符 LTRIM( char1,' ' ) AS ltrim, LPAD( char1,10,'0' ) AS LPAD, "補0,或者補任何其他字符至10位 REPLACE( char1,'12','__' ) AS replace, "替換 RIGHT( char1,3 ) as right, "從右邊截取,且包含空格 RTRIM( char1,'3' ) AS rtrim, ""該函式功能是在arg的右邊查找char字符,如果找到,則去掉; SUBSTRING( char1,3,3 ) AS substring FROM demo_expressions INTO @DATA(result2). cl_demo_output=>write( result2 ). *--------------------------------------------------------------------* *REPLACE *RIGHT( arg, len ) 從右往左截取固定長度 *RTRIM( arg, char ) 該函式功能是在arg的右邊查找char字符,如果找到,則去掉; *COALESCE( sql_exp1, sql_exp2, ..., sql_expn ) 凝聚函式,該函式的功能是將引數中的第一個不為空的引數回傳來 *可以用于不同的表取值 *--------------------------------------------------------------------* SELECT matnr, replace( vpsta,'VE','HU' ) AS str, vpsta, ernam FROM mara WHERE vpsta LIKE 'KCV%' INTO TABLE @DATA(gt_out) UP TO 10 ROWS. SELECT matnr, right( matkl,3 ) AS str, matkl FROM mara WHERE vpsta LIKE 'KCV%' INTO TABLE @DATA(gt_out1) UP TO 10 ROWS. *其實該語法也可以用于inner join,從而可以解決在inner join時欄位長度不一致的問題 SELECT a~* FROM vbrp AS a INNER JOIN ekpo AS b ON a~aubel = b~ebeln AND right( a~aupos,5 ) = b~ebelp WHERE b~ebeln <> '' INTO TABLE @DATA(gt_out2). *該函式的功能是將引數中的第一個不為空的引數回傳來,或者是將引數中第一個成立的運算式的值回傳到別名 *比如請假,先找cell長審批,再找part長,再找group長,再找team長,也可以innerjoin等 SELECT FROM mara FIELDS matnr, coalesce( CASE vpsta WHEN 'KDG' THEN 'HUJIE' END, CASE vpsta WHEN 'KDA' THEN 'LAIMIN' ELSE 'DUODUO' END ) AS str, vpsta WHERE vpsta LIKE 'KD%' INTO TABLE @DATA(lt_out) UP TO 10 ROWS. SELECT LFA1~LIFNR, COALESCE( EKKO~LIFNR, EKKO~EBELN, '無采購訂單' ) as vendor FROM LFA1 INNER JOIN EKKO ON LFA1~LIFNR = EKKO~LIFNR INTO TABLE @DATA(LT_OUT1). cl_demo_output=>display( ).
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/500911.html
標籤:其他
