MODULE POOL에 서브스크린으로 조회조건을 만들어 놓았는데

막상 검색하려고 하면 USER-COMMAND를 제대로 타지 않아서 계속 CLEAR되는 현상이 발생하게 되었다.

전에도 이런일이 있었는데 까먹을 까봐 올려놈



아래 PAI에 구문 하나 추가 해주면 해결



'SAP Program > ABAP' 카테고리의 다른 글

Maint view T-code 없이 Call 하기  (0) 2017.03.30
Select-options => Sql where 로 변환  (0) 2017.03.28
Internal Table Group By  (0) 2017.03.28
Global Macro  (0) 2017.03.22
SAP Technical Dictionary  (0) 2017.03.22

설정

트랙백

댓글

Internal table의 collect 또는 At-New 등의 기능을 대신 사용하면 좋을것 같음.
잘 사용하면 performance 에 좋을것 같음.



You know the GROUP BY clause from SQL. There was not such a clause for internal tables up to now. 

All we had was that clumsy group level processing with statements AT NEW … that relied on the order of table columns and contents that is sorted respectively.

With release 7.40, SP08 there is a real GROUP BY clause for LOOP AT itab that is much more powerful than the SQL one.


DATA flights TYPE TABLE OF spfli WITH EMPTY KEY.

SELECT * FROM  spfli
         WHERE carrid = ‘…’
         INTO TABLE @flights.

DATA members LIKE flights.
LOOP AT flights INTO DATA(flight)
     GROUP BY ( carrier = flight-carrid cityfr = flight-cityfrom )
              ASCENDING
              ASSIGNING FIELD-SYMBOL(<group>).
  CLEAR members.
  LOOP AT GROUP <group> ASSIGNING FIELD-SYMBOL(<flight>).
    members = VALUE #( BASE members ( <flight> ) ).
  ENDLOOP.
  cl_demo_output=>write( members ).
ENDLOOP.
cl_demo_output=>display( ).


Looks like dreaded nested LOOPs, but it isn’t quite that – no quadratic behavior!  What happens here is that the first LOOP statement is executed over all internal table lines in one go and the new GROUP BY addition groups the lines. Technically, the lines are bound internally  to a group that belongs to a group key that is specified behind GROUP BY.The group key is calculated for each loop pass. And the best is, it need not be as simple as using only column values, but you can use any expressions here that normally depend on the contents of the current line, e.g. comparisons, method calls, …. The LOOP body is not evaluated in this phase!


Only after the grouping phase, the LOOP body is evaluated. Now a second (but not nested) loop is carried out over the groups constructed in the first phase. Inside this group loop you can access the group using e.g. the field symbol <group> that is assigned to the group in the above example. If you want to access the members of the group, you can us the new LOOP AT GROUP statement, which enables a member loop within the group loop. In the example, the members are inserted into a membertable and displayed.

Here another example, where the group key is evaluated from method calls:


LOOP AT flights INTO DATA(wa)

     GROUP BY ( tz_from = get_time_zone( wa-airpfrom )

                tz_to   = get_time_zone( wa-airpto ) )

     ASSIGNING FIELD-SYMBOL(<group>).

  …

ENDLOOP.


Of course, there is also expression enabled syntax for grouping internal tables.

In a first step, we get rid of LOOP AT GROUP by replacing it with a FOR expression:


DATA members LIKE flights.

LOOP AT flights INTO DATA(flight)

     GROUP BY ( carrier = flight-carrid cityfr = flight-cityfrom )

              ASCENDING

              ASSIGNING FIELD-SYMBOL(<group>).

  members = VALUE #( FOR m IN GROUP <group> ( m ) ).

  cl_demo_output=>write( members ).

ENDLOOP.

cl_demo_output=>display( ).


The IN GROUP is a new addition to FOR. Second, away with the outer LOOP:


TYPES t_flights LIKE flights.

DATA out TYPE REF TO if_demo_output.

out = REDUCE #( INIT o = cl_demo_output=>new( )

                FOR GROUPS <group> OF flight IN flights

                GROUP BY ( carrier = flight-carrid cityfr = flight-cityfrom )

                  ASCENDING

                LET members = VALUE t_flights( FOR m IN GROUP <group> ( m ) ) IN

                NEXT o = o->write( members ) ).

