반응형
1. SAP ECC 6.0 기준으로 작성
2. 동적 where조건이 들어가야 하는 필드가 각 테이블 마다 필드명이 다름.
[1] SELECT문 동적 WEHRE 사용
*&---------------------------------------------------------------------*
*& Form GET_DETAIL
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LT_RESB text
* -->P_LT_DATA text
* -->P_I_HISTORY text
*----------------------------------------------------------------------*
FORM get_detail_resb TABLES pt_resb STRUCTURE zcrms0092
USING ps_detail_info TYPE zcrms0095
p_history.
CONSTANTS: c_f_posnr(11) VALUE 'posnr'.
DATA: lv_where_posnr TYPE string,
lv_where_matnr TYPE string.
CLEAR: lv_where_posnr, lv_where_posnr.
PERFORM get_where_clause USING ps_detail_info-posnr
ps_detail_info-matnr
c_f_posnr
CHANGING lv_where_posnr
lv_where_matnr.
*-- Select Data
* p_history = 'X"일 경우 삭제 삭제 이력 테이블에서 조회한다.
CASE p_history.
WHEN space.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_resb
FROM resb
WHERE aufnr = ps_detail_info-aufnr
AND (lv_where_matnr)
AND (lv_where_posnr)
AND bdmng = ps_detail_info-bdmng
AND postp = 'N'
AND xloek = space.
WHEN 'X'.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_resb
FROM zsst8073
WHERE aufnr = ps_detail_info-aufnr
AND (lv_where_matnr).
* AND dedat = ps_detail_info-dedat
* AND dezit = ps_detail_info-dezit
* AND denam = ps_detail_info-denam.
ENDCASE.
IF pt_resb[] IS INITIAL.
EXIT.
ENDIF.
PERFORM get_text_for_field TABLES pt_resb.
SORT pt_resb BY aufnr posnr.
ENDFORM. " GET_DETAIL
*&---------------------------------------------------------------------*
*& Form GET_DETAIL_ZCRMS0093
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LT_ZCRMS0093 text
* -->P_LT_DATA text
* -->P_I_DETAIL_INFO text
* -->P_I_HISTORY text
*----------------------------------------------------------------------*
FORM get_detail_zcrms0093 TABLES pt_zcrms0093 STRUCTURE zcrms0093
USING ps_detail_info TYPE zcrms0095
p_history.
CONSTANTS: c_f_posnr(11) VALUE 'qmseq'.
DATA: lv_qmnum LIKE afih-qmnum.
DATA: lv_where_posnr TYPE string,
lv_where_matnr TYPE string.
CLEAR: lv_qmnum, lv_where_posnr, lv_where_matnr.
PERFORM get_where_clause USING ps_detail_info-posnr
ps_detail_info-matnr
c_f_posnr
CHANGING lv_where_posnr
lv_where_matnr.
SELECT SINGLE qmnum
INTO lv_qmnum
FROM qmel
WHERE aufnr = ps_detail_info-aufnr
AND kzloesch = space.
*-- Select Data
* p_history = 'X"일 경우 삭제 삭제 이력 테이블에서 조회한다.
CASE p_history.
WHEN space.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_zcrms0093
FROM zcst5040
WHERE qmnum = lv_qmnum
AND (lv_where_matnr)
AND (lv_where_posnr)
AND menge = ps_detail_info-bdmng
AND lifnr = ps_detail_info-dealer_cd
AND zsupply = '02'.
WHEN 'X'.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_zcrms0093
FROM zsst8074
WHERE qmnum = lv_qmnum
AND (lv_where_matnr)
AND lifnr = ps_detail_info-dealer_cd.
* AND dedat = ps_detail_info-dedat
* AND dezit = ps_detail_info-dezit
* AND denam = ps_detail_info-denam.
ENDCASE.
IF pt_zcrms0093[] IS INITIAL.
EXIT.
ENDIF.
PERFORM get_text_for_field TABLES pt_zcrms0093.
SORT pt_zcrms0093 BY qmnum qmseq.
ENDFORM. " GET_DETAIL_ZCRMS0093
*&---------------------------------------------------------------------*
*& Form GET_DETAIL_ZCST0040
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* -->P_LT_ZCST0040 text
* -->P_I_DETAIL_INFO text
* -->P_I_HISTORY text
*----------------------------------------------------------------------*
FORM get_detail_zcst0040 TABLES pt_zcst0040 STRUCTURE zcst0040
USING ps_detail_info TYPE zcrms0095
p_history.
CONSTANTS: c_f_posnr(11) VALUE 'item_number'.
DATA: lv_where_posnr TYPE string,
lv_where_matnr TYPE string.
CLEAR: lv_where_posnr, lv_where_matnr.
PERFORM get_where_clause USING ps_detail_info-posnr
ps_detail_info-matnr
c_f_posnr
CHANGING lv_where_posnr
lv_where_matnr.
* p_history = 'X"일 경우 삭제 삭제 이력 테이블에서 조회한다.
CASE p_history.
WHEN space.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_zcst0040
FROM zcst0040
WHERE aufnr = ps_detail_info-aufnr
AND (lv_where_matnr)
AND (lv_where_posnr)
AND pgmng = ps_detail_info-bdmng
AND item_cat = 'N'.
WHEN 'X'.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE pt_zcst0040
FROM zsst8075
WHERE aufnr = ps_detail_info-aufnr
AND (lv_where_matnr).
* AND dedat = ps_detail_info-dedat
* AND dezit = ps_detail_info-dezit
* AND denam = ps_detail_info-denam.
ENDCASE.
IF pt_zcst0040[] IS INITIAL.
EXIT.
ENDIF.
PERFORM get_text_for_field TABLES pt_zcst0040.
SORT pt_zcst0040 BY aufnr item_number.
ENDFORM. " GET_DETAIL_ZCST0040

