28. 6-я программа в SAP. ООП в ABAP. Паттерн MVC.

Создадим 6-ю программу, где рассмотрим как можно использовать ООП в ABAP. ООП будем рассматривать на основе шаблона проектирования MVC. Создадим программу ZKRE_HW6. Для этого скопируем 4-ю программу, транзакция SE80:

image_398

Рассказывать про ООП я здесь не буду, обновить знания по ООП можно в википедии. Единственно сделаю вставочку про MVC.

Model-view-controller (MVC, «модель-представление-контроллер», «модель-вид-контроллер») — схема использования нескольких шаблонов проектирования, с помощью которых модель приложения, пользовательский интерфейс и взаимодействие с пользователем разделены на три отдельных компонента таким образом, чтобы модификация одного из компонентов оказывала минимальное воздействие на остальные. Данная схема проектирования часто используется для построения архитектурного каркаса, когда переходят от теории к реализации в конкретной предметной области.

Мы создадим три класса.

ZCL_KRE_HW6_MDL - модель, описание данных.

ZCL_KRE_HW6_CNT - класс который будет создавать объект модели.

ZCL_KRE_HW6_VIEW - класс отображения данных.

image_400

image_401

Не забываем активировать программу.

Удалим радиокнопки с экрана, они нам не понадобятся!

*&---------------------------------------------------------------------*
*& Report  ZKRE_HW4
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zkre_hw6 NO STANDARD PAGE HEADING.
TABLES: sscrfields.
DATA: gt_products TYPE zkre_t_hw3,
      gs_products LIKE LINE OF gt_products,
      it_ran_quant TYPE zkre_r_quant,
      wa_ran_quant LIKE LINE OF it_ran_quant.

SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS: p_id TYPE zkre_products-id.
PARAMETERS: p_name TYPE zkre_products-name MODIF ID m1.
SELECT-OPTIONS: p_quant FOR gs_products-quantity.
SELECT-OPTIONS: p_desc FOR gs_products-description NO INTERVALS.
"PARAMETERS: p_s1 RADIOBUTTON GROUP uc1,
"            p_s2 RADIOBUTTON GROUP uc1.
SELECTION-SCREEN END OF BLOCK bl1.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN PUSHBUTTON 1(10) bt1 USER-COMMAND uc2.

INITIALIZATION.
  bt1 = text-bt1.

  " Делаем поле Name обязательным для заполнения.

AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    CASE screen-group1.
      WHEN 'M1'.
        screen-required = 1.
        MODIFY SCREEN.
    ENDCASE.
  ENDLOOP.

AT SELECTION-SCREEN.
  CASE sscrfields-ucomm.
    WHEN 'UC2'.
      CLEAR: p_id, p_name, p_quant[], p_desc[].
  ENDCASE.

START-OF-SELECTION.



  REFRESH it_ran_quant.
  wa_ran_quant-sign = 'I'.
  wa_ran_quant-option = 'EQ'.
  wa_ran_quant-low = '555'.
  wa_ran_quant-high = ''.
  APPEND wa_ran_quant TO it_ran_quant.

  IF p_s2 EQ 'X'.
    CALL FUNCTION 'ZKRE_FM4'
      EXPORTING
        ir_quant    = it_ran_quant
      IMPORTING
        er_products = gt_products.
  ELSEIF p_s1 EQ 'X'.

    SELECT zkre_products~id supply_id name purchase_cost sale_cost quantity description supply_date
    INTO CORRESPONDING FIELDS OF TABLE gt_products
    FROM ( ( zkre_products INNER JOIN zkre_productst ON zkre_productst~prod_id = zkre_products~id )
    INNER JOIN zkre_supply ON zkre_supply~id = zkre_products~supply_id )
    WHERE zkre_products~name EQ p_name.

  ENDIF.

  NEW-PAGE LINE-SIZE 138.
  WRITE: 'Day and time of program execution: ',sy-datum, ' ', sy-uzeit.
  SKIP 2.
  ULINE.
  WRITE: / sy-vline,
   AT (4) 'ID', sy-vline, AT (10) 'SUPPLY_ID', sy-vline, AT (17) 'NAME', sy-vline, AT (13) 'PURCHASE_COST', sy-vline,
         AT (13) 'SALE_COST', sy-vline, AT (10) 'QUANTITY', sy-vline, AT (35) 'DESCRIPTION', sy-vline, 'SUPPLY_DATE', sy-vline.
  ULINE.



  LOOP AT gt_products INTO gs_products.
    WRITE: /   sy-vline,
               AT (4) gs_products-id COLOR COL_KEY,
               sy-vline,
               AT (10) gs_products-supply_id COLOR COL_KEY,
               sy-vline,
               AT (17) gs_products-name COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-purchase_cost COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-sale_cost COLOR COL_NORMAL,
               sy-vline,
               AT (10) gs_products-quantity COLOR COL_NORMAL,
               sy-vline,
               AT (35) gs_products-description COLOR COL_NORMAL,
               sy-vline,
               AT (11) gs_products-supply_date COLOR COL_NORMAL,
               sy-vline.
  ENDLOOP.