out->display( ).


FOR GROUPS is another new FOR variant. Believe me, it does the same as the variants above. But for reasons of readability, the combination of LOOP AT GROUP with a FOR IN GROUP within might be the preferable one, at least for this example 😈 .

For a deep dive, read this and this!

PS: If you are confused what kind of loops and nesting takes place, have a look at my comment below.

PPS: For a step-by-step approach to GROUP BY see GROUP BY for Internal Tables – Step by Step


2. https://blogs.sap.com/2016/06/23/group-by-for-internal-tables-step-by-stepc/

In my blog  ABAP News for 7.40, SP08 – GROUP BY for Interna… | SCN I introduced the GROUP BYaddition for LOOP AT for internal tables.


Since there seems to be some confusion about the syntax and its meaning, let us approach the grouping of internal tables step by step using a very simple case and you will see that it isn’t that complicated at all. 

I also attached the full text of a program, that executes the following steps and produces some output.

Say, you have an internal table spfli_tab TYPE TABLE OF spfli  filled with data from database table SPFLI (what else …).

Step 1, Grouping by one column

The most simple thing you can do is grouping by one column:

LOOP AT spfli_tab INTO wa

                  GROUP BY wacarrid.

       … wacarrid ...

ENDLOOP.


Inside the loop you can access wa, especially wa-carridwa contains the first line of each group that is created by GROUP BY. This is called representative binding. Inside the loop wa represents a group.


In order to access the members of each group, you add a member loop:


LOOP AT spfli_tab INTO wa

                  GROUP BY wa-carrid.

  …

  LOOP AT GROUP wa INTO DATA(member).

    … member-… …

  ENDLOOP.

  …

ENDLOOP.


member is a structure with the line type of spfli_tab and contains the members of each group.


Step 2, Grouping by more than one column


If you want to group by more than one grouping criterion (columns in the most simple case), you write:


LOOP AT spfli_tab INTO wa

                  GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom ).

  … wa-carrid … wa-airpfrom …

ENDLOOP.


In this case, you construct a structured group key. In the case of representative binding shown here, wa is reused for accessing the group key inside the loop.


In order to access the members of the groups, you can add exactly the same member loop as in step 1 above.


Step 3, Group key binding for grouping by one column


Besides the representative binding, where the INTO-clause of LOOP AT is reused for accessing the group, you can define a group key binding:


LOOP AT spfli_tab INTO wa

                  GROUP BY wa-carrid

                  INTO DATA(key).

  … key …

ENDLOOP.


Not too different from step 1 above, eh? Instead of reusing wa, you use an elementary data object key that for convenience is declared inline here. Group key binding offers some more functionality compared to representative binding (additions WITHOUT MEMBERSGROUP SIZEGROUP INDEX). If you don’t need those, you can stay with representative binding. Nevertheless, I myself always prefer group key binding, since it makes the group key more explicit. But that’s a question of taste.


Inserting the member loop works as before:


LOOP AT spfli_tab INTO wa

                  GROUP BY WA-CARRID

                  INTO DATA(key).

  …

  LOOP AT GROUP key INTO member.

    … members …

  ENDLOOP.

  …

ENDLOOP.


Note, that you access the group using the name key now.


Step 4, Group key binding for grouping by more than one column


Last but not least, group key binding for structured group keys:


LOOP AT spfli_tab INTO wa

                  GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom )

                  INTO DATA(key).

  … key-key1 … key-key2 …

ENDLOOP.


Now, key is a structure with the components key1 and key2. The member loop can be added exactly as in step 3.


If you aren’t interested in the members, you can use the NO MEMBERS addition in order to save some run time and some memory. E.g.


LOOP AT spfli_tab INTO wa

                  GROUP BY ( key1 = wa-carrid key2 = wa-airpfrom

                             index = GROUP INDEX size = GROUP SIZE )

                  WITHOUT MEMBERS

                  INTO DATA(key).

  … key-key1 … key-key2 … key-index … key-size … 

