ABAP 로직 추가

Objective

After completing this lesson, you will be able to 비즈니스 오브젝트의 동작을 구현합니다.

유효성 확인

의미 키 확인

ABAP RESTful 어플리케이션 프로그래밍 모델에서 데이터베이스 테이블의 키는 일반적으로 클라이언트 필드와 UUID 필드로 구성되며, 이 필드는 비즈니스 오브젝트의 신규 인스턴스를 생성할 때 런타임에 의해 자동으로 지정됩니다. 시스템에서 테이블의 각 레코드를 고유하게 식별할 수 있도록 이 필드 조합으로 충분합니다. 그러나 이 기술 키뿐만 아니라 오브젝트에 의미 키도 있습니다. 이 경우 항공사와 항공편 번호의 조합도 비즈니스 로직에 따라 고유해야 합니다. 이 필드 조합의 고유성을 보장하기 위해 유효성 확인 형식으로 자체 점검을 구현해야 합니다.

CDS 뷰 엔티티의 동작 정의에서 유효성 확인을 선언하고 동작 구현 클래스에서 이를 구현합니다.

앱의 입력 점검

의미 키를 점검할 뿐만 아니라 수행해야 하는 다른 점검도 있습니다. 예를 들어, 생성된 앱에서 데이터를 생성하고 읽고 업데이트하고 삭제할 수 있지만 아직 일관성 점검은 포함되지 않습니다. 따라서 존재하지 않거나 출발 공항과 도착 공항이 동일한 항공사에 대해 항공편 연결을 생성할 수 있습니다.

이를 방지하기 위해 동작 정의에서 추가 유효성 확인을 정의하고 이를 동작 구현 클래스에 구현합니다.

메시지 텍스트 생성

유효성 확인을 생성하기 전에 표시할 텍스트를 생성해야 합니다. 메시지 클래스를 사용하여 이 작업을 수행합니다. 메시지 클래스는 특정 어플리케이션 영역에 속하는 최대 1000개의 메시지로 구성된 컬렉션입니다. 그림에 표시된 것처럼 각 텍스트에는 메시지 클래스 내에서 메시지를 고유하게 식별하는 번호가 있습니다.

신규 메시지 클래스를 생성하려면 다음과 같이 진행합니다.

  1. 파일신규기타... 를 선택하고 필터 필드에 메시지를 입력합니다.

  2. 적중 리스트에서 메시지 클래스 엔트리를 더블 클릭하고 신규 메시지 클래스의 패키지, 이름, 내역을 입력합니다. 다음을 선택합니다.

  3. 전송 요청에 메시지 클래스를 지정하고 종료 를 선택합니다.

메시지가 표시될 때 구체적인 값으로 대체되는 자리 표시자도 메시지에 포함될 수 있습니다. 자리 표시자에는 앰퍼샌드 기호 뒤에 숫자가 표시됩니다. 각 메시지에 최대 4개의 자리 표시자를 사용할 수 있습니다.

유효성 확인 정의

유효성 확인을 정의하려면 비즈니스 오브젝트의 동작 정의에 유효성 확인 선언을 추가합니다. 이 예에서는 사용자가 데이터 레코드를 저장할 때마다 유효성 확인을 수행해야 하며, 이는 레코드를 생성할 때나 나중에 레코드를 변경할 때일 수 있습니다.

동작 정의에서 유효성 확인을 정의할 때 해당 메소드가 없음을 알리는 경고가 표시됩니다. Quick Fix(키 조합 CTRL + 1)를 사용하여 메소드를 동작 구현에 추가합니다. 동작 구현은 동작 풀 내의 로컬 클래스입니다. 메소드 정의에는 유효성 확인 구현으로 식별되는 FOR VALIDATE ON SAVE 추가 요소가 포함되어 있습니다. 임포트 매개변수 KEYS 가 있습니다. 생성 또는 변경된 오브젝트의 키가 포함된 내부 테이블입니다. 사용자가 입력한 실제 데이터를 읽을 때 사용합니다.

FOR Connection~CheckSemanticKey 추가 요소는 동작 정의의 유효성 확인 CheckSemanticKey와 메소드를 연결합니다. 여기서 연결 은 뷰 엔티티 Z_R_CONNECTION의 별칭 이름입니다.

