Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Question on Logic of seperation in OOAbap-Selection screen

former_member196098
Participant
0 Kudos

Hello guys

I like to ask you one question i found and get your ideas.

If you look at the codes for creating an ALV

it always recommends you to seperate logic and business layer etc..

this is the new way of creating an ALV

So you have  a model view and a controller

I implemented that following useful resources.

So that there s class called view

and the selection screen gets called from there inside the method

like

    call SELECTION-SCREEN 100.

     IF sy-subrc EQ 0.

     ENDIF.

But one issue when you execute the report and press GO BACK standard button it doesnot come back to your selection screen but way to your code.

Is there a get around to that?

here is the code below:

Header 1

*&---------------------------------------------------------------------*

*& Report  ZZ_SOLEN_FIRST

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

REPORT ZZ_SOLEN_FIRST.

DATA: gv_vbeln type vbap-Vbeln.

***Screen

SELECTION-SCREEN: BEGIN OF SCREEN 100 TITLE t-004.

SELECTION-SCREEN: BEGIN OF block aa WITH FRAME TITLE t-001.

SELECT-OPTIONS: s_vbeln FOR gv_vbeln.

SELECTion-SCREEN: END OF block aa.

SELECTion-SCREEN: END OF SCREEN 100.

*****DATA Layer

class lcl_data DEFINITION.

   PUBLIC SECTION.

     TYPES: BEGIN OF ty_out,

       vbeln type vbap-vbeln,

       posnr type vbap-posnr,

       matnr type vbap-matnr,

       vkorg type vbak-vkorg,

       END OF ty_out

       .

     TYPES: tt_out TYPE STANDARD TABLE OF ty_out.

     TYPES: gr_vbeln TYPE RANGE OF vbap-vbeln.

     DATA: gt_output TYPE tt_out.

     methods: constructor,

              select_data IMPORTING VALUE(rs_vbeln) TYPE gr_vbeln.

     .

ENDclass.

class lcl_data IMPLEMENTATION.

   method constructor.

     clear GT_OUTPUT.

   ENDMETHOD.

   method select_data.

     DATA: lt_vbak type SORTED TABLE OF vbak WITH UNIQUE KEY vbeln.

     FIELD-SYMBOLS: <lfs_output> like LINE OF gt_output,

                    <lfs_vbak> like LINE OF lt_vbak

                    .

     select vbeln posnr matnr from vbap

       INto TABLE

        GT_OUTPUT

       where vbeln in S_VBELN

       .

     IF sy-SUBRC EQ 0.

       select * from vbak

         INTO TABLE lt_vbak

         FOR ALL ENTRIES IN  GT_OUTPUT

         where vbeln = GT_OUTPUT-vbeln

         .

       LOOP AT gt_output ASSIGNING <lfs_output>.

         READ TABLE lt_vbak ASSIGNING <lfs_vbak>

         with TABLE KEY vbeln = <lfs_output>-vbeln.

         IF sy-Subrc eq 0.

           <lfs_output>-vkorg = <lfs_vbak>-VKORG.

         ENDIF.

       ENDLOOP.

     ENDIF.

   ENDMETHOD.

ENDCLASS.

****Display

class lcl_view DEFINITION.

   PUBLIC SECTION.

     methods: start RETURNING VALUE(rv_true) type abap_bool.

     METHODS: display CHANGING it_data TYPE STANDARD TABLE.

ENDCLASS.

class lcl_view IMPLEMENTATION.

   METHOD start.

     call SELECTION-SCREEN 100.

     IF sy-subrc EQ 0.

       rv_true = abap_true.

     ENDIF.

   endmethod.

   method display.

     DATA: lo_salv_table type REF TO CL_SALV_TABLE,

           lt_columns TYPE SALV_T_COLUMN_REF.

     FIELD-SYMBOLS: <lfs_columns> like LINE OF lt_columns.

     CL_SALV_TABLE=>FACTORY(

*    exporting

*      LIST_DISPLAY   = IF_SALV_C_BOOL_SAP=>FALSE    " ALV Displayed in List Mode

*      R_CONTAINER    =     " Abstract Container for GUI Controls

*      CONTAINER_NAME =

       importing

         R_SALV_TABLE   = lo_salv_table    " Basis Class Simple ALV Tables

       changing

         T_TABLE        = it_data

     ).