ENDLOOP.


A member loop is not possible here. But key is enriched with some predefiined optional components for additional informations. 


Conclusion


Not too complicated, or?


Having understood these simple facts, you can go on, read the documentation, and do more complicated things, e.g. exploiting the fact that you can use expressions for the RHS of the group key definitions or using FOR expressions instead of LOOP AT.


설정

트랙백

댓글

Global Macro

SAP Program/ABAP 2017. 3. 22. 17:06

종종 프로그램에 break-point를 소스로 처리할 때

BREAK USER_ID.

구문을 쓴다.


이 구문은 사실 ABAP 언어의 문법이 아니라 Global MACRO이다
SAP TABLE : TRMAC 에서 BREAK 로 조회 하면



DATA로 보인다.


이처럼 GLOBAL MACRO는 모든 프로그램에 영향을 미친다.
위와 같은 방법으로 테이블에 업데이트 하면 GLOBAL MACRO를 쓸수 있다.
단 이관이나 다른 문제가 있으니 신중히 써야 된다. (데이터이므로 운영 서버에 데이터를 넣어야 한다.)

설정

트랙백

댓글


DD01L            Domains

DD01T            R/3 DD: domain texts

DD07L            Domain Item Value

DD07T            Domain Item Text

DD02L             SAP Tables

DD02T             R/3 DD: SAP table texts

DD03L             Table Fields

DD03T             DD: Texts for fields (language dependent)

DD04L            Data element

DD04T            R/3 DD: Data element texts

DD05S             Foreign key fields

DD06L             Pool/cluster structures

DD08L             R/3 DD: relationship definitions

DD09L             DD: Technical settings of tables

DD12L             R/3 S_SECINDEX: secondary indexes, header;

DD17S             R/3 S_SECINDEX: secondary indexes, fields

DD30L             Search helps

DD30T             Search help texts

E070               Change & Transport System: Header of Reque

E071               Change & Transport System: Object Entries

ECLOG_HEAD    Table for Log Header

FUPARAREF      Parameters of function modules

LTDX               ALV Layout Variant

LXE_ATTOB       Attributes of Translation Objects

LXE_LOG          SE63 Translation Log

NRIV               Number Range Table

SMEN_BUFFC    Table for Storing Favorites

STXFADM         Smart Forms: Administration

STXH              STXD SAPscript text file header - Long Text Header

STXL              STXD SAPscript text file lines - Long Text Line data

TADIR             프로그램 Attribute

TDEVC             Package

TFDIR             Function Module

TRDIR             프로그램 리스트

TRDIRT           프로그램 이름

TRMAC           Macros in ABAP/4 programs

TSTC              Transaction

TSTCT             Transaction Description


SPROXHDR_TADIR_V  proxy Generated Table for View

SPROXDAT               Proxy Metadata (Substitution Table)


SEOCLASS            Class/Interface

SEOCOMPO            Class/Interface component

ENHOBJ                Enhancement Objects

SEOCOMPODF        Definition class/interface component

TBTCO            Job Status Overview Table

TBTCP            Background Job Step Overview



'SAP Program > ABAP' 카테고리의 다른 글

Internal Table Group By  (0) 2017.03.28
Global Macro  (0) 2017.03.22
Select screen의 extensiom 버튼 기능 제한하기  (0) 2017.03.22
GM_CODE - BAPI_GOODSMVT_CREATE  (0) 2017.03.16
Search Help 를 parameter setting 해서 사용하는 방법  (0) 2017.03.15

설정

트랙백

댓글

Selection Screen에서 필드 자체를 disable 시키지 않고

해당 필드 extension의 특정 기능만 disable 시키고자 할때 사용하는 coding.


* equal 과 between 기능만 활성화 시킴.


DATArestrict TYPE sscr_restrict.
* Auxiliary objects for filling RESTRICT
DATAoptlist TYPE sscr_opt_list,
      ass     TYPE sscr_ass.



