ABAP

중첩 IF 90% COND로 줄이는 법 #shorts #SAP #ABAP

개요 및 이 글에서 다루는 것

ABAP 7.4 이후 도입된 COND 표현식은 전통적인 IF...ELSEIF...ENDIF 블록을 한 줄의 우아한 표현식으로 압축할 수 있는 강력한 기능입니다. 이 글에서는 중첩 조건문을 COND로 리팩토링하는 방법과 실무 시나리오에서의 적용 패턴을 다룹니다.

  • COND 표현식의 기본 문법과 타입 추론 원리 이해
  • 중첩 IF/ELSEIF 구문을 한 줄로 변환하는 패턴 습득
  • SWITCH와 COND의 차이점 구분
  • 판매 주문, 배송, 재고 등급 실무 시나리오 적용
  • 가독성과 성능 트레이드오프 판단 능력 확보

알아두면 좋은 배경 지식

이 글은 ABAP 7.40 이상의 표현식 기반 문법(Constructor Expression)에 대한 기본 이해를 가정합니다. VALUE #( ), NEW #( ), 인라인 선언(DATA(...)) 사용 경험이 있으면 좋습니다. 또한 일반적인 절차형 IF/CASE 사용에 익숙해야 하며, 데이터 타입 호환성 개념(TYPE, LIKE)도 필요합니다.

실행 환경과 준비물

본 예제는 다음 환경에서 검증되었습니다.

  • NetWeaver AS ABAP 7.40 SP08 이상 (COND/SWITCH 표현식 도입 버전)
  • S/4HANA 1909 이상 권장 (최신 ABAP 표현식 문법 활용)
  • ABAP Cloud / Steampunk 환경에서도 동일하게 동작
  • 개발 도구: ADT(ABAP Development Tools for Eclipse) 또는 SE80
  • 권한: S_DEVELOP 개발 권한, 테스트 패키지 접근 권한

구버전 시스템에서는 컴파일 오류가 발생할 수 있으므로 시스템 릴리즈 확인이 우선입니다.

COND 표현식의 핵심 개념

COND는 "조건부 표현식(Conditional Expression)"의 약자로, 절차문이 아닌 값을 반환하는 표현식이라는 점이 가장 중요한 특징입니다. 전통적인 IF는 명령문(statement)이라 변수에 값을 할당하려면 별도의 = ... 구문이 필요하지만, COND는 그 자체가 하나의 값으로 평가됩니다.

기본 구문은 다음과 같습니다.

DATA(result) = COND data_type(
  WHEN condition1 THEN value1
  WHEN condition2 THEN value2
  ELSE default_value ).

여기서 data_type 자리에 #을 쓰면 컨텍스트(좌변)로부터 타입을 자동 추론합니다.

COND vs SWITCH의 결정적 차이

두 표현식은 비슷해 보이지만 용도가 다릅니다.

구분CONDSWITCH
조건 형태임의의 논리식 (>, <, AND, OR)단일 값 비교 (=)
대응 절차문IF / ELSEIF 체인CASE 문
사용 시점복합 조건, 범위 비교단일 변수의 값 분기

예를 들어 "금액이 1만원 이상이고 VIP면..."처럼 복합 조건은 COND가, "주문 상태가 A/B/C 중 무엇이냐"는 SWITCH가 자연스럽습니다.

실전 예제 1단계: 기본 변환

판매 주문(SalesOrder)의 금액에 따라 할인율을 결정하는 단순한 시나리오부터 시작합니다. 먼저 전통적인 IF 방식입니다.

DATA: lv_order_amount TYPE p DECIMALS 2 VALUE '15000.00',
      lv_discount     TYPE p DECIMALS 2.

IF lv_order_amount >= 100000.
  lv_discount = '0.20'.
ELSEIF lv_order_amount >= 50000.
  lv_discount = '0.10'.
ELSEIF lv_order_amount >= 10000.
  lv_discount = '0.05'.
ELSE.
  lv_discount = '0.00'.
ENDIF.

위 코드를 COND로 변환하면 다음과 같습니다.

DATA(lv_order_amount) = CONV p( '15000.00' ).

DATA(lv_discount) = COND p(
  WHEN lv_order_amount >= 100000 THEN '0.20'
  WHEN lv_order_amount >= 50000  THEN '0.10'
  WHEN lv_order_amount >= 10000  THEN '0.05'
  ELSE '0.00' ).

WRITE: / 'Applied Discount Rate:\, lv_discount.

9줄의 절차문이 4줄의 표현식으로 줄어들었습니다. 더 중요한 것은 "할인율 = 금액에 따른 함수"라는 의미가 좌변에 명확히 드러난다는 점입니다.

실전 예제 2단계: 배송 구분과 에러 처리

