# 시작하기 전
# 프로그램을 개발하면서 한 번쯤은 경험하지 않을까?라는 생각과
또한 현업이나 컨설턴트나 누군가 자신에게 "피벗테이블처럼 Table 데이터를 가로에서 세로로 변경해서 가독성 있게 만들어주세요."라고 들었을 때?
무엇부터 해야 할지 모르겠는 당신을 위해서 글을 썼다.
( 물론 당신 = 나 )
피벗테이블은 클릭 몇 번만으로 뚝딱해서 Table 데이터를 가로에서 세로로 변경해 준다.
하지만 SAP에서는 그러한 기능은 없는 걸로 알고 있다....
# 사람마다 로직은 다르니 참고정도만 하셔유( 코딩에 정답은 없다 )
시나리오.
# ID와 날짜에 맞춰서 월 단위로 조회가 되는 리포트를 만들어 주셨으면 좋겠다.
#1. 시작하기 전, 생성
# 1. DB Table 준비하기
# 이미 준비가 되어있으면 넘어가자.
ZPRODUCT_GJ ( DB Table ) = 가로 테이블
# 2. Strcutre( 구조 ) 만들기 = 가로 인터널 테이블 만들기 위함
# 가로 스트럭처를 만드는 데 있어서는 Local Structure 만들어도 되고, SE11 가서 만들어도 되는데
여기서는 SE11에서 만드는 걸로 하겠다.
우리는 월 단위로 보여줘야 하기 때문에 다음과 같이 스트럭처를 만들었다.
ZSPRO_GJ( ALV Table ) = 세로 테이블 TYPE Structure
# 혹여나 테이블 말고 스트럭처를 만드는 이유는 우리는 "조회"가 목적이기 때문에 스트럭처를 만든 것뿐이다.
* ALV Table Type
TYPES: BEGIN OF TY_S_SPRO.
TYPES: ID TYPE ZPRODUCT, " CHAR 10자리 "
MON01 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON02 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON03 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON04 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON05 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON06 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON07 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON08 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON09 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON10 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON11 TYPE ZCOUNT_GJ, " NUMC 10자리 "
MON12 TYPE ZCOUNT_GJ, " NUMC 10자리 "
END OF TY_S_SPRO.
참고
# 월 단위가 아닌 일 단위, 주 단위도 이와 비슷하게 만들면 된다.
대신 앞에 영어는 같고 숫자만 달라져야 한다. ( 패턴이 있어야 한다 )
일 단위 # DAY01
DAY02
주 단위 # WEEK01
WEEK02
# 2. 기준 만들기 ( 중요 )
우리는 세로->가로 테이블로 변경해야 하기 때문에 "기준"이라는 것이 필요하다.
세로 테이블에서 ID를 보면 APPLE, BANANA, GAMJA 총 16개이다.
하지만
다음과 같이 보여주게 하려면 중복된 ID 빼고 총라인은 3개가 있어야 한다는 것이다.
이 라인이 가로 테이블 "기준" 이 되는 것이다.
# 중복된 데이터를 다 빼고 남은 ID = 기준
우리는 이 기준에 따라서 GT_DATA에서 값을 가져와야 하기 때문에 "기준"을 잡아줘야 한다.
예를 들어
GAMJA일 때?
GT_DATA의 GAMJA 데이터에서 1월부터 12월까지의 데이터를 가져올 수 있게 되는 것이고,
Apple 일 때?
GT_DATA의 Apple 데이터에서 1월부터 12월까지의 데이터를 가져올 수 있다.
# TOP 선언
1. GT_DATA( 세로 테이블 ) = ZPRODUCT_GJ ( DB Table)
GT_LIST( 가로 테이블 ) = TYPE TABLE OF ZSPRO_GJ ( Strucutre ) => ALV에 보여줄 인터널 테이블
* DB Table Type
DATA: GT_DATA TYPE TABLE OF ZPRODUCT_GJ.
* ALV Table Type
TYPES: BEGIN OF TY_S_LIST.
INCLUDE STRUCTURE ZSPRO_GJ.
TYPES: CELLSTYL TYPE LVC_T_STYL,
CELLSCOL TYPE LVC_T_SCOL,
ROWSCOL TYPE CHAR04,
END OF TY_S_LIST.
DATA: GT_LIST TYPE TABLE OF TY_S_LIST. " ALV Table Type "
# ALV Table TYPE에 쓰이는 CELLSTYL, CELLSCOL, ROWSCOL은 신경 안 써도 된다.
중요한 것은 빨간색 상자이다.
# START-OF-SELECTION
1. 세로 테이블인 GT_DATA에 데이터( ZPRODUCT_GJ )를 넣어보자.
SELECT *
FROM ZPRODUCT_GJ
INTO CORRESPONDING FIELDS OF TABLE @GT_DATA.
2. 세로 테이블에서 가로 테이블로 데이터를 옮겨주고 기준에 따라서 중복제거를 해주자.
MOVE-CORRESPONDING GT_DATA TO GT_LIST.
DELETE ADJACENT DUPLICATES FROM GT_LIST. " 중복제거
# 중복 제거를 하는 이유 : ( # 2. 기준 만들기 ) 이 부분을 다시 보자.
3. 로직
# ( LOOP문을 2번 사용하는 버전 ) OR ( LOOP문을 한번 써서 Append을 통해서 넣는 버전 ) 등등..
( LOOP문을 2번 사용하는 버전, Field-Symbol 사용 )
DATA:
L_DATUM(10),
L_MON(5).
LOOP AT GT_LIST ASSIGNING FIELD-SYMBOL(<FS_LIST>).
LOOP AT GT_DATA INTO DATA(LS_DATA)
WHERE ID EQ <FS_LIST>-ID.
" 현재 있는 날짜에서 년,월,일 중에서 월만 가져오기. "
L_DATUM = LS_DATA-ZDAY+4(2).
" 스트럭처에 맞게 동적으로 돌리기 위해서 설정 "
L_MON = |MON{ L_DATUM }|.
" L_MON에 대한 값을 동적으로 처리하는 로직 "
ASSIGN COMPONENT L_MON OF STRUCTURE <FS_LIST> TO FIELD-SYMBOL(<FS>).
" LS_DATA-ZCOUNT와 MON01~MON12 타입과 자릿수가 맞지않기 때문에 맞춰야한다. "
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
INPUT = LS_DATA-ZCOUNT
IMPORTING
OUTPUT = LS_DATA-ZCOUNT.
" 위에서 날짜 조건에 따라서 값을 합산하기 "
<FS> += LS_DATA-ZCOUNT. " == <FS> = <FS> + LS_DATA-ZCOUNT "
ENDLOOP.
ENDLOOP.
FIELD-SYMBOL에 대해서 이해하고 넘어가고싶으면 밑에 링크 클릭!
2023.09.20 - [.SAP/..ABAP] - SAP FIELD SYMBOL( 필드심볼 ) 정리, 예제
로직 설명( 더 보기 참고 )
#1. GT_LIST을 LOOP문을 돌린다.
#2. GT_DATA를 LOOP문에 LOOP문을 또 돌린다. ( 기준에 따라서 조건 값 설정 )
#3. 날짜에 따라서 값을 넣어줘야 하기 때문에 설정한다.
#4. ASSIGN을 통해서 동적으로 값을 넣어주는 준비한다.
#5. 수량을 더하고 GT_LIST에 값을 넣어준다.
더 보기
FIELD SYMBOL을 설정 할 때 중요했던 것은 A, B, C 였다. 만들어보자.
( 이해가 안 간다면 위에 링크를 클릭.. )
# 1. GT_LIST을 LOOP문을 돌린다.
# 가로 테이블에 값을 넣어야 하기 때문이다.
# 중복된 데이터는 없는 상태고 ID만 있는 상태이다.
B = <FS_LIST>
# 2. GT_DATA를 LOOP문에 LOOP문을 또 돌린다. ( 기준에 따라서 조건 값 설정 )
# 세로 테이블에 데이터를 가져오기 위함.
# Read Table을 사용하면 데이터를 하나하나 못 가져온다.
# 3. 날짜에 따라서 동적으로 값을 넣어줘야 하기 때문에 설정한다. ( A = 패턴 만들기 )
# 우리가 가로 테이블을 만들 때 만들었던 스트럭처를 참고해 보자.
MON01, MON02.... 이런 식으로 숫자만 증가되는 걸 볼 수 있다.
우리는 월 단위로 나누었으니깐 MON(동적) 이런 식으로 짜면 된다는 것이다.
예를 들어
일 단위로 한다고 하면 DAY(동적)
주 단위로 한다고 하면 WEEK(동적) 이 된다.
이제 로직을 봐보자.
# L_DATUM은 LS_DATA-ZDAY+4(2)는 월 단위이기 때문에 월 단위를 가져오는 로직
# L_MON은 위에서 말했듯이 L_DATUM을 통해서 만든 MON( 동적 )이기 때문에 만든 로직인 것이다.
# CONCATENATE New Syntax or Old Syntax 사용한 것이다.
디버깅을 돌려보면
GT_DATA 데이터에 있는 날짜를 가져와서 ( 10월이면 MON10, 11월이면 MON11 ) 이런 식으로 동적으로 들어갈 수 있게 만든 것이다.
A( 패턴 만들기 ) = L_MON
# 4. ASSIGN을 통해서 동적으로 값을 넣어주는 준비한다.
<FS> = <FS_LIST>-( MON01 ~ MON12 )이다.
이런 식으로 일일이 설정을 해야 하지만 우리는 동적으로 사용하기 때문에 효율적으로 사용할 수 있다.
# 5. 수량을 더하고 GT_LIST에 값을 넣어준다.
# 이제 더하고 싶은 수량을 다음과 같이 설정하면 된다.
C( 인터널 테이블에 값을 넣어줄 변수 ) = <FS>
그러면 끝이다.
다른 방법인?
( LOOP문을 한번 써서 Append을 통해서 넣는 버전, Field-Symbol 사용 안 함 )
SORT GT_DATA BY ID.
LOOP AT GT_DATA INTO DATA(LS_DATA).
" 현재 있는 날짜에서 년,월,일 중에서 월만 가져오기. "
L_DATUM = LS_DATA-ZDAY+4(2).
" 월에 맞춰서 데이터 넣기 "
CASE L_DATUM.
WHEN '01'.
GS_LIST-MON01 += LS_DATA-ZCOUNT.
WHEN '02'.
GS_LIST-MON02 += LS_DATA-ZCOUNT.
WHEN '03'.
GS_LIST-MON03 += LS_DATA-ZCOUNT.
WHEN '04'.
GS_LIST-MON04 += LS_DATA-ZCOUNT.
WHEN '05'.
GS_LIST-MON05 += LS_DATA-ZCOUNT.
WHEN '06'.
GS_LIST-MON06 += LS_DATA-ZCOUNT.
WHEN '07'.
GS_LIST-MON07 += LS_DATA-ZCOUNT.
WHEN '08'.
GS_LIST-MON08 += LS_DATA-ZCOUNT.
WHEN '09'.
GS_LIST-MON09 += LS_DATA-ZCOUNT.
WHEN '10'.
GS_LIST-MON10 += LS_DATA-ZCOUNT.
WHEN '11'.
GS_LIST-MON11 += LS_DATA-ZCOUNT.
WHEN '12'.
GS_LIST-MON12 += LS_DATA-ZCOUNT.
ENDCASE.
" ID 필드 값이 변경되기 전, END OF 로직이 타는 구문 "
AT END OF ID.
" 상품 ID 값 넣기 "
GS_LIST-ID = LS_DATA-ID.
APPEND GS_LIST TO GT_LIST.
CLEAR GS_LIST.
ENDAT.
ENDLOOP.
로직 설명( 더 보기 )
#1. GT_DATA을 LOOP문을 돌린다.( GT_DATA는 SORT 필수 )
#2. 날짜에 따라서 값을 넣어줘야 하기 때문에 설정한다.
#3. 필드심볼을 사용하지 않았기 때문에 CASE문으로 월 별로 구별한다.
#4. AT END OF 구문을 통해 "기준"에 따라서 로직을 타게 해 주고 상품 ID 값을 넣어주자.
#5. APPEND을 통해서 GT_LIST에 값을 넣어준다.
더 보기
# 참고로 APPEND을 사용할 때에는 LOOP문을 돌면서 "기준"을 잡기 때문에 이 부분을 해줄 필요가 없다.
# 또한 Field Symbol(필드심볼)을 사용하지 않기 때문에 동적인 부분을 없앴다.
( 필드 심볼을 사용하면 APPEND를 굳이 해줄 필요가 없기 때문에 )
하지만
SORT는 필수로 해주어야한다. ( 기준에 따라서 )
#1. GT_DATA을 LOOP문을 돌린다. ( SORT 필수 )
#2. 날짜에 따라서 값을 넣어줘야 하기 때문에 설정한다.
# GT_DATA에 가지고 있는 날짜 데이터에서 월만 가져오게 해 주었다.
디버깅을 돌려서 L_DATUM에 데이터를 보면
이런 식으로 월만 가져오게 할 수 있다.
#3. 필드심볼을 사용하지 않았기 때문에 CASE문으로 월 별로 구별한다.
# 앞에서 가져온 L_DATUM( 월 별 )을 통해서 1월부터 12월까지 구별해 준 뒤,
각 월 별에 값을 더해주면서 넣어주자.
#4. AT END OF 구문을 통해 "기준"에 따라서 로직을 타게 해 주고상품 ID 값을 넣어주자.
#5. APPEND을 통해서 GT_LIST에 값을 넣어준다.
# 사진에 설명이 있듯이, "기준"이 되는 ID의 값이 변경되기 전에 로직을 타게 해주는 구문이다.
APPNED 구문에 디버깅을 걸어보면 다음과 같이 APPLE 일 때 값, GAMJA 일 때 값이 들어가 있는 걸 볼 수 있다.
APPLE
GAMJA
끝.
실행해 보자.
실행해 보면 가로 테이블로 변경된 것 을 볼 수 있다.
세로 테이블에서 가로 테이블로 변경하기에는
LOOP문을 2번 쓰나, APPEND을 쓰나,,
중요한 건 "기준"이다.
"기준만 설정하고 합산할 것만 설정하면 끝나는 문제이다."
하지만.
ALV 필드를 보면 1월부터 12월이 아닌 개수, 개수,.... 개수로 이루어져 있다.
ALV 필드 이름을 설정하는 것 또한? 동적으로 설정하면 편하다.
FIELDCATALOG 설정
# 로직 설명은 하지 않겠다..! 실행을 시켜보면
도움이 되셨으면 하단에 있는 광고 한번씩 눌러주세유!!
'.ABAP > ..모든 것' 카테고리의 다른 글
SAP SAPlink 설치, 사용 방법 (0) | 2023.09.26 |
---|---|
SAP FIELD SYMBOL( 필드심볼 ) 정리, 예제 (0) | 2023.09.20 |
SAP Workbench Request OR Customizing Request 정리 (0) | 2023.09.08 |
SAP Select-Options 정리 (0) | 2023.09.03 |
SAP Range 정리 (2) | 2023.09.01 |