ULINE.
TOP-OF-PAGE.
  WRITE: 'Name of report - ', sy-repid.
  SKIP 1.
  WRITE:  'Executed by ', sy-uname.

Будем использовать MVC.
Для начала создадим класс ZCL_KRE_HW6_MDL. Либо через навигатор объектов SE80.

image_402

Либо через транзакцию SE24

image_403

Задаем описание и модификатор доступа также снимем галочку с final.

image_404

Нажимаем Save и далее как обычно в пакет и транспортный запрос.

Создадим в классе метод GET_DATA с такими параметрами:

image_405

Сохраняем метод.
Двойной клик по имени метода или нажимаем иконку Code.

image_406

Попадаем в редактор где введем следующий код из 4-й программы:

METHOD get_data.
  SELECT zkre_products~id supply_id name purchase_cost sale_cost quantity description supply_date
    INTO CORRESPONDING FIELDS OF TABLE it_products
    FROM ( ( zkre_products INNER JOIN zkre_productst ON zkre_productst~prod_id = zkre_products~id )
    INNER JOIN zkre_supply ON zkre_supply~id = zkre_products~supply_id )
    WHERE zkre_products~name EQ p_name.
ENDMETHOD.

 

image_407

Cохраняем и переходим на вкладку атрибуты где создаем атрибут it_products.

image_408

Сохраняем и возвращаемся опять на вкладку методы где зададим параметр.

image_409

Создадим такой параметр:

image_410

Сохраняем, активируем и запустим на выполнение наш класс - нажимаем F8.

Получаем следующую картинку, где нажимаем иконку часов.

image_411

Указываем следующее значение параметра и нажимаем выполнить.

image_412

Видим что появились записи.

image_413

Нажав на них получим таблицу.

image_414

Так мы убеждаемся что наш класс написан правильно и он работает.

Создадим класс ZCL_KRE_HW6_CNT который будет создавать объект модели. Транзакция SE24.

image_415

image_416

Создадим метод GET_OBJECT сохраним и перейдем  в редактор кода для этого метода.

image_417

METHOD get_object.
  CREATE OBJECT: o_model.
ENDMETHOD.

Добавим всего одну строку кода.

image_418

 

Вернемся в главное окно редактирования класса и создадим еще атрибут для этого класса следующего вида:

image_419

Сохраняем, активируем наш класс и запускаем на выполнение F8, также как мы тестировали предыдущий класс.
Получаем следующий экран где нажимаем иконку выполнить.

image_420

После чего видно, что наш атрибут принял уже не нулевое значение.

image_421

Класс отработал корректно.

Теперь создадим класс для отображения наших данных ZCL_KRE_HW6_VIEW.  Стандартно транзакция SE24.

image_422

image_423

Создаем метод SHOW_DATA.

image_424

Добавляем в метод следующий код из главной программы.

image_425

 

METHOD show_data.

  NEW-PAGE LINE-SIZE 138.
  WRITE: 'Day and time of program execution: ',sy-datum, ' ', sy-uzeit.
  SKIP 2.
  ULINE.
  WRITE: / sy-vline,
   AT (4) 'ID', sy-vline, AT (10) 'SUPPLY_ID', sy-vline, AT (17) 'NAME', sy-vline, AT (13) 'PURCHASE_COST', sy-vline,
         AT (13) 'SALE_COST', sy-vline, AT (10) 'QUANTITY', sy-vline, AT (35) 'DESCRIPTION', sy-vline, 'SUPPLY_DATE', sy-vline.
  ULINE.



  LOOP AT gt_products INTO gs_products.
    WRITE: /   sy-vline,
               AT (4) gs_products-id COLOR COL_KEY,
               sy-vline,
               AT (10) gs_products-supply_id COLOR COL_KEY,
               sy-vline,
               AT (17) gs_products-name COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-purchase_cost COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-sale_cost COLOR COL_NORMAL,
               sy-vline,
               AT (10) gs_products-quantity COLOR COL_NORMAL,
               sy-vline,
               AT (35) gs_products-description COLOR COL_NORMAL,
               sy-vline,
               AT (11) gs_products-supply_date COLOR COL_NORMAL,
               sy-vline.
  ENDLOOP.
  ULINE.

 