실무에서는 단순 값 반환을 넘어 복합 조건과 예외 시나리오를 다뤄야 합니다. 배송 우선순위를 결정하는 클래스 메서드를 예제로 살펴봅니다.

CLASS lcl_delivery_classifier DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_shipment,
             shipment_id   TYPE c LENGTH 10,
             weight_kg     TYPE p LENGTH 8 DECIMALS 2,
             is_vip        TYPE abap_bool,
             dest_country  TYPE c LENGTH 3,
           END OF ty_shipment.

    METHODS classify_priority
      IMPORTING is_shipment       TYPE ty_shipment
      RETURNING VALUE(rv_priority) TYPE string
      RAISING   cx_sy_conversion_no_number.
ENDCLASS.

CLASS lcl_delivery_classifier IMPLEMENTATION.
  METHOD classify_priority.

    IF is_shipment-shipment_id IS INITIAL.
      RAISE EXCEPTION TYPE cx_sy_conversion_no_number.
    ENDIF.

    rv_priority = COND string(
      WHEN is_shipment-is_vip = abap_true
       AND is_shipment-dest_country = 'KOR'
        THEN 'EXPRESS_DOMESTIC'
      WHEN is_shipment-is_vip = abap_true
        THEN 'EXPRESS_INTERNATIONAL'
      WHEN is_shipment-weight_kg > 50
        THEN 'FREIGHT_HEAVY'
      WHEN is_shipment-weight_kg BETWEEN 5 AND 50
        THEN 'STANDARD_PARCEL'
      ELSE 'STANDARD_SMALL' ).

  ENDMETHOD.
ENDCLASS.

여기서 주목할 점은 조건 평가 순서입니다. COND는 위에서 아래로 첫 번째 참(true)인 WHEN을 찾으면 즉시 평가를 멈춥니다. 따라서 가장 구체적인 조건을 위에 배치해야 합니다.

실전 예제 3단계: THROW를 활용한 예외 통합

프로덕션 코드에서는 예외 발생까지 표현식에 통합할 수 있습니다. CONDTHEN 자리에 THROW 구문을 받아 예외를 던질 수 있습니다.

CLASS lcx_invalid_grade DEFINITION
  INHERITING FROM cx_static_check.
ENDCLASS.

CLASS lcl_stock_grader DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS evaluate_stock_grade
      IMPORTING iv_available_qty TYPE i
                iv_safety_qty    TYPE i
      RETURNING VALUE(rv_grade)  TYPE c
      RAISING   lcx_invalid_grade.
ENDCLASS.

CLASS lcl_stock_grader IMPLEMENTATION.
  METHOD evaluate_stock_grade.

    rv_grade = COND c(
      WHEN iv_safety_qty <= 0
        THEN THROW lcx_invalid_grade( )
      WHEN iv_available_qty >= iv_safety_qty * 3
        THEN 'A'
      WHEN iv_available_qty >= iv_safety_qty * 2
        THEN 'B'
      WHEN iv_available_qty >= iv_safety_qty
        THEN 'C'
      WHEN iv_available_qty > 0
        THEN 'D'
      ELSE 'E' ).

  ENDMETHOD.
ENDCLASS.

성능 측면에서 COND는 컴파일 시점에 동등한 IF/ELSEIF 코드로 변환되므로 런타임 오버헤드는 사실상 없습니다.

자주 발생하는 실수와 해결책

Q1. "Type cannot be determined" 오류가 납니다.
COND #( ... )로 작성하면서 결과를 인라인 DATA(x) =으로 받으면 컴파일러가 타입 추론 기준이 없어 오류가 발생합니다. 해결책: COND string( ... )처럼 명시적 타입 지정.

Q2. ELSE를 빠뜨렸더니 예상치 못한 초기값이 나옵니다.
모든 WHEN이 거짓이면 해당 타입의 초기값(숫자는 0, 문자열은 공백)이 반환됩니다. 비즈니스 로직상 "해당 없음"이 의미를 가질 때는 반드시 ELSE를 명시하거나 THROW로 예외를 발생시키는 것이 권장됩니다.

Q3. WHEN 절을 너무 많이 넣으니 오히려 IF보다 읽기 어렵습니다.
일반적으로 WHEN이 5~6개를 넘어가면 가독성이 떨어집니다. 이 경우 (1) 결정 테이블로 데이터 분리, (2) 의미 단위로 메서드 분리, (3) 단순 값 매칭이면 SWITCH로 전환을 검토하십시오.

이어서 살펴볼 만한 주제

  • SWITCH 표현식과 함께 사용하는 분기 패턴
  • REDUCE 표현식으로 내부 테이블 집계 처리
  • FILTERFOR를 결합한 함수형 ABAP 스타일
  • RAP(RESTful ABAP Programming) Behavior Definition에서의 활용
  • CDS View의 CASE WHEN 구문과 ABAP COND 비교

댓글 0

아직 댓글이 없습니다.