FORM restrict_sel_field .


  CHECK restrict-opt_list_tab[] IS INITIAL.

  optlist-name       'OBJECTKEY1'.
  optlist-options-eq 'X'.
  optlist-options-bt 'X'.
  APPEND optlist TO restrict-opt_list_tab.    CLEARoptlist.

   ass-kind    'S'.      "A(ll), B(lock), S(elect-Option)

  ass-name    'S_MATNR'.
  ass-sg_main 'I'.      " (only) I, SPACE = both
  ass-sg_addy space.
  ass-op_main 'OBJECTKEY1'.
  APPEND ass TO restrict-ass_tab.    CLEARass.


* 다른 select-option도 추가로 한번에 setting 가능함.

* 추가로 작업하고자 하는 필드를 계속 붙여주면 한꺼번에 여러개 필드 작업이 가능함.


*
*  optlist-name       = 'OBJECTKEY2'.
*  optlist-options-eq = 'X'.       optlist-options-bt = 'X'.
*  APPEND optlist TO restrict-opt_list_tab.    CLEAR: optlist.

*  ass-kind    = 'S'.
*  ass-name    = 'S_MATNR'.
*  ass-sg_main = 'I'.
*  ass-sg_addy = space.
*  ass-op_main = 'OBJECTKEY2'.
*  APPEND ass TO restrict-ass_tab.    CLEAR: ass.
*/

*  optlist-name       = 'OBJECTKEY3'.
*  optlist-options-eq = 'X'.
*  APPEND optlist TO restrict-opt_list_tab.    CLEAR: optlist.
*
*  ass-kind    = 'S'.
*  ass-name    = 'S_MATNR'.
*  ass-sg_main = 'I'.
*  ass-sg_addy = space.
*  ass-op_main = 'OBJECTKEY3'.
*  APPEND ass TO restrict-ass_tab.    CLEAR: ass.
**/
*  optlist-name       = 'OBJECTKEY4'.
*  optlist-options-eq = 'X'.
*  APPEND optlist TO restrict-opt_list_tab.    CLEAR: optlist.
*
*  ass-kind    = 'S'.
*  ass-name    = 'S_BWART'.
*  ass-sg_main = 'I'.
*  ass-sg_addy = space.
*  ass-op_main = 'OBJECTKEY4'.
*  APPEND ass TO restrict-ass_tab.    CLEAR: ass. 

  CALL FUNCTION 'SELECT_OPTIONS_RESTRICT'
    EXPORTING
      restriction            restrict
    EXCEPTIONS
      too_late               1
      repeated               2
      selopt_without_options 3
      selopt_without_signs   4
      invalid_sign           5
      empty_option_list      6
      invalid_kind           7
      repeated_kind_a        8
      OTHERS                 9.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
             WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.

'SAP Program > ABAP' 카테고리의 다른 글

Global Macro  (0) 2017.03.22
SAP Technical Dictionary  (0) 2017.03.22
GM_CODE - BAPI_GOODSMVT_CREATE  (0) 2017.03.16
Search Help 를 parameter setting 해서 사용하는 방법  (0) 2017.03.15
New Open Sql  (0) 2017.03.07

설정

트랙백

댓글

You can check table T158G for all GMCODE available.

01          MB01
02          MB31
03          MB1A
04          MB1B
05          MB1C
06          MB11
07          MB04

  1. GM_Code 01: Goods receipt for purchase order
  2. GM_Code 02: Goods receipt for production order
  3. GM_Code 03: Goods issue
  4. GM_Code 04: Transfer posting
  5. GM_Code 05: Other goods receipts
  6. GM_Code 06: Reversal of goods movements
  7. GM_Code 07: Subsequent adjustment to a subcontract order


For movement indicator, you can check domain KZBEW.

- Goods movement w/o reference

B - Goods movement for purchase order

F - Goods movement for production order

L - Goods movement for delivery note

K - Goods movement for kanban requirement (WM - internal only)

O - Subsequent adjustment of "material-provided" consumption

W - Subsequent adjustment of proportion/product unit material

설정

트랙백

댓글

SAP Search Help를 사용할때 이미 선택된 어떤 값을 search help의 parameter 로

지정해서 search help 띄우는 방법.


- 해당 필드에 대해서 on value-request event에서 search help 띄우도록 지정


