Wednesday, February 1, 2017

Multiple ALVs with Different Header

In the following example we have prepared two ALV Grid report in one single screen. There are two custom screens – one is for finished goods materials and another is for Raw materials. We also have mentioned two different header texts by using the Layout. Step by step approach is as follows:

1. At first create a report and create a custom screen (9000) without modifying the standard one.


2. Go to Layout and then create the custom containers (here 2 is in our example).


3. Now create the PBO & PAI modules at the custom screen.


4. In PBO we are creating custom container, ALV grid & calling the ALV grid method along with PF status & Title Bar.





5. In PAI the BACK, EXIT & CANCEL buttons are activated.


The detailed coding is as follows.

REPORT zsr_test NO STANDARD PAGE HEADING.

TABLESmara.

"-General Material Data
TYPESBEGIN OF ty_mara,
         matnr TYPE mara-matnr,
         ersda TYPE mara-ersda,
         mtart TYPE mara-mtart,
       END OF ty_mara.
DATAwa_mara TYPE ty_mara,
      it_mara TYPE TABLE OF ty_mara.

"-Material Descriptions
TYPESBEGIN OF ty_makt,
         matnr TYPE makt-matnr,
         maktx TYPE makt-maktx,
       END OF ty_makt.
DATAwa_makt TYPE ty_makt,
      it_makt TYPE TABLE OF ty_makt.

"-Output Table
TYPESBEGIN OF ty_out,
         matnr TYPE mara-matnr,
         maktx TYPE makt-maktx,
         ersda TYPE mara-ersda,
         mtart TYPE mara-mtart,
       END OF ty_out.
DATAwa_out TYPE ty_out,
      it_fg  TYPE TABLE OF ty_out"-Finished Goods Table
      it_rm  TYPE TABLE OF ty_out"-Raw Materials Table

"-Field Catalouge
DATAwa_fcat TYPE lvc_s_fcat,
      it_fcat TYPE TABLE OF lvc_s_fcat.

"-Custom Container Object
DATAob_cont_fg TYPE REF TO cl_gui_custom_container,
      ob_cont_rm TYPE REF TO cl_gui_custom_container.

"-ALV Grid Object
DATAob_grid_fg TYPE REF TO cl_gui_alv_grid,
      ob_grid_rm TYPE REF TO cl_gui_alv_grid.

"-Layout
DATAwa_lay_fg TYPE lvc_s_layo,
      wa_lay_rm TYPE lvc_s_layo,
      ok_code   TYPE sy-ucomm.

INITIALIZATION.
  SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
  SELECT-OPTIONS   s_ersda FOR mara-ersda OBLIGATORY.
  SELECTION-SCREEN END OF BLOCK b1.

CLASS cl_material DEFINITION.
  PUBLIC SECTION.
    METHODS:
      get_material,
      prepare_output,
      fieldcat.
ENDCLASS.