FORM get_where_clause USING ps_detail_info-posnr TYPE resb-posnr
ps_detail_info-matnr TYPE resb-matnr
pv_f_posnr
CHANGING pv_where_posnr
pv_where_matnr.
DATA: lv_posnr(18),
lv_matnr(28).
CLEAR: lv_posnr, lv_matnr.
"*** 값이 없으면 전체 조회, 있으면 입력 값만 조건 조회
IF ps_detail_info-posnr IS INITIAL.
CONCATENATE pv_f_posnr 'LIKE ''%''' INTO pv_where_posnr
SEPARATED BY space.
ELSE.
CALL FUNCTION 'CONVERSION_EXIT_NUMCV_INPUT'
EXPORTING
input = ps_detail_info-posnr
IMPORTING
output = ps_detail_info-posnr.
CONCATENATE '''' ps_detail_info-posnr '''' INTO lv_posnr
SEPARATED BY space.
CONDENSE lv_posnr NO-GAPS.
CONCATENATE pv_f_posnr ' = ' lv_posnr INTO pv_where_posnr
SEPARATED BY space.
ENDIF.
IF ps_detail_info-matnr IS INITIAL.
pv_where_matnr = 'matnr LIKE ''%'''.
ELSE.
CONCATENATE '''' ps_detail_info-matnr '''' INTO lv_matnr
SEPARATED BY space.
CONDENSE lv_matnr NO-GAPS.
CONCATENATE 'matnr = ' lv_matnr INTO pv_where_matnr
SEPARATED BY space.
ENDIF.
ENDFORM. " GET_WHERE_CLAUSE
[2] RTTI를 활용하여 필드 존재 여부 확인
🔍 설명
- RTTI를 사용하여 현재 구조의 필드 목록을 가져옴
- cl_abap_structdescr=>describe_by_data(<fs_field>)을 사용하여 구조의 메타데이터를 조회.
- components 테이블에 필드 목록이 저장됨.
- 필드 목록에서 해당 필드가 존재하는지 확인
- READ TABLE lt_components INTO ls_component WITH KEY name = 'DEALER_CD'
- sy-subrc = 0 이면 필드가 존재하는 것.
- 존재할 때만 ASSIGN COMPONENT 실행
- 필드가 없으면 ASSIGN을 실행하지 않도록 제어.