유효성 확인을 정의할 때 해당 구현도 생성해야 합니다. 동작 풀의 메소드입니다. 이 작업을 수행하는 가장 쉬운 방법은 Quick Fix를 사용하는 것입니다. 유효성 확인 이름에 커서를 놓고 CTRL + 1 을 누릅니다. ADT에서 메소드를 생성하도록 제안합니다. 제안을 더블 클릭하여 메소드를 생성합니다.

유효성 확인 프로세스

노트

이 섹션의 코드 예 중 일부는 루프 내에서 SELECT 문을 사용합니다. 이는 예제를 단순하게 유지하기 위해 이루어졌습니다. 루프의 SELECT는 성능 문제를 일으킬 수 있으므로 피해야 합니다.

시스템에서 유효성 확인이 트리거되면 해당 구현을 호출합니다. 임포트 매개변수 KEYS 에는 변경된 데이터 레코드의 키가 포함되어 있습니다. 키를 사용하여 엔티티 조작 언어(EML, Entity Manipulation Language)를 사용하여 필요한 레코드의 필드를 읽습니다. EML은 ABAP에서 비즈니스 오브젝트를 처리할 수 있는 특수 명령문 세트입니다.

데이터를 읽으면 필요한 점검을 수행할 수 있습니다. 점검에 실패하면 적절한 오류 메시지를 발행해야 하며, 중요한 경우 프레임워크에 변경사항을 데이터베이스에 쓰지 않도록 해야 합니다.

유효성 확인의 첫 번째 태스크는 사용자 입력을 읽는 것입니다. 엔티티 조작 언어(EML, Entity Manipulation Language) 문(READ ENTITIES)을 사용하여 이 작업을 수행합니다. 해당 데이터 레코드의 키는 임포트 매개변수 키를 사용하여 유효성 확인으로 전달됩니다.

의미 키의 유효성을 확인해야 하는 필드는 항공사의 CarrierID, 항공편 번호의 ConnectionID입니다.

코드 스니핏은 CORRESPONDING 키워드와 인라인 선언을 결과 세트에 사용합니다. 아래에는 명시적으로 정의된 변수를 사용하는 동등한 코드가 나와 있습니다. 따라서 사용되는 유형을 더 쉽게 이해할 수 있습니다.

Code Snippet
12345678910111213
DATA read_keys TYPE TABLE FOR READ IMPORT zs4d400_r_connection. DATA connections TYPE TABLE FOR READ RESULT zs4d400_r_connection. read_keys = CORRESPONDING #( keys ). READ ENTITIES OF zs4d400_r_connection IN LOCAL MODE ENTITY Connection FIELDS ( CarrierID ConnectionID ) WITH read_keys RESULT connections.

사용자 입력을 읽으면 CarrierIDConnectionID 의 값을 사용하여 지금 처리 중인 키가 아닌 다른 데이터 세트에서 이 의미 키가 이미 사용되었는지 확인할 수 있습니다. 키 조합은 활성 테이블 또는 드래프트 테이블에 있을 수 있으므로 둘 다 살펴봐야 하며 가장 효율적인 방법은 유니온을 사용하는 것입니다.

이 쿼리의 결과 세트는 항상 비어 있어야 합니다. 그렇지 않은 경우 CarrierID와ConnectionID의 조합이 동일한 레코드가 더 있습니다. 즉, 사용자가 현재 생성하려는 레코드가 중복이므로 거부해야 합니다.

운송업체 ID와 연결 ID의 조합이 이미 있는 경우 check_result 테이블에 엔트리가 있습니다. 이 경우 메시지를 출력해야 합니다.

첫 번째 단계는 메시지 오브젝트를 생성하는 것입니다. 자체 참조 나를 사용하고 new_message( ) 메소드를 호출하여 이 작업을 수행합니다. 매개변수 ID, 숫자, 심각도는 필수 항목입니다. ID는 메시지가 포함된 메시지 클래스의 이름입니다. 번호는 메시지 번호입니다. 심각도는 메시지를 성공, 정보, 경고 또는 오류 메시지로 분류합니다. 동작 구현 클래스에는 컴포넌트가 다양한 심각도 레벨을 나타내는 구조화된 상수 ms가 포함되어 있습니다. 이 경우 심각도 레벨 ms-error 가 필요합니다.