PROCESS ON VALUE-REQUEST.
  FIELD p_lgort MODULE f4_help_lgort.



- tabname : search help를 가지고 있는 table

  fieldname : search help를 가지고 있는 table의 field

  searchhelp : search help name

  shlpparam : search help에서 읽어올 field 이름

  dynpprog, dynpnr, dynprofield : 읽어온 field 값을 setting 할 화면, 필드

  callback_form : parameter setting을 지정하는 부분.



MODULE f4_help_lgort INPUT.

  DATAreturn_tab TYPE TABLE OF ddshretval WITH HEADER LINE.

  CALL FUNCTION 'F4IF_FIELD_VALUE_REQUEST'
    EXPORTING
      tabname           'RESB'
      fieldname         'LGORT'
      searchhelp        'H_T001L' "search help 이름
      shlpparam         'LGORT'   "search help에서 가져올 필드
      dynpprog          sy-repid
      dynpnr            sy-dynnr
      dynprofield       'P_LGORT'
      callback_program  sy-repid
      callback_form     'CALLB_VALUE_REQUEST'
    TABLES
      return_tab        return_tab
    EXCEPTIONS
      field_not_found   1
      no_help_for_field 2
      inconsistent_help 3
      no_values_found   4
      OTHERS            5.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

*  CHECK sy-subrc = 0.
*  READ TABLE return_tab INDEX 1.
*  p_lgort = return_tab-fieldval. "위의 dynprofield 를 지정하면 이로직 필요 없음.

ENDMODULE.




FORM callb_value_request  TABLES   record_tab STRUCTURE seahlpres
                          CHANGING shlp TYPE shlp_descr_t
                                   callcontrol LIKE ddshf4ctrl.

  DATAls_selopt    LIKE LINE OF shlp-selopt.

  ls_selopt-shlpfield 'WERKS'.
  ls_selopt-sign      'I'.
  ls_selopt-option    'EQ'.
  ls_selopt-low       p_werks.

  APPEND ls_selopt TO shlp-selopt .

ENDFORM.

설정

트랙백

댓글

New Open Sql

SAP Program/ABAP 2017. 3. 7. 10:19


https://www.consolut.com/en/s/sap-ides-access/d/s/doc/B-ABENNEWS-740_SP05-OPEN_SQL

설정

트랙백

댓글

Include 이용하여 Internal Table등을 선언할때 

Renaming with suffix 라는 명령어를 사용하면 기존의 이름 뒤에 이름을 붙여주는 기능이네요.

잘 사용하면 편리할것 같습니다.


TYPES BEGIN OF ty_data.
  INCLUDE TYPE jcds AS status_change RENAMING WITH SUFFIX _change.
  INCLUDE TYPE tj02t AS status_text RENAMING WITH SUFFIX _text.
TYPES END OF ty_data.

DATAlt_status TYPE STANDARD TABLE OF ty_data.
SELECT  jcds~*,
           tj02t~*
  FROM  jcds INNER JOIN tj02t
    ON  jcds~stat tj02t~istat
 WHERE  tj02t~spras @sy-langu
  INTO  TABLE @lt_status
UP TO 100 ROWS.

IF sy-subrc 0.
  cl_demo_output=>display_data(
  EXPORTING
  value lt_status
  name 'New AGE SQL : 9' ).
ENDIF.

'SAP Program > ABAP' 카테고리의 다른 글

Search Help 를 parameter setting 해서 사용하는 방법  (0) 2017.03.15
New Open Sql  (0) 2017.03.07
New Open sql - data exist check  (0) 2017.03.07
1개 이상의 Sheet를 가진 excel file 읽기  (0) 2017.03.07
LONG Text ID, Object 찾기  (0) 2017.03.03

설정

트랙백

댓글

따로 변수 선언같은거 없이 check 가 가능하네요.

편리할것 같고 빠른것은 별 차이가 없을것 같고요.


SELECT SINGLE @abap_true
FROM    mara
INTO @DATA(lv_exists)
WHERE MTART = 'IBAU'.

IF lv_exists = abap_true.
WRITE:/ 'Data Exists!! New AGE SQL : 7'.
ENDIF.


설정

트랙백

댓글