본문 바로가기
RAP

RAP 19 - MANAGED REPORT : VIRTUAL ELEMENT

by SAPortal 2026. 9. 16.
반응형

 

 

 

목차

    Virtual Element

    Virtual Element는 데이터베이스 테이블에 실제 존재하거나 저장된 컬럼이 아니라 CDS View상에서 선언하고 ABAP Class 로직을 통해 실시간/동적으로 계산하여 UI에 보여주는 가상 필드입니다.

    CDS View의 기본 SQL 연산만으로 표현하기 힘든 복잡한 비즈니스 로직, 외부 API/함수 연산 결과를 CDS 레이어에 얹어 Fiori UI나 OData 서비스로 전달할 때 활용합니다.

     

    주요 특징

    DB 미저장 : DB테이블의 물리적 컬럼이 아니므로 Persistence Table 변경이 필요 없습니다.

    ABAP Class 연동 : CDS 어노테이션을 통해 계산 로직을 담당할  ABAP Calculator Class를 직접 지정합니다.

    Read-Only특성 : 기본적으로 화면 조회 시점에 ABAP로직이 트리거 되어 결과값을 반환하는 읽기전용 필드입니다.

     

     

    Travel정보중에 Starting Date가 있습니다. 여행시작일인데 현재일자 기준으로 여행시작일까지 몇일이 남았는지 화면에 보여주면 App을 이용하는 사용자는 좀더 편하게 업무를 할 수 있을것 같습니다. 그런데 이 필드는 DB에 없는 필드입니다. 화면에 어떻게 보여줘야 할까요? 이럴때 Virtual Element를 사용하면 됩니다.

    이번 실습에서는 남은 일수를 보여주는 필드를 추가하고 남은 일수에 따라 일수옆에 아이콘을 보여주도록 하겠습니다. 그 기준은 남은일수가 8일 이상남으면 초록색, 7일까지는 노란색, 날짜가 없거나 이미 지나면 빨강색 아이콘으로 하겠습니다.

     

     

    Travel Projection View로 이동해서 Virtual 필드를 추가해 보겠습니다. Virtual 필드는 Interface View가 아니라 Projection View에 선언을 합니다. 비즈니스 오브젝트의 데이터 모델이 아니라 표현계층에 속하는 값이기 때문입니다.

    Virtual 필드는 필드 앞에 "virtual" 이라는 키워드를 붙입니다. 그리고 필드이름 + 타입으로 선언을 하고 @ObjectModel.virtualElementCalculatedBy 어노테이션으로 Virtual 필드의 값을 결정할 Class를 지정해 줍니다. 그리고 동일한 이름의 Class를 생성합니다.

     

     

    Class를 생성하고 if_sadl_exit_calc_element_read 인터페이스를 추가해 줍니다. 인터페이스에는 2개의 메소드가 존재하는데 일단 둘다 모두 구현부에 추가해 줍니다. 아직 로직은 넣지 않겠습니다.

     

     

    Travel Metadata Extension으로 이동해 남은일수를 보여줄 필드를 추가해 줍니다. @UI.lineItem.criticality 어노테이션은 인자값으로 지정된 'DepartureCriticality' 필드의 값에따라 아이콘을 함께 보여주는 어노테이션입니다. 조금후에 Class에 로직이 구현된 이후 화면에 어떻게 표현이 되는지 확인해 보겠습니다.

     

     

    Virtual Element Class에 로직을 구현해 보겠습니다. 로직은 calculate 메소드에 구현하면 됩니다. 파라미터를 확인해 보겠습니다. it_original_data와 it_requested_calc_elements로 값을 받고 ct_calculated_data로 반환해 주면 될 것 같습니다. 그러면 디버깅을 걸고 App을 실행해서 데이터가 어떻게 들어오는지 확인해 보겠습니다.

     

     

    it_request_calc_elements에는 Virtual 필드 정보가 넘어오고 it_original_data에는 Travel Entity값이 넘어오고 있습니다. it_original_data의 값을 바탕으로 계산한 후에 Virtual 필드의 값을 채워서 ct_calculated_data로 반환해 주도록 로직을 구현해 보겠습니다.

     

     

    먼저 Class 정의부분에 색상관련 상수를 선언합니다. (1:빨간색, 2:노란색, 3:초록색)

     

     

    1. Begin Data에서 현재일자를 뺀 값을 Virtual 필드 DaysUnitDeparture에 넣어줍니다.

    2. DaysUnitDeparture가 0보다 작으면 빨간색, 7보다 작거나 같으면 노란색, 나머지는 초록색으로 표시합니다. 앞에서 Metadata

        Extension에 추가했던 criticality 어노테이션에서 DepartureCriticality 필드의 값을 읽어 아이콘으로 표시하게 됩니다.

    3. Virtual 필드에 값을 넣어주고 전체 데이터를 반환 합니다.

     

     

    App을 실행해 보겠습니다. 추가했던 Virtual 필드가 보이고 계산된 일자도 보입니다. criticality 값에 의해 아이콘도 함께 표시됩니다.

     

     

    Virtual 필드에 대한 로직은 calculate 메소드에 구현하면 된다고 했습니다. 그러면 get_calculation_info 메소드는 언제 필요할까요?

     

     

     

    우리가 추가한 Virtual 필드의 값을 결정하기 위해서는 Begin Date가 필요합니다. 그런데 만약 Begin Date 필드가 화면에 노출하면 안되는 필드면 어떻게 될까요? 테스트를 위해 Metadata Extension에서 Begin Date를 Hidden 처리 해보겠습니다.

     

     

    Begin Date를 Hidden 처리하고 값이 어떻게 들어오는지 확인해 보면 Begin Date값이 들어오지 않습니다. 이런경우 get_calculation_info 메소드를 활용하여 Begin Date값을 calculate 메소드로 넘겨 줄수 있습니다.

     

     

    get_calculation_info 메소드에 로직을 구현해 보겠습니다.

    1. it_requested_calc_elements 에는 Virtual 필드값이 들어옵니다. Virtual 필드 이름이 'DAYSUNTILDEPARTURE' 또는 

        'DEPARTURECRITICALITY' 인경우 Begin Date 필드가 필요합니다. String 타입의 내부테이블을 하나 선언해서 필요한

        필드명을 넣어줍니다. Virtual 필드 이름을 체크하는 이유는 나중에 추가로 Virtual 필드가 추가될 수도 있기 때문입니다.

    2. 필드정보를 반환합니다.

     

     

    로직을 추가하고 App을 다시 실행시켜 Begin Date가 어떻게 들어오는지 확인해 보겠습니다. Hidden필드인 Begin Date값도 잘 들어옵니다. 테스트를 완료했으니 Metadata Extension에서 Begin Date에 걸었던 Hidden 어노테이션을 다시 삭제합니다.

     

     

     

    이번에는 Travel의 상태가 B(Booked)이면 Object Page의 Booking정보를 숨김처리 해보겠습니다. Metadata Extension으로 이동합니다. Object Page에서 Booking정보 숨김처리는 아래와 같이 hidden에 true값을 주면 됩니다. 하지만 이렇게 하면 항상 숨김처리가 되기 때문에 동적으로 hidden처리가 되도록 해보겠습니다.

     

     

    먼저 Projection View에 동적 Hidden 처리를 위한 Virtual 필드를 하나 추가해 줍니다. 값은 true 또는 false값을 받아야 하기 때문에 abap_boolean 타입으로 선언합니다.

     

     

    Virtual Class에 로직을 추가합니다. Status값이 B(Booked)이면 true를 아니면 false값을 넣어줍니다.

     

     

    다시 Metadata Extension으로 이동해서 hidden처리가 동적으로 되도록 수정해 줍니다.

     

     

    App을 다시 실행해서 결과를 확인해 보겠습니다. 상태가 N(New)인 Travel ID를 클릭해 보면 Booking정보가 보입니다.

     

     

    이번에는 상태가 B(Booked)인 Travel ID를 선택해 보면 Hidden처리가 된걸 확인할 수 있습니다.

    반응형