메소드에는 선택적 임포트 매개변수 v1, v2, v3, v4도 있습니다. 이 필드를 사용하여 자리 표시자를 실제 값으로 바꿉니다. 이 예에서 자리 표시자 &1은(는) 항공사 코드로 대체되고 자리 표시자 &2은(는) 항공편 번호로 대체됩니다.

메소드 호출 결과는 오브젝트 참조입니다. 다음 단계에서는 오류 메시지가 OData 서비스를 반환하고 앱 미리보기에 표시되도록 오브젝트를 런타임으로 전달합니다.

런타임에 메시지가 표시되도록 하려면 보고된 구조를 사용하여 메시지를 보고해야 합니다. 이는 모든 유효성 확인 방법의 암시적 변경 매개변수로 심층 구조입니다. 엔티티의 별칭 이름을 가진 컴포넌트가 포함되어 있습니다. 이 컴포넌트는 내부 테이블입니다.

메시지를 보고하려면 다음 세 가지를 수행해야 합니다.

  1. 영향을 받는 레코드의 키를 내부 테이블에 추가합니다. 필드 그룹 %tky 를 사용하여 이 작업을 수행할 수 있습니다. 이와 같은 필드를 그룹화할 때 각 필드를 개별적으로 처리할 필요 없이 그룹 이름을 지정할 수 있습니다.
  2. 메시지 오브젝트를 테이블에 첨부합니다. 내부 테이블의 %msg 컴포넌트에 메시지 오브젝트의 오브젝트 참조를 지정하여 이 작업을 수행합니다.
  3. 영향을 받는 필드에 메시지를 바인딩합니다. 이렇게 하면 앱에서 필드가 강조표시됩니다. 이렇게 하면 사용자가 앱을 더 잘 탐색할 수 있습니다. 내부 테이블의 %element 구성요소를 사용하여 이 작업을 수행합니다.

이 예에서 reported_record 는 내부 테이블 reported-connection 의 라인 유형이 포함된 구조입니다. 구조 연결에서%tky 필드 그룹의 내용으로 %tky 컴포넌트를 채웁니다. 이 연결 구조는 사용자가 입력한 데이터를 포함하는 내부 테이블의 작업 영역으로 사용됩니다. 그런 다음 new_message( ) 메소드를 사용하여 생성한 메시지 오브젝트를 %msg 컴포넌트에 지정합니다. 마지막으로 메시지를 CarrierIDConnectionID 필드에 바인딩하려면 구조 %element 를 사용합니다. %element 요소에는 엔터티의 각 필드에 대한 구성 요소가 포함되어 있습니다. 컴포넌트를 참(true)으로 설정하면 해당하는 입력 필드가 앱에서 강조표시됩니다. 구조화 상수 if_abap_behv=>mk를 사용하여 이 작업을 수행합니다. 여기에는 checked/true 에 대해 컴포넌트가 설정되며, unchecked/false 는 off 입니다.

이 시점에서 전역 상수 abap_trueabap_false는 데이터 유형이 호환되지 않으므로 사용할 수 없습니다.

메시지를 보낼 뿐만 아니라 잘못된 데이터를 저장하지 않도록 런타임도 알려야 합니다. 이를 위해 유효성 확인 방법의 실패한 구조를 사용합니다. 실패 는 모든 유효성 확인 방법에 있는 암시적 변경 매개변수입니다.

레코드를 실패한 것으로 보고하려면 해당 필드 그룹 %tky를 내부 테이블(Internal Table)의 필드 그룹 %tky에 추가하십시오.

다음 유효성 확인에서는 사용자가 입력한 항공사가 실제로 존재하는지 확인합니다. 첫 번째 단계는 EML 문 READ ENTITIES를 사용하여 사용자 입력을 읽는 것입니다. 이번에는 CarrierID 필드만 읽으면 됩니다.