CLASS cl_material IMPLEMENTATION.
  METHOD get_material.
    IF s_ersda[] IS NOT INITIAL.
      SELECT matnr ersda mtart
        FROM mara INTO TABLE it_mara
        WHERE ersda IN s_ersda
          AND mtart IN 'FERT''ROH' ).

      "-FERT - Finished Goods
      "-ROH  - Raw Materials

      IF sy-subrc 0.
        SORT it_mara BY matnr.
        SELECT matnr maktx
          FROM makt INTO TABLE it_makt
          FOR ALL ENTRIES IN it_mara
          WHERE matnr it_mara-matnr.

        IF sy-subrc 0.
          SORT it_makt BY matnr.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDMETHOD.

  METHOD prepare_output.
    IF it_mara IS NOT INITIAL.
      LOOP AT it_mara INTO wa_mara.
        READ TABLE it_makt INTO wa_makt
        WITH KEY matnr wa_mara-matnr
        BINARY SEARCH.
        IF sy-subrc 0.
          wa_out-maktx wa_makt-maktx.
        ENDIF.
        wa_out-matnr wa_mara-matnr.
        wa_out-ersda wa_mara-ersda.
        wa_out-mtart wa_mara-mtart.

        IF wa_out-mtart 'FERT'.
          APPEND wa_out TO it_fg.         "-Finished Goods Table
          CLEARwa_outwa_marawa_makt.

        ELSE.
          APPEND wa_out TO it_rm.         "-Raw Materials Table
          CLEARwa_outwa_marawa_makt.
        ENDIF.
      ENDLOOP.
    ENDIF.
    FREEit_marait_makt.
  ENDMETHOD.

  METHOD fieldcat.

    "-Creating Field Catalouge
    REFRESH it_fcat.
    DATAlv_col TYPE VALUE 0.
    lv_col            lv_col + 1.
    wa_fcat-col_pos   lv_col.
    wa_fcat-fieldname 'MATNR'.
    wa_fcat-reptext   'Material Code'.
    APPEND wa_fcat TO it_fcat.
    CLEAR wa_fcat.

    lv_col            lv_col + 1.
    wa_fcat-col_pos   lv_col.
    wa_fcat-fieldname 'MAKTX'.
    wa_fcat-reptext   'Description'.
    APPEND wa_fcat TO it_fcat.
    CLEAR wa_fcat.

    lv_col            lv_col + 1.
    wa_fcat-col_pos   lv_col.
    wa_fcat-fieldname 'ERSDA'.
    wa_fcat-reptext   'Created On'.
    APPEND wa_fcat TO it_fcat.
    CLEAR wa_fcat.

    lv_col            lv_col + 1.
    wa_fcat-col_pos   lv_col.
    wa_fcat-fieldname 'MTART'.
    wa_fcat-reptext   'Material Type'.
    APPEND wa_fcat TO it_fcat.
    CLEAR wa_fcat.

    "-Creating Layout
    wa_lay_fg-zebra      'X'.
    wa_lay_fg-cwidth_opt 'X'.
    wa_lay_fg-grid_title 'Finished Goods Materials'.
    wa_lay_rm-zebra      'X'.
    wa_lay_rm-cwidth_opt 'X'.
    wa_lay_rm-grid_title 'Raw Materials'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  DATAob_material TYPE REF TO cl_material.
  CREATE OBJECT ob_material.
  CALL METHODob_material->get_material,
               ob_material->prepare_output,
               ob_material->fieldcat.
  CALL SCREEN 9000.                  "-Calling Custom Screen

*&---------------------------------------------------------------------*
*&      Module  STATUS_9000  OUTPUT
*&---------------------------------------------------------------------*
*       PBO of 9000
*----------------------------------------------------------------------*
MODULE status_9000 OUTPUT.
  SET PF-STATUS 'PF_9000'.
  SET TITLEBAR 'MAT'.

  PERFORM finished_goods_alv.
  PERFORM raw_materials_alv.

ENDMODULE.
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_9000  INPUT
*&---------------------------------------------------------------------*
*       PAI of 9000
*----------------------------------------------------------------------*
MODULE user_command_9000 INPUT.

  IF   ok_code 'BACK'
    OR ok_code 'EXIT'
    OR ok_code 'CANCEL'.
    FREEob_cont_fgob_grid_fgob_cont_rmob_grid_rm,
          it_fcatit_fgit_rm.
    LEAVE TO SCREEN 0.
  ENDIF.

ENDMODULE.
*&---------------------------------------------------------------------*
*&      Form  FINISHED_GOODS_ALV
*&---------------------------------------------------------------------*
*       ALV of FG
*----------------------------------------------------------------------*
FORM finished_goods_alv .
  CREATE OBJECT ob_cont_fg
    EXPORTING
      container_name 'CONT_FG'"-Creating Container
  "-In layout CONT_FG name is given

  CREATE OBJECT ob_grid_fg
    EXPORTING
      i_parent ob_cont_fg"-Creating ALV Grid

  "-ALV Grid Display Method
  CALL METHOD ob_grid_fg->set_table_for_first_display
    EXPORTING
      is_layout       wa_lay_fg
    CHANGING
      it_fieldcatalog it_fcat
      it_outtab       it_fg.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  RAW_MATERIALS_ALV