*    catch CX_SALV_MSG.    " ALV: General Error Class with Message

***

     lt_columns = lo_salv_table->GET_COLUMNS( )->GET( ).

*

*    LOOP AT  lt_columns ASSIGNING <lfs_columns>.

*

*    break developer.

*

*    ENDLOOP.

     lo_salv_table->DISPLAY( ).

   ENDMETHOD.

ENDCLASS.

class lcl_controller DEFINITION.

   PUBLIC SECTION.

     methods: main.

ENDCLASS.

class lcl_controller IMPLEMENTATION.

   method main.

     DATA: lo_view type REF TO lcl_view,

           lo_data TYPE REF TO LCL_DATA .

     CREATE OBJECT: lo_data, lo_view.

     break developer.

     IF lo_view->START( ) Eq abap_true.

**get the data

       lo_data->SELECT_DATA( s_vbeln[] ).

       lo_view->DISPLAY(

         changing

           IT_DATA = lo_data->GT_OUTPUT

       ).

     ENDIF.

   ENDMETHOD.

ENDCLASS.

INITIALIZATION.

START-OF-SELECTION.

   break developer.

   DATA: lo_controller type REF TO lcl_controller.

   CREATE OBJECT lo_controller.

   lo_controller->MAIN( ).

1 ACCEPTED SOLUTION

SuhaSaha
Advisor
Advisor
0 Kudos

Hello Solen,

Using ABAP screens you cannot achieve 100% MVC. So you have to use workarounds like creating the screen in a FuGr, Global program & then calling it. If you do so, then all the standard behaviour of the screens may not be available.

But one issue when you execute the report and press GO BACK standard button it doesnot come back to your selection screen but way to your code.

Yes, because it returns to the calling position which is the code in your case. For e.g., if you create a transaction for this report & then it'll return to the main/SAP menu. This is a known problem

The trick here is to put the CALL SELECTION-SCREEN statement in an endless loop e.g., DO...ENDDO.

I don't quite like the idea of introducing the infinite loop in your code. So i visualize the report to be my view - displaying the screen, ALV etc. - and program accordingly.

A few interesting blog(s) you can refer to are -

  • Read Matthew's comment on how to trigger WD apps from your program -

BR,

Suhas

11 REPLIES 11

SuhaSaha
Advisor
Advisor
0 Kudos

Hello Solen,

Using ABAP screens you cannot achieve 100% MVC. So you have to use workarounds like creating the screen in a FuGr, Global program & then calling it. If you do so, then all the standard behaviour of the screens may not be available.

But one issue when you execute the report and press GO BACK standard button it doesnot come back to your selection screen but way to your code.

Yes, because it returns to the calling position which is the code in your case. For e.g., if you create a transaction for this report & then it'll return to the main/SAP menu. This is a known problem

The trick here is to put the CALL SELECTION-SCREEN statement in an endless loop e.g., DO...ENDDO.

I don't quite like the idea of introducing the infinite loop in your code. So i visualize the report to be my view - displaying the screen, ALV etc. - and program accordingly.

A few interesting blog(s) you can refer to are -

  • Read Matthew's comment on how to trigger WD apps from your program -

BR,

Suhas

0 Kudos

Suhas

You are a great help my friend

Thanks for you reply

Its useful

Appreciate it

Havent thought to put inside a en endless loop

i will read all these links

Private_Member_7726
Active Contributor

Hi,

Don't let this discourage you, but the thing I don't like about many reports implemented using OO Abap most is that I have to scroll up and down countless times just to figure out the flow of a trivial report.