SELECT SINGLE 문은 CDS 뷰 엔티티 /dmo/i_carrier 를 사용하여 데이터를 읽고 지정된 항공사가 있는지 확인합니다. 이 경우 전역 상수 abap_true('X')의 값이 필드에 배치됩니다. SELECT 문 다음에 초기 값이 있으면 이전 예시와 같이 메시지를 발행하고 보고한 후 실패한 구조에 레코드를 추가해야 합니다.

최종 유효성 확인에서는 출발 공항과 도착 공항이 서로 다른지 확인합니다. 첫 번째 단계는 READ ENTITIES 문을 사용하여 사용자 입력을 읽는 것입니다. 이번에는 AirportFromIDAirportToID 필드가 관련이 있습니다.

출발 공항과 도착 공항이 동일한 경우 해당 메시지를 발행하고 리포트된 구조와 실패한 구조를 입력해야 합니다. 코드 추출에는 메시지를 생성하기 위한 관련 코딩이 표시됩니다. 보고된 구조와 실패한 구조를 채우기 위한 코딩은 이전 예시와 동일합니다.

의미 키의 유효성 확인 방법

결정(Determinations)

공항 코드 기준 도시 결정

예제 앱에서 항공편 연결 엔티티에는 출발 공항, 도시, 국가, 도착 공항, 도시, 국가가 포함됩니다. 사용자가 이 정보를 모두 입력하도록 강제할 수 있지만, 사용자가 공항 코드만 입력하고 앱이 데이터베이스에서 해당 도시와 국가 정보를 읽도록 하는 것이 사용자 경험과 데이터 일관성 면에서 더 좋습니다. ABAP RESTful 어플리케이션 프로그래밍 모델에서는 결정을 사용하여 이러한 종류의 태스크를 수행할 수 있습니다.

먼저 결정을 구현합니다. 그런 다음 자동으로 입력되는 필드의 입력을 비활성화하는 방법을 배웁니다.

결정 정의

결정은 비즈니스 오브젝트의 동작 정의에서 정의합니다. 여기서 결정은 getCities 라고 하며, 비즈니스 오브젝트가 저장되고 AirportFromIDAirportToID 필드 중 하나 이상이 변경될 때마다 호출됩니다. 동작 정의에서 Quick Fix를 사용하여 동작 구현에서 해당 메소드를 생성할 수 있습니다.

결정 프로세스

결정 프로세스의 각 단계를 살펴보겠습니다.

시스템에서 결정을 트리거하면 해당 구현이 호출됩니다. 임포트 매개변수 KEYS 에는 변경된 데이터 레코드의 키가 포함되어 있습니다. 결정 방법에서는 EML을 사용하여 유효성 확인과 동일한 방식으로 키를 기준으로 데이터를 읽습니다. 그러나 결정에서는 메소드에서 데이터를 조작하고, 따라서 EML 문 UPDATE를 사용하여 프레임워크에서 보유한 데이터를 업데이트해야 합니다.

노트

이 섹션의 코드 예 중 일부는 루프 내에서 SELECT 문을 사용합니다. 이는 예제를 단순하게 유지하기 위해 이루어졌습니다. 루프의 SELECT는 성능 문제를 일으킬 수 있으므로 피해야 합니다.

결정을 시작할 때 EML을 사용하여 사용자 입력을 읽습니다. AirportFromIDAirportToID 필드가 필요하며 이 필드를 사용하여 도시 및 국가 정보를 입력합니다.

데모 데이터 모델에서는 CDS 뷰 엔티티 /dmo/i_airport 를 사용하여 특정 공항이 위치한 도시와 국가를 읽을 수 있습니다. 예시에서는 사용자가 입력할 구조의 필드를 명시적으로 지정하는 INTO 절의 변형을 사용합니다. 데이터에 대한 변경사항은 내부 테이블(Internal Table)의 작업 영역에 있으며 MODIFY 문을 사용하여 테이블 자체로 리턴해야 합니다.

READ ENTITIES 문은 파생 유형이 FOR READ RESULT인 내부 테이블을 리턴합니다. 트랜잭션 버퍼에서 데이터를 변경하려면 MODIFY ENTITIES 문이 필요합니다. 파생 유형이 FOR UPDATE인 내부 테이블을 사용하여 이 명령문으로 변경할 데이터를 전달합니다. 데이터 필드는 두 유형에서 동일하지만 FOR UPDATE 테이블에는 관리 정보가 포함된 %control 이라는 추가 구조가 있습니다.