FORM get_text_for_field TABLES pt_table.
FIELD-SYMBOLS: <fs_table> TYPE ANY TABLE,
<fs_field> TYPE ANY.
FIELD-SYMBOLS: <lv_matnr> TYPE matnr,
<lv_maktx> TYPE maktx,
<lv_dealer_cd> TYPE zedealer_cd,
<name1> TYPE name1_gp.
DATA: lo_structdescr TYPE REF TO cl_abap_structdescr.
DATA: BEGIN OF ls_component,
length TYPE i,
decimals TYPE i,
type_kind TYPE abap_typekind,
name TYPE abap_compname,
END OF ls_component,
lt_components LIKE STANDARD TABLE OF ls_component WITH KEY name.
DATA: lr_matnr TYPE RANGE OF matnr,
ls_matnr LIKE LINE OF lr_matnr,
lr_dealer_cd TYPE RANGE OF zedealer_cd,
ls_dealer_cd LIKE LINE OF lr_dealer_cd.
DATA: BEGIN OF ls_maktx,
matnr TYPE makt-matnr,
maktx TYPE makt-maktx,
spras TYPE spras,
END OF ls_maktx,
lt_maktx LIKE TABLE OF ls_maktx.
DATA: BEGIN OF ls_dealer_nm,
name1 TYPE kna1-name1,
kunnr TYPE kna1-kunnr,
END OF ls_dealer_nm,
lt_dealer_nm LIKE TABLE OF ls_dealer_nm.
CLEAR: lo_structdescr, ls_component, ls_maktx, ls_matnr, ls_dealer_cd, ls_dealer_nm.
REFRESH: lt_components, lt_maktx, lr_matnr, lr_dealer_cd, lt_dealer_nm.
ASSIGN pt_table[] TO <fs_table>.
LOOP AT <fs_table> ASSIGNING <fs_field>.
lo_structdescr ?= cl_abap_typedescr=>describe_by_data( <fs_field> ).
lt_components[] = lo_structdescr->components[].
CLEAR ls_component.
READ TABLE lt_components INTO ls_component WITH KEY name = 'MATNR'.
IF sy-subrc = 0.
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <fs_field> TO <lv_matnr>.
IF <lv_matnr> IS NOT INITIAL.
_make_range_type2 ls_matnr lr_matnr <lv_matnr>.
ENDIF.
ENDIF.
CLEAR ls_component.
READ TABLE lt_components INTO ls_component WITH KEY name = 'LIFNR'.
IF sy-subrc = 0.
ASSIGN COMPONENT 'LIFNR' OF STRUCTURE <fs_field> TO <lv_dealer_cd>.
IF <lv_dealer_cd> IS NOT INITIAL.
_make_range_type2 ls_dealer_cd lr_dealer_cd <lv_dealer_cd>.
ENDIF.
ENDIF.
ENDLOOP.
"MAKTX
SELECT DISTINCT matnr maktx spras
INTO CORRESPONDING FIELDS OF TABLE lt_maktx
FROM makt
WHERE matnr IN lr_matnr
AND spras = sy-langu
ORDER BY matnr.
IF lr_dealer_cd[] IS NOT INITIAL.
SORT lr_dealer_cd BY low.
DELETE ADJACENT DUPLICATES FROM lr_dealer_cd COMPARING ALL FIELDS.
"DEALER_NM
SELECT name1 kunnr
INTO CORRESPONDING FIELDS OF TABLE lt_dealer_nm
FROM kna1
WHERE kunnr IN lr_dealer_cd
ORDER BY kunnr.
ENDIF.
LOOP AT <fs_table> ASSIGNING <fs_field>.
lo_structdescr ?= cl_abap_typedescr=>describe_by_data( <fs_field> ).
lt_components[] = lo_structdescr->components[].
CLEAR ls_component.
READ TABLE lt_components INTO ls_component WITH KEY name = 'MATNR'.
IF sy-subrc = 0.
ASSIGN COMPONENT 'MATNR' OF STRUCTURE <fs_field> TO <lv_matnr>.
IF <lv_matnr> IS NOT INITIAL.
CLEAR ls_maktx.
READ TABLE lt_maktx INTO ls_maktx WITH KEY matnr = <lv_matnr>
BINARY SEARCH.
IF sy-subrc = 0.
ASSIGN COMPONENT 'MAKTX' OF STRUCTURE <fs_field> TO <lv_maktx>.
<lv_maktx> = ls_maktx-maktx.
ENDIF.
ENDIF.
ENDIF.
CLEAR ls_component.
READ TABLE lt_components INTO ls_component WITH KEY name = 'LIFNR'.
IF sy-subrc = 0.
ASSIGN COMPONENT 'LIFNR' OF STRUCTURE <fs_field> TO <lv_dealer_cd>.
IF <lv_dealer_cd> IS NOT INITIAL.
CLEAR ls_dealer_nm.
READ TABLE lt_dealer_nm INTO ls_dealer_nm WITH KEY kunnr = <lv_dealer_cd>
BINARY SEARCH.
IF sy-subrc = 0.
ASSIGN COMPONENT 'NAME1' OF STRUCTURE <fs_field> TO <name1>.
<name1> = ls_dealer_nm-name1.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM. " GET_TEXT_FOR_FIELD
'SAP > ABAP' 카테고리의 다른 글
변경 문서 헤더 CDHDR, 변경 문서 상세 정보 CDPOS (1) | 2025.03.14 |
---|---|
장비번호(Equipment Number)로 DO 정보찾기 (0) | 2025.03.07 |
VC_I_GET_CONFIGURATION_IBASE (0) | 2025.02.10 |
SYSTEM-CALL OTR GET_TEXT_BY_ALIAS (0) | 2025.02.04 |
BDC와 SAP 세션 (2) | 2024.12.24 |