lcl_data->select_data( ) is not utilizing rs_vbeln but rather s_vblen... oh, the "power" of global things I cringed looking at the all public lcl_data (don't really know why) and the FOR ALL ENTRIES...

Maybe it just takes some getting used to time, but I honestly doubt the utility of programming reports this way. This report will not support being SUBMITted and being planned as a SM37 batch job, will it?

cheers

Jānis

Oh, and forgot to answer the actulal question: a WHILE lo_view->START( ) Eq abap_true instead of IF should loop the selection-screen nicely, provided of course you add the user (exit) command processing and return false when it's time to exit.

Message was edited by: Jānis B

former_member196098
Participant
0 Kudos

Here is the complete code that works fine!!!

Thanks to your ideas:

OO ALV

*&---------------------------------------------------------------------*

*& Report  ZZ_SOLEN_FIRST

*&

*&---------------------------------------------------------------------*

*&

*&

*&---------------------------------------------------------------------*

REPORT ZZ_SOLEN_FIRST.

DATA: gv_vbeln type vbap-Vbeln.

***Screen

SELECTION-SCREEN: BEGIN OF SCREEN 100 TITLE t-004.

SELECTION-SCREEN: BEGIN OF block aa WITH FRAME TITLE t-001.

SELECT-OPTIONS: s_vbeln FOR gv_vbeln.

SELECTion-SCREEN: END OF block aa.

SELECTion-SCREEN: END OF SCREEN 100.

*****DATA Layer

class lcl_data DEFINITION.

   PUBLIC SECTION.

     TYPES: BEGIN OF ty_out,

       vbeln type vbap-vbeln,

       posnr type vbap-posnr,

       matnr type vbap-matnr,

       vkorg type vbak-vkorg,

       END OF ty_out

       .

     TYPES: tt_out TYPE STANDARD TABLE OF ty_out.

     TYPES: gr_vbeln TYPE RANGE OF vbap-vbeln.

     DATA: gt_output TYPE tt_out.

     methods: constructor,

              select_data IMPORTING VALUE(rs_vbeln) TYPE gr_vbeln.

     .

ENDclass.

class lcl_data IMPLEMENTATION.

   method constructor.

     clear GT_OUTPUT.

   ENDMETHOD.

   method select_data.

     DATA: lt_vbak type SORTED TABLE OF vbak WITH UNIQUE KEY vbeln.

     FIELD-SYMBOLS: <lfs_output> like LINE OF gt_output,

                    <lfs_vbak> like LINE OF lt_vbak

                    .

     select vbeln posnr matnr from vbap

       INto TABLE

        GT_OUTPUT

       where vbeln in S_VBELN

       .

     IF sy-SUBRC EQ 0.

       select * from vbak

         INTO TABLE lt_vbak

         FOR ALL ENTRIES IN  GT_OUTPUT

         where vbeln = GT_OUTPUT-vbeln

         .

       LOOP AT gt_output ASSIGNING <lfs_output>.

         READ TABLE lt_vbak ASSIGNING <lfs_vbak>

         with TABLE KEY vbeln = <lfs_output>-vbeln.

         IF sy-Subrc eq 0.

           <lfs_output>-vkorg = <lfs_vbak>-VKORG.

         ENDIF.

       ENDLOOP.

     ENDIF.

   ENDMETHOD.

ENDCLASS.

****Display

class lcl_view DEFINITION.

   PUBLIC SECTION.

     methods: start RETURNING VALUE(rv_return_flag) type abap_bool.

     METHODS: display CHANGING it_data TYPE STANDARD TABLE.

ENDCLASS.

class lcl_view IMPLEMENTATION.

   METHOD start.

     call SELECTION-SCREEN 100.

     IF sy-subrc EQ 0.

       rv_return_flag = abap_true.

     ENDIF.

   endmethod.

   method display.

     DATA: lo_salv_table type REF TO CL_SALV_TABLE,

           lt_columns TYPE SALV_T_COLUMN_REF.

     FIELD-SYMBOLS: <lfs_columns> like LINE OF lt_columns.

     CL_SALV_TABLE=>FACTORY(

*    exporting

*      LIST_DISPLAY   = IF_SALV_C_BOOL_SAP=>FALSE    " ALV Displayed in List Mode

*      R_CONTAINER    =     " Abstract Container for GUI Controls

*      CONTAINER_NAME =

       importing

         R_SALV_TABLE   = lo_salv_table    " Basis Class Simple ALV Tables

       changing

         T_TABLE        = it_data

     ).

*    catch CX_SALV_MSG.    " ALV: General Error Class with Message

***

     lt_columns = lo_salv_table->GET_COLUMNS( )->GET( ).

*

*    LOOP AT  lt_columns ASSIGNING <lfs_columns>.

*

*    break developer.

*

*    ENDLOOP.

     lo_salv_table->DISPLAY( ).

   ENDMETHOD.

ENDCLASS.

class lcl_controller DEFINITION.

   PUBLIC SECTION.

     methods: main.

ENDCLASS.

class lcl_controller IMPLEMENTATION.

   method main.

     DATA: lo_view type REF TO lcl_view,

           lo_data TYPE REF TO LCL_DATA .

     CREATE OBJECT: lo_data, lo_view.

     break developer.

*    while lo_view->START( ) eq abap_true.

***get the data

*      lo_data->SELECT_DATA( s_vbeln[] ).

*

*      lo_view->DISPLAY(

*        changing

*          IT_DATA = lo_data->GT_OUTPUT

*      ).

*

*    ENDWHILE.

     do.

       if lo_view->START( ) eq abap_true.

***get the data

         lo_data->SELECT_DATA( s_vbeln[] ).

         lo_view->DISPLAY(

           changing

             IT_DATA = lo_data->GT_OUTPUT

         ).

       else.

         return.

       ENDIF.

     ENDDO.

   ENDMETHOD.

ENDCLASS.

class lcl_test_submit DEFINITION.

   PUBLIC SECTION.

     TYPES: tr_vbeln TYPE RANGE OF vbap-vbeln.

     data: lt_list type table_abaplist.

     methods: test_submit IMPORTING VALUE(ir_vbeln) type tr_vbeln

                          EXCEPTIONS submit_failed

                                     no_data_found

       .

ENDCLASS.

class lcl_test_submit IMPLEMENTATION.

   method test_submit.

  submit ZZ_SOLEN_FIRST

   with s_vbeln in ir_vbeln

   exporting list to memory and return

     .

***Get the list from the memory

    call function 'LIST_FROM_MEMORY'

       tables

         listobject = lt_list

       exceptions

         not_found  = 1

         others     = 2.

     if sy-subrc <> 0.

       raise submit_failed.

     endif.

     if lt_list is initial.

       raise no_data_found.

     endif.

   ENDMETHOD.

ENDCLASS.

INITIALIZATION.

START-OF-SELECTION.

   break developer.

   DATA: lo_controller type REF TO lcl_controller.

****Testing the Main

   CREATE OBJECT lo_controller.

   lo_controller->MAIN( ).

 

0 Kudos

Hi Janis

THanks mate

I will test the submit now and background too

and get back to you

Better to test by code and proove it.

Cheers

0 Kudos

Janis

I tested

Submit didnot work with this code!!

That proves that its not the best solution if there needs to be submit or execute in background

Another way is to try to wrap this code inside a Function Module

will that be better?

0 Kudos

Hi,

I'll try read up and experiment a bit, but I'm afraid there will be no other way than letting ABAP run-time environment to handle the classic selection screen and the associated reporting events (meaning, no direct CALL SELECTION-SCREEN in the class). But the logic of the AT SELECTION-SCREEN could still be nicely wrapped in the methods.

cheers

Jānis

0 Kudos

I set myself a modest goal: first see if it is possible to determine somehow if the "call mode" was entered via SUBMIT statement (sy-calld, sy-cprog is not enough to do the trick). After looking at and debugging RSDBRUNT, I feel that, even if I could do it via some arcane logic gleaned from RSDBRUNT, the gain of "encapsulating" CALL SELECTION-SCREEN is not worth the risk of potential incompatibility and maintenance effort, should SAP change some of their internal stuff.

I'm no MVC specialist, but i feel the selection screen logic and call shouldn't even be a part of C, much less the V. MVC should not depend on selection screen or on other way of getting selection criteria. The C->main( ) should take in as input/changing parameters (or even as an instance of some lcl_selection_criteria class) the selection criteria, and the selection screen events logic should be wrapped as a separate class entirely, leaving ABAP run-time to do the screen call. Only if MVC is separated from selection screen is there a hope, without having to change the logic, to move MVC into global classes for reuse in elsewhere in the system.

cheers

Jānis

0 Kudos

Yes I agree with you Janis

For selection screens we need to wait up for oo abap to come up with a better way

0 Kudos

I think Abap still needs some enhacements to enforce some patterns

Like in the GUI itself

Webdynpro is a great response but thats more like a framework rather then abp way

0 Kudos

Janis you gave me a good idea to create a post in MVC

As much as i undertsand

Its worth to investigate