연결 테이블을 MODIFY ENTITIES 문에 전달할 수 없습니다. 따라서 실제 수정을 수행하기 전에 적절한 유형의 내부 테이블(connections_upd)에 데이터를 복사해야 합니다.

결정에 입력한 필드로 데이터를 업데이트하려면 MODIFY ENTITIES 문을 사용합니다. FIELDS 절에서 업데이트할 필드를 지정하고 WITH 추가 요소를 사용하여 내부 테이블에 데이터를 전달합니다. 이 테이블에는 올바른 파생 데이터 유형이 있어야 하며, 이 경우 TYPE TABLE FOR UPDATE zsd4d400_r_connection 입니다.

MODIFY ENTITIES 문은 REPORTED 절을 사용하여 수신하는 메시지를 반환할 수 있습니다. 그런 다음 내부 테이블(Internal Table)의 내용을 결정 방법의 REPORTED 구조에 복사하여 이 메시지를 사용자의 비즈니스 오브젝트로 전파합니다.

도시와 국가를 결정하는 방법

항공편 가격 유효성 확인

이 연습문제에서는 항공편 가격의 유효성 확인을 정의하고 구현합니다.

템플릿:

  • 없음

솔루션:

  • /LRN/S4D400_R_FLIGHT(동작 정의)
  • /LRN/BP_S4D400_R_FLIGHT(전역 클래스)

선행조건

이전 연습문제를 완료했습니다. 데이터베이스 테이블 Z##FLIGHT (## = 그룹 번호)를 생성하고 OData UI 서비스를 위한 개발 오브젝트를 생성했습니다.

태스크 1: 가격 유효성 확인

유효성 확인을 정의하고 구현하여 가격 필드에 플러스 값(권장 이름: validatePrice)이 있는지 확인합니다. 값이 마이너스이거나 0이면 변경을 거부하고 메시지 클래스 /LRN/S4D400에서 적절한 오류 메시지를 보고하십시오.