ENDMETHOD.

Как вы могли заметить мы просто разрезали исходный тексто 6-й программы на части и повставляли эти части в разные классы.

Сохраянем. Вернемся на главную страницу и добавим импортируемый параметр, который мы будем получать из класса модели и передавать в класс вьюшки.

image_426

image_427

Сохраяем и вернемся в экран редактирования кода метода. Вставим там следующую строку.

image_428

В итоге код метода должен получиться таким.

METHOD show_data.

  DATA: gs_products LIKE LINE OF gt_products.

  NEW-PAGE LINE-SIZE 138.
  WRITE: 'Day and time of program execution: ',sy-datum, ' ', sy-uzeit.
  SKIP 2.
  ULINE.
  WRITE: / sy-vline,
   AT (4) 'ID', sy-vline, AT (10) 'SUPPLY_ID', sy-vline, AT (17) 'NAME', sy-vline, AT (13) 'PURCHASE_COST', sy-vline,
         AT (13) 'SALE_COST', sy-vline, AT (10) 'QUANTITY', sy-vline, AT (35) 'DESCRIPTION', sy-vline, 'SUPPLY_DATE', sy-vline.
  ULINE.



  LOOP AT gt_products INTO gs_products.
    WRITE: /   sy-vline,
               AT (4) gs_products-id COLOR COL_KEY,
               sy-vline,
               AT (10) gs_products-supply_id COLOR COL_KEY,
               sy-vline,
               AT (17) gs_products-name COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-purchase_cost COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-sale_cost COLOR COL_NORMAL,
               sy-vline,
               AT (10) gs_products-quantity COLOR COL_NORMAL,
               sy-vline,
               AT (35) gs_products-description COLOR COL_NORMAL,
               sy-vline,
               AT (11) gs_products-supply_date COLOR COL_NORMAL,
               sy-vline.
  ENDLOOP.

ENDMETHOD.

Сохраняем, проверяем, активируем и запускаем на выполнение.

image_429

image_430

image_431

Класс отработал нормально.

Теперь когда все классы созданы, доделаем главную программу.  Из текста главной программы можно удалить блоки которые мы перенесли в классы.

*&---------------------------------------------------------------------*
*& Report  ZKRE_HW4
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zkre_hw6 NO STANDARD PAGE HEADING.
TABLES: sscrfields.
DATA: gt_products TYPE zkre_t_hw3,
      gs_products LIKE LINE OF gt_products,
      it_ran_quant TYPE zkre_r_quant,
      wa_ran_quant LIKE LINE OF it_ran_quant.

SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS: p_id TYPE zkre_products-id.
PARAMETERS: p_name TYPE zkre_products-name MODIF ID m1.
SELECT-OPTIONS: p_quant FOR gs_products-quantity.
SELECT-OPTIONS: p_desc FOR gs_products-description NO INTERVALS.
PARAMETERS: p_s1 RADIOBUTTON GROUP uc1,
            p_s2 RADIOBUTTON GROUP uc1.
SELECTION-SCREEN END OF BLOCK bl1.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN PUSHBUTTON 1(10) bt1 USER-COMMAND uc2.

INITIALIZATION.
  bt1 = text-bt1.

  " Делаем поле Name обязательным для заполнения.

AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    CASE screen-group1.
      WHEN 'M1'.
        screen-required = 1.
        MODIFY SCREEN.
    ENDCASE.
  ENDLOOP.

AT SELECTION-SCREEN.
  CASE sscrfields-ucomm.
    WHEN 'UC2'.
      CLEAR: p_id, p_name, p_quant[], p_desc[].
  ENDCASE.