*&---------------------------------------------------------------------*
*       ALV of RM
*----------------------------------------------------------------------*
FORM raw_materials_alv .
  CREATE OBJECT ob_cont_rm
    EXPORTING
      container_name 'CONT_RM'"-Creating Container
  "-In layout CONT_RM name is given

  CREATE OBJECT ob_grid_rm
    EXPORTING
      i_parent ob_cont_rm"-Creating ALV Grid

  "-ALV Grid Display Method
  CALL METHOD ob_grid_rm->set_table_for_first_display
    EXPORTING
      is_layout       wa_lay_rm
    CHANGING
      it_fieldcatalog it_fcat
      it_outtab       it_rm.
ENDFORM.

Output.



Saturday, December 31, 2016

Dynamic Footer Window

In the last article we have created a simple Smart Form which displays a list of POs based on the date range. We found a problem that the form is generated with lot of blank spaces after the main window table. Now we want to utilize that space by configuring the footer window dynamically. To do this we have to pass Event inside the Table of Main window. Step by step approach is as follows.

Right click on the Table and create a folder. Go to Event TAB and configure like follows.

Go to Condition (Only before end of main window).

Now go to the Footer window which had already been created as the Final window. Change it to the Secondary Window.

Go to Condition (Only after end of main window).

Now check the Main window area. The last line should be one the same line of page and the header will come at the top of page from the second page.


Execute the report again to get the required output.






Thursday, December 29, 2016

Simple Smart Form

T-code for smart form is SMARTFORMS. Various business processes need a standard form by which the business can be run. Example of this kind of form is invoice, purchase orders, sales order details, delivery notes etc. We see that there are various formats of invoices between various retail shops. It means each and every organization uses a unique format of forms. Smart Form is one of the tools of SAP which fulfils this requirement. There is another tool for this and that is SAP Script. SAP script was the only one tool before release 4.6 and now from that release we have two options for the forms.

In the following example we have demonstrated a simple smart form which prints Purchase Order list based on the creation date at the selection screen. We can write a complete program inside a smart form. But in this example we have created a driver program for that.

Smart form always generates a function module while activating into the system. Now this system generated function module is dependent on the system. It means if we transport the form into development to quality system then the name of the function module gets changed. So to avoid naming conflict we can produce the name at run time and then we can call that by a variable. To achieve this we have function module SSF_FUNCTION_MODULE_NAME. It produces the FM for the form into a variable. After that we call that variable as FM.

We are passing an internal table from the driver program to the form. To do this we need to create a custom structure in DDIC. The internal table for the program and smart form will hold this DB structure.


















The driver program is as follows.

REPORT zsr_test.

TABLESekko.
TYPES:
  BEGIN OF ty_ekko,
    ebeln TYPE ekko-ebeln,
    aedat TYPE ekko-aedat,
  END OF ty_ekko.

DATA:
  wa_ekko   TYPE ty_ekko,
  it_ekko   TYPE TABLE OF ty_ekko,
  lw_ekpo   TYPE zsr_test,
  lt_ekpo   TYPE TABLE OF zsr_test,
  wa_ekpo   TYPE zsr_test,
  it_ekpo   TYPE TABLE OF zsr_test,
  date_low  TYPE sy-datum,
  date_high TYPE sy-datum.

INITIALIZATION.
  SELECT-OPTIONSs_date FOR ekko-aedat.

START-OF-SELECTION.
  PERFORM get_po_details.
  PERFORM call_smart_form.