단계

  1. 동작 정의 ZR_##FLIGHT 에서 신규 유효성 확인 validatePrice 를 정의합니다. 표준 작업 생성 중에는 항상 유효성 확인이 실행되지만 다른 모든 작업에 대해 가격 값이 변경된 경우에만 유효성 확인이 실행되어야 합니다.

    힌트

    가능하면 코드 자동 완성을 사용하여 코드를 입력합니다.
    1. 동작 정의 ZR_##FLIGHT 를 엽니다.

    2. 코드를 다음과 같이 조정합니다.

      Code Snippet
      12345
      create; update; delete; validation validatePrice on save { create; field Price; }
  2. 동작 정의를 활성화합니다.

    1. Ctrl + F3 을 눌러 동작 정의를 활성화합니다.

  3. Quick Fix를 사용하여 동작 핸들러 클래스에서 유효성 확인 구현 메소드를 생성합니다.

    1. 유효성 확인 이름에 커서를 놓고 Ctrl + 1 을 선택합니다.

    2. 유효성 확인을 위한 메소드 추가 엔트리를 더블 클릭합니다.....

  4. validatePrice 메소드를 시작할 때 failed-flight 라인 유형으로 입력하는 구조화 데이터 오브젝트(제안 이름: failed_record)를 선언합니다. 마찬가지로 reported-flight 라인 유형(권장 이름: reported_record)을 사용하여 입력하는 구조화 데이터 오브젝트를 선언합니다.

    노트

    이러한 구조는 유효성 확인에서 오류가 발견된 경우 failed-flightreported-flight에 행을 추가하는 데 사용됩니다.
    1. 다음 코드를 추가합니다.

      Code Snippet
      12
      DATA failed_record LIKE LINE OF failed-flight. DATA reported_record LIKE LINE OF reported-flight.
  5. READ ENTITIES 문을 사용하여 트랜잭션 버퍼에서 사용자 입력을 읽습니다. IN LOCAL MODE 추가 요소를 사용하여 키 필드와 가격 필드만 읽도록 합니다. 결과 세트에 인라인 선언(제안 이름: flights)을 사용합니다.

    노트

    FIELDS 추가 요소 뒤에 키 필드를 나열할 필요는 없습니다. READ ENTITIES는 항상 키 필드를 읽습니다.
    1. 신고 뒤에 다음 코드를 추가하고 ##을 그룹 번호로 대체합니다.

      Code Snippet
      12345
      READ ENTITIES OF ZR_##Flight IN LOCAL MODE ENTITY Flight FIELDS ( Price ) WITH CORRESPONDING #( keys ) RESULT DATA(flights).
  6. 방금 읽은 데이터에 대해 루프를 구현합니다. 작업 영역에 인라인 선언을 사용합니다(제안 이름: 항공편).

    1. EML 문 뒤에 다음 코드를 추가합니다.

      Code Snippet
      123
      LOOP AT flights INTO DATA(flight). ENDLOOP.
  7. 루프 내에서 가격 구성요소가 0보다 큰지 확인합니다. 그렇지 않은 경우 failed_record 구조에 현재 항공편의 키를 입력하고 failed-flight 테이블에 신규 행으로 추가합니다. 마찬가지로 구조 reported_record를 현재 항공편의 키로 채우고 리포트-항공편 테이블에 새 행으로 추가합니다.

    힌트

    드래프트 지원 비즈니스 오브젝트에서는 컴포넌트 %tky를 사용하여 키를 지정하는 것이 좋습니다.
    1. 루프 안에 다음 코드를 추가합니다.

      Code Snippet
      12345678
      IF flight-price <= 0. failed_record-%tky = flight-%tky. APPEND failed_record TO failed-flight. reported_record-%tky = flight-%tky. APPEND reported_record TO reported-flight. ENDIF.
  8. APPEND 문 앞에 메시지 오브젝트를 참조하여 reported_record 구조의 %msg 컴포넌트를 입력합니다. 메시지 오브젝트를 생성하려면 다음과 같이 입력하여 new_message 메소드를 호출합니다.

    매개변수 이름
    id'/LRN/S4D400'
    number'101'
    심각도ms-error
    1. 코드를 다음과 같이 조정합니다.

      Code Snippet
      123456789101112131415
      LOOP AT flights INTO DATA(flight). IF flight-price <= 0. failed_record-%tky = flight-%tky. APPEND failed_record TO failed-flight. reported_record-%tky = flight-%tky. reported_record-%msg = new_message( id = '/LRN/S4D400' number = '101' severity = ms-error ). APPEND reported_record TO reported-flight. ENDIF. ENDLOOP.
  9. 클래스를 활성화합니다.

    1. Ctrl + F3 을 눌러 클래스를 활성화합니다.

태스크 2: 테스트 및 디버그

유효성 확인 구현에 중단점을 설정합니다. OData UI 서비스의 미리보기를 재시작하고 기존 항공편의 가격을 변경합니다. 유효하고 잘못된 엔트리를 생성하고 유효성 확인을 디버그합니다.

단계

  1. validatePrice 메소드의 READ ENTITIES 문에 중단점을 설정합니다.

    1. validatePrice 메소드 구현에서 READ ENTITIES 문을 찾고 행 번호 왼쪽에 있는 영역을 더블 클릭하여 중단점을 설정합니다.

  2. OData UI 서비스의 미리보기를 재시작합니다.

    1. 미리보기가 포함된 브라우저 윈도우 또는 브라우저 탭을 닫습니다.

    2. ZUI_##FLIGHT_O4 서비스 바인딩을 엽니다. 오른쪽의 엔티티 세트 및 연관 관계 리스트에서 먼저 항공편 엔트리를 선택한 다음 미리보기.... 를 선택합니다.

  3. 앱에서 항공편 리스트를 조회하고 항공편 중 하나의 세부사항을 연 다음 변경 모드로 전환합니다.

    1. 이전 연습문제에서 완료한 대로 진행합니다.

  4. 가격을 변경한 후 저장 을 선택합니다. 디버거에서 유효성 확인을 분석합니다.

    1. 이전 연습문제에서 완료한 대로 진행합니다.