START-OF-SELECTION.



  REFRESH it_ran_quant.
  wa_ran_quant-sign = 'I'.
  wa_ran_quant-option = 'EQ'.
  wa_ran_quant-low = '555'.
  wa_ran_quant-high = ''.
  APPEND wa_ran_quant TO it_ran_quant.

  IF p_s2 EQ 'X'.
    CALL FUNCTION 'ZKRE_FM4'
      EXPORTING
        ir_quant    = it_ran_quant
      IMPORTING
        er_products = gt_products.
  ELSEIF p_s1 EQ 'X'.

    SELECT zkre_products~id supply_id name purchase_cost sale_cost quantity description supply_date
    INTO CORRESPONDING FIELDS OF TABLE gt_products
    FROM ( ( zkre_products INNER JOIN zkre_productst ON zkre_productst~prod_id = zkre_products~id )
    INNER JOIN zkre_supply ON zkre_supply~id = zkre_products~supply_id )
    WHERE zkre_products~name EQ p_name.

  ENDIF.

  NEW-PAGE LINE-SIZE 138.
  WRITE: 'Day and time of program execution: ',sy-datum, ' ', sy-uzeit.
  SKIP 2.
  ULINE.
  WRITE: / sy-vline,
   AT (4) 'ID', sy-vline, AT (10) 'SUPPLY_ID', sy-vline, AT (17) 'NAME', sy-vline, AT (13) 'PURCHASE_COST', sy-vline,
         AT (13) 'SALE_COST', sy-vline, AT (10) 'QUANTITY', sy-vline, AT (35) 'DESCRIPTION', sy-vline, 'SUPPLY_DATE', sy-vline.
  ULINE.



  LOOP AT gt_products INTO gs_products.
    WRITE: /   sy-vline,
               AT (4) gs_products-id COLOR COL_KEY,
               sy-vline,
               AT (10) gs_products-supply_id COLOR COL_KEY,
               sy-vline,
               AT (17) gs_products-name COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-purchase_cost COLOR COL_NORMAL,
               sy-vline,
               AT (13) gs_products-sale_cost COLOR COL_NORMAL,
               sy-vline,
               AT (10) gs_products-quantity COLOR COL_NORMAL,
               sy-vline,
               AT (35) gs_products-description COLOR COL_NORMAL,
               sy-vline,
               AT (11) gs_products-supply_date COLOR COL_NORMAL,
               sy-vline.
  ENDLOOP.
ULINE.
TOP-OF-PAGE.
  WRITE: 'Name of report - ', sy-repid.
  SKIP 1.
  WRITE:  'Executed by ', sy-uname.

В итоге текст главной программы будет иметь вид:

image_432

image_433

image_434

 

*&---------------------------------------------------------------------*
*& Report  ZKRE_HW4
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zkre_hw6 NO STANDARD PAGE HEADING.

TABLES: sscrfields.
DATA: gt_products TYPE zkre_t_hw3,
      gs_products LIKE LINE OF gt_products.

DATA: contr TYPE REF TO zcl_kre_hw6_cnt,
      view TYPE REF TO zcl_kre_hw6_view.

SELECTION-SCREEN BEGIN OF BLOCK bl1 WITH FRAME TITLE text-001.
PARAMETERS: p_id TYPE zkre_products-id.
PARAMETERS: p_name TYPE zkre_products-name MODIF ID m1.
SELECT-OPTIONS: p_quant FOR gs_products-quantity.
SELECT-OPTIONS: p_desc FOR gs_products-description NO INTERVALS.
SELECTION-SCREEN END OF BLOCK bl1.

SELECTION-SCREEN SKIP.
SELECTION-SCREEN PUSHBUTTON 1(10) bt1 USER-COMMAND uc2.

INITIALIZATION.
  bt1 = text-bt1.

AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    CASE screen-group1.
      WHEN 'M1'.
        screen-required = 1.
        MODIFY SCREEN.
    ENDCASE.
  ENDLOOP.

AT SELECTION-SCREEN.
  CASE sscrfields-ucomm.
    WHEN 'UC2'.
      CLEAR: p_id, p_name, p_quant[], p_desc[].
  ENDCASE.

START-OF-SELECTION.

  CREATE OBJECT: contr.
  CALL METHOD contr->get_object.
  CALL METHOD
    contr->o_model->get_data
    EXPORTING
      p_name = p_name.

  CREATE OBJECT: view.
  CALL METHOD
    view->show_data
    EXPORTING
      gt_products = contr->o_model->it_products.


  ULINE.

TOP-OF-PAGE.
  WRITE: 'Name of report - ', sy-repid.
  SKIP 1.
  WRITE:  'Executed by ', sy-uname.

Запустим на выполнение.

image_434-1

image_434-3

Вот таким образом можно реализовать ООП в ABAP.

Комментарии

Чтобы оставить комментарий, необходимо Войти или Зарегистрироваться.