*&---------------------------------------------------------------------*
*&      Form  GET_PO_DETAILS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_po_details .

  SELECT ebeln aedat
    FROM ekko INTO TABLE it_ekko
    WHERE aedat IN s_date.

  IF sy-subrc 0.
    date_low s_date-low.
    date_high s_date-high.

    SORT it_ekko BY aedat.
    SELECT ebeln ebelp txz01
           matnr menge meins
      FROM ekpo INTO TABLE lt_ekpo
      FOR ALL ENTRIES IN it_ekko
      WHERE ebeln it_ekko-ebeln
        AND menge NE 0.

    IF sy-subrc 0.

      LOOP AT lt_ekpo INTO lw_ekpo.
        AT NEW ebeln.
          wa_ekpo-ebeln lw_ekpo-ebeln.
        ENDAT.

        wa_ekpo-ebelp lw_ekpo-ebelp.
        wa_ekpo-txz01 lw_ekpo-txz01.
        wa_ekpo-menge lw_ekpo-menge.
        wa_ekpo-meins lw_ekpo-meins.

        IF lw_ekpo-matnr IS NOT INITIAL.
          wa_ekpo-matnr lw_ekpo-matnr.
        ELSE.
          wa_ekpo-matnr '<Service PO>'.
        ENDIF.
        APPEND wa_ekpo TO it_ekpo.
        CLEARwa_ekpolw_ekpo.
      ENDLOOP.
    ENDIF.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  CALL_SMART_FORM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM call_smart_form .

  DATAlv_form_name TYPE rs38l_fnam.

  IF it_ekpo IS NOT INITIAL.
    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
      EXPORTING
        formname           'ZTEST'
      IMPORTING
        fm_name            lv_form_name
      EXCEPTIONS
        no_form            1
        no_function_module 2
        OTHERS             3.

    CALL FUNCTION lv_form_name
      EXPORTING
        date_low         date_low
        date_high        date_high
      TABLES
        it_ekpo          it_ekpo
      EXCEPTIONS
        formatting_error 1
        internal_error   2
        send_error       3
        user_canceled    4
        OTHERS           5.
  ENDIF.

ENDFORM.

Now go to SMARTFORMS and create a simple form step by step. At first we import all the variables, structure & table into Form Interface.


After that we create the variables, structure or internal tables inside Global Definition.


Now we create the nodes one by one at first page. The first page will contain a header window, main window & a footer window. The header will be a secondary window which holds the condition of displaying at first page. The main is the main window which is mandatory for any page. The footer will be the final window which comes after finishing of every window.

The HEADER Part which holds the Condition - Only first page:


Now create a template by right clicking on the Header Window.


Now we create Logo, Header & body text by right clicking on the template.


Here we have to mention the position in Output Structure. (1,1) means 1st row & 1st column. Similarly (2,1) means 2nd row & 1st column. Similarly we are creating the following.






The MAIN Part:

In the main part we have to create a table to display item wise PO details.

Table contains a structure which needs to be designed at table painter.




Now table always has a loop so we need to loop into work area in the data section.


The header must come each and every page.

In the main the serial number will not come for different line items of same PO. So we have created code inside the loop and also we are changing the format of Item numbers.



Based on this condition the text will come.

All of the texts are populated by hard coded text or variable text. Since table contains different variable texts which are populated by clicking Field List (mark in red) and then drag and drop the particular field.

Now the Total calculation will be done at footer level of the table. This footer will come only at the end of the table.

In this way we create a table inside the main window. Now it’s time to create a footer window. Right click on the page and create a window named Footer Window.

The FOOTER Part:

We have created the footer window as a final window.

It has a condition that it will trigger at the last page after the end of main.

We create a template here by which the footer information will be displayed.

Now we create another small window which will display only Page number. The window is at the right last location of any page. So it will be a Secondary window which contains only one text field.

The page number is populated by system fields. Current page = SFSY-PAGE & Total page = SFSY-FORMPAGES. Just drag and drop to populate the text.

Now we need to create a second page which holds the copy of Main, Footer & Page number window. If the line item exceeds the first page then it will come at second page. The main window of second page will start from the top of the page.



Now execute the report and mention the date range. It will generate the following Smart form.




The output comes by one page. Now we are going to generate more than one page by expanding the date range.







The problem is that the Footer window always captures a fixed height in every page. We shall sort out this by next article.