Skip to end of metadata
Go to start of metadata

List of all pages

Pages at first level

This page is solely intended to classify pages which:

  • can run in background (no User Interaction)
  • can run in all ABAP-based systems (S/4, C/4, R/3, etc.) - any version (some codes may not run on old or recent systems)

List of all pages

Pages at first level

List of all pages

Pages at first level

Description: Field Symbol can hold run time object of type any and Runtime Type identification which is part of Runtime Type services can help us to identify the type of objects at runtime, including dictionary types and classes / objects.

Below is the code snippet which will explain you the use of Field symbol at run time and different way to cast the data objects type and the usage of RTTI.

Field symbols can be declared with specific types or can be declared as generic type

Part I:  Generically typed field symbols will have the run time type based on the 'type of data object assigned'.

For e.g if you have following structure defined in your program

Step 1)  

DATA: BEGIN OF spfli_key,
        carrid TYPE s_carr_id,
        connid TYPE s_conn_id,
      END OF spfli_key.
 

Step 2)

and if you want to identify the components of the structure or type of the structure at runtime, then

DATA: descr_ref TYPE REF TO cl_abap_structdescr,
      wa_comp TYPE abap_compdescr.
 

cl_abap_structdescr is the class defined by SAP under RTTI to identify the structure and components of the structure at runtime.

Step 3) 

At some part of your program, you may assign any strucutre to field symbol as below.

spfli_key-carrid = 'AA'.
spfli_key-connid = 800.

ASSIGN spfli_key TO <fs_any>.
 

Step 4)  call the static method of t he class typedescr, and import the field symbol created. Loop throgh the components and identify the name of the component.

descr_ref ?= cl_abap_typedescr=>describe_by_data( <fs_any> ).

WRITE: ' Structure components at run time :' .
SKIP 2.
WRITE: ' Field symbol will hold the data object assigned :' .

LOOP AT  descr_ref->components INTO wa_comp.
  WRITE: wa_comp-name.
ENDLOOP.

UNASSIGN <fs_any>.
 

Part II:  Generically typed field symbols can be casted at runtime by using the keyword, 'CASTING TYPE'. Data object assigned to the field symbol, will be type casted based on the runtime type specified.

Step 1: Follow the steps as before. and cast the field symbol defined as any to  any particular type at runtime, using 'CASTING TYPE' .

ASSIGN obj_spfli TO <fs_any> CASTING TYPE spfli_type.

descr_ref ?= cl_abap_typedescr=>describe_by_data( <fs_any> ).

WRITE: ' Field symbol will read the data object assign as per the casted type :' .
SKIP 2.

LOOP AT  descr_ref->components INTO wa_comp.
  WRITE: wa_comp-name.
ENDLOOP.
 
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*----this program is aimed for converting a character into currency format

DATA: v_dcpfm    TYPE usr01-dcpfm,
      v_amount   TYPE bseg-wrbtr,
      v_char(16) TYPE c.

SELECT SINGLE dcpfm FROM usr01
                    INTO v_dcpfm
                   WHERE bname = sy-uname.
IF v_dcpfm = 'X'.
*-- decimal point is '.' and thousands separator is ','
  TRANSLATE v_char USING ', '.
  CONDENSE v_char NO-GAPS.
  v_amount = v_char.
ELSEIF v_dcpfm = 'Y'.
*-- decimal point is ',' and thousands separator is '.'
  TRANSLATE v_char USING '. '.
  CONDENSE v_char NO-GAPS.
  v_amount = v_char.
ELSE.
*-- decimal point is ',' and thousands separator is space
  CONDENSE v_char NO-GAPS.
  v_amount = v_char.
ENDIF.

we can also use this function module HRCM_STRING_TO_AMOUNT_CONVERT


List of all pages

Pages at first level

*-------------------------------------------------------*
*  report name
*-------------------------------------------------------*

REPORT zchange_of_case .

*-------------------------------------------------------*
*   selection screen parameters
*------------------------------------------------------*

PARAMETERS: P_STR TYPE CHAR100 .

*-------------------------------------------------------*
*      data declarations
*------------------------------------------------------*

DATA: STRING TYPE CHAR100 .

*-------------------------------------------------------*
*    initialization
*------------------------------------------------------*

INITIALIZATION .

P_STR = 'THIS IS THE TEST' .

*-------------------------------------------------------*
*  start of selection
*------------------------------------------------------*

START-OF-SELECTION .

CALL FUNCTION 'STRING_UPPER_LOWER_CASE'
  EXPORTING
    delimiter = ' '
    string1   = P_STR
  IMPORTING
    STRING    = STRING
  EXCEPTIONS
    NOT_VALID = 1
    TOO_LONG  = 2
    TOO_SMALL = 3
    OTHERS    = 4.

IF sy-subrc <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

*------output
	WRITE:/ STRING .

Go to SE37

Enter Name < NN_TEXT_CONVERT_PROPER>

Press Create Button

Enter Import & Export Variables as Type String

Enter Exceptions as      NOT_VALID

                                    TOO_LONG

                                    TOO_SMALL  
Create Source Code as Follows

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FUNCTION nn_text_convert_proper.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(STRING1)
*"  EXPORTING
*"     REFERENCE(STRING)
*"  EXCEPTIONS
*"      NOT_VALID
*"      TOO_LONG
*"      TOO_SMALL
*"----------------------------------------------------------------------

  DATA  :
        it_txts      TYPE TABLE OF string,  "Tabel for data storing
        wa_txts(100) TYPE c,                "Getting each words
        cp_text      TYPE string,           "Copying text
        nn_text      TYPE string.           "Result text

  cp_text = string1.
  SPLIT cp_text AT space INTO: TABLE it_txts.

  LOOP AT it_txts INTO wa_txts.
    PERFORM  change_case USING wa_txts.
    CONCATENATE nn_text wa_txts INTO nn_text SEPARATED BY space.
  ENDLOOP.
  CONDENSE nn_text.
*
  CASE sy-subrc.
    WHEN 0.
      string = nn_text.
      EXIT.
    WHEN 2.
      RAISE not_valid.
    WHEN 3.
      RAISE too_long.
    WHEN 4.
      RAISE too_small.
  ENDCASE.

ENDFUNCTION.

*in the perform part add code as follows (include lzpropertop)

FUNCTION-POOL zproper.                      "MESSAGE-ID ..

*&---------------------------------------------------------------------*
*&      Form  CHANGE_CASE
*&---------------------------------------------------------------------*
FORM change_case  USING  p_wa_txts.

  DATA : p_dem.

  p_dem = '&'.

  CALL FUNCTION 'STRING_UPPER_LOWER_CASE'
    EXPORTING
      delimiter = p_dem
      string1   = p_wa_txts
    IMPORTING
      string    = p_wa_txts
    EXCEPTIONS
      not_valid = 1
      too_long  = 2
      too_small = 3
      OTHERS    = 4.
ENDFORM.                    " CHANGE_CASE
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*----this is the report for concatenating 2 strings

REPORT  zconcatenate_fm                         .

DATA: string(100) TYPE c.

PARAMETERS: abc(15) TYPE c,
            bbc(15) TYPE c.

CALL FUNCTION 'STRING_CONCATENATE'
  EXPORTING
    string1   = abc
    string2   = bbc
  IMPORTING
    string    = string
  EXCEPTIONS
    too_small = 1
    OTHERS    = 2.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

WRITE:/ string.

*----------------------------------------------------------------*
*  this is the report for concatenating 3 strings
*--------------------------------------------------------------*
REPORT  zconcatenate_fm01   .

DATA: string(50) TYPE c.

PARAMETERS: p_strng1(15) TYPE c,
            p_strng2(15) TYPE c,
            p_strng3(15) TYPE c.

CALL FUNCTION 'STRING_CONCATENATE_3'
  EXPORTING
    string1   = p_strng1
    string2   = p_strng2
    string3   = p_strng3
  IMPORTING
    string    = string
  EXCEPTIONS
    too_small = 1
    OTHERS    = 2.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

WRITE:/ string.

Method 1

PARAMETERS inp(40) DEFAULT 'Habitación' LOWER CASE.

DATA: BEGIN OF uml,
  um1 VALUE 'ó',
  um1_e VALUE 'o',
  um2 VALUE 'ä',
  um2_e VALUE 'a',
  um7 VALUE 'ß',
  um7_e(2) VALUE 'ss',
 END OF uml.

FIELD-SYMBOLS: <h1_string>, <h2_string>.
DATA string TYPE string.
DATA outp(40).
DATA: zaehler TYPE i VALUE 1.

string = inp.

DO.
  ASSIGN COMPONENT zaehler OF STRUCTURE uml TO <h1_string>.
  IF sy-subrc  NE 0.
    EXIT.
  ENDIF.
  zaehler = zaehler + 1.
  ASSIGN COMPONENT zaehler OF STRUCTURE uml TO <h2_string>.
  IF sy-subrc  NE 0.
    MESSAGE e000(yp).
  ENDIF.
  IF string CA <h1_string>.
    sy-subrc = 0.
    WHILE sy-subrc = 0.
      REPLACE <h1_string> WITH <h2_string> INTO string.
    ENDWHILE.
  ENDIF.
  zaehler = zaehler + 1.
ENDDO.

WRITE: inp, / string.
 

Method 2

PARAMETERS inp(40) DEFAULT 'Habitación' LOWER CASE.

DATA: outtext TYPE char40 .

CALL FUNCTION 'SCP_REPLACE_STRANGE_CHARS'
  EXPORTING
    intext  = inp
  IMPORTING
    outtext = outtext.

WRITE:/ outtext.
 

This code explains that how we can find the length of a string using the oops class using Static and instance method.

The  "methods" statement declares or redefines an instance method "get_strlen".

Instance methods are linked to Objects.

To use instance methods,we have to create an object of the class.

By Instance method we can access all components of the own class without using a component selector.

REPORT ztest_prem
     NO STANDARD PAGE HEADING LINE-SIZE 255.

DATA:  string_in  TYPE string,
       len_out TYPE i.

*----------------------------------------------------------------------*
*       CLASS string_op DEFINITION
*----------------------------------------------------------------------*
CLASS string_op DEFINITION.

  PUBLIC SECTION.
    METHODS : get_strlen IMPORTING value(str1) TYPE string
                         EXPORTING value(len1) TYPE i.


    METHODS : constructor.


    CLASS-METHODS : write_len.

**The CLASS-METHODS statement declares a static method.
* With the class component selector (=>), static methods can be used independently of objects.
*By static methods, we can only access the static components of the class or its
*superclasses

ENDCLASS.                    "string_op DEFINITION

DATA :  inst TYPE REF TO string_op.

CREATE OBJECT inst.

string_in = 'Premraj'.

CALL METHOD inst->get_strlen     "Calling of Instance method.
EXPORTING
   str1 = string_in
IMPORTING
   len1 = len_out.

CALL METHOD string_op=>write_len.   "Calling of Staic method.

*----------------------------------------------------------------------*
*       CLASS string_op IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS string_op IMPLEMENTATION.

  METHOD get_strlen.
    len1 = strlen( str1 ).
  ENDMETHOD.                    "get_strlen

  METHOD write_len.
    WRITE : len_out.
  ENDMETHOD.                    "write_len

  METHOD constructor.
    WRITE : 'The length of String is :'.
  ENDMETHOD.                    "constructor

ENDCLASS.                    "string_op IMPLEMENTATION
 

Author: Jay Sadaram
Submitted: 11/07/2008
Description: In a SAP script I had some long text,which I was getting from Read_text function module. I had to split it and show in various lines. When the code was originally developed they were using the FM RKD_WORD_WRAP which splits to 3 lines Only, but my requirement was to have more than 10+ lines. So I developed a logic where with min changes you can adjust the number of characters to split to.. and kind of dynamic approach.

DATA: lv_len TYPE i,
      lv_z1 TYPE i,
      lv_z2 TYPE i,
      lv_z3 TYPE i,
      lv_z4 TYPE i,
      lv_z5 TYPE i,
      lv_z6 TYPE i,
      lv_z7 TYPE i,
      lv_last TYPE i,
      lv_offset(3) TYPE n.

lv_len = strlen( ztext ).
CLEAR: lv_offset.
lv_offset = lv_len / 7 .
lv_z1 = lv_offset.
lv_z2 = lv_z1 + 1.
lv_z3 = lv_z2 + lv_z1 + 1.
lv_z4 = lv_z3 + lv_z1 + 1.
lv_z5 = lv_z4 + lv_z1 + 1.
lv_z6 = lv_z5 + lv_z1 + 1.
lv_z7 = lv_z6 + lv_z1 + 1.
zoutline1 = ztext+0(lv_z1).
zoutline2 = ztext+lv_z2(lv_z1).
zoutline3 = ztext+lv_z3(lv_z1).
zoutline4 = ztext+lv_z4(lv_z1).
zoutline5 = ztext+lv_z5(lv_z1).
zoutline6 = ztext+lv_z6(lv_z1).
CHECK lv_len GT lv_z7.
lv_last = abs( lv_len - lv_z7 ).
zoutline7 = ztext+lv_z7(lv_last).
 

Here is a sample code where datatype 'N' accepts alphabets.

REPORT zconvert.
DATA :
w_date TYPE d , " Variable of type D
w_num(6) TYPE n . " Variable of type N

w_date = 'ABC123' .
MOVE w_date TO w_num .
SKIP 2 .
WRITE :25 w_num .

 In this case datatype 'N' accepts characters.





Factorial Calculation using Macro.

This program calculates the factorials of first 5 numbers using a macro.
Display the output in the following format using another macro.

Factorial of 1 is 1.
Factorial of 2 is 2.
Factorial of 3 is 6.
Factorial of 4 is 24.
Factorial of 5 is 120.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT zmacro.
* Work variables
DATA:
  w_num TYPE i VALUE 1,                " First number
  w_num1 TYPE i VALUE 5,               " Last Number
  w_fact TYPE i VALUE 1.               " Factorial Value
* Definition of Macro to Perform Factorial of first 5 numbers
DEFINE factorial.
  while &1 <= &2.
    &3 = &3 * &1.
    output &1 &3.
    add 1 to &1.
  endwhile.
END-OF-DEFINITION.                     " DEFINITION FACTORIAL
* Definition of Macro to Display the factorial result
DEFINE output.
  write:/ 'Factorial of', &1,'is', &2.
END-OF-DEFINITION.                     " DEFINITION OUTPUT

factorial w_num w_num1 w_fact.

Author: Jatra Riwayanto
Submitted: 06.06.2007

Description:
There is a time that we need to encode our data before we save it to database table.
I try encoded and decoded string data using method IF_HTTP_UTILITY~DECODE_BASE64 and IF_HTTP_UTILITY~ENCODE_BASE64 in class CL_HTTP_UTILITY.

Here the snippet:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA: encoded   TYPE string,
      unencoded TYPE string.

START-OF-SELECTION.

  unencoded = 'This is test value'.
  WRITE: / 'Unencoded string:',  unencoded.

  encoded = cl_http_utility=>if_http_utility~encode_base64( unencoded = unencoded ).
  WRITE: / 'Encoded string:',  encoded.

  CLEAR: unencoded.
  unencoded = cl_http_utility=>if_http_utility~decode_base64( encoded = encoded ).
  WRITE: / 'Unencoded string:',  unencoded.

Result:

Author: JNN
Submitted: April 2nd 2014
Related Links:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT zz_buffer3.


CLASS lcx_buffer_error DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.                    "lcx_buffer_error DEFINITION


CLASS lcx_buffer_key_in_buffer DEFINITION INHERITING FROM lcx_buffer_error.
ENDCLASS.                    "lcx_buffer_key_in_buffer DEFINITION


CLASS lcx_iterator_error DEFINITION INHERITING FROM lcx_buffer_error.
ENDCLASS.


CLASS lcx_buffer_value_not_found DEFINITION INHERITING FROM lcx_buffer_error.
ENDCLASS.                    "lcx_buffer_value_not_found DEFINITION


INTERFACE lif_unit_test.
ENDINTERFACE.


*----------------------------------------------------------------------*
*       CLASS lcl_table_buffer DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_table_buffer DEFINITION CREATE PRIVATE FRIENDS lif_unit_test.


  PUBLIC SECTION.
    TYPES tt_fieldname TYPE STANDARD TABLE OF fieldname.
*   create a table buffer
    CLASS-METHODS factory
      IMPORTING iv_text TYPE csequence      " Unique ID, used for caching
                iv_value TYPE any           " any structure
                iv_key TYPE fieldname       " name of key field in structure
                it_keys TYPE tt_fieldname OPTIONAL  " (or all key fields) - not tested
      RETURNING value(ro_buffer) TYPE REF TO lcl_table_buffer
      RAISING lcx_buffer_error.
    METHODS put                             " put structure value in buffer
      IMPORTING iv_value TYPE any
      RAISING lcx_buffer_key_in_buffer .
    METHODS get                             " get value from buffer according to key
      IMPORTING iv_key TYPE simple
      EXPORTING ev_value TYPE data
      RAISING lcx_buffer_value_not_found.
    METHODS size                            " number of entries in buffer
      RETURNING value(rv_size) TYPE syindex.
    METHODS isempty                         " is the buffer empty?
      RETURNING value(rv_empty) TYPE flag.
    METHODS contains_key                    " is there a value with this key in buffer?
      IMPORTING iv_key TYPE simple
      RETURNING value(rv_idx) TYPE syindex.
    METHODS contains                       " is this value in the buffer ?
      IMPORTING iv_value TYPE data
      RETURNING value(rv_idx) TYPE syindex.
    METHODS delete                         " remove value with key from buffer
      IMPORTING iv_key TYPE simple
      RETURNING value(rv_found) TYPE flag.
    METHODS clear.                          " clear/empty the buffer
    CLASS-METHODS free
      IMPORTING iv_text TYPE csequence OPTIONAL.


  PRIVATE SECTION.
    DATA mv_key TYPE fieldname.
    DATA mr_buffer TYPE REF TO data.
    TYPES: BEGIN OF ts_map,
             name TYPE string,
             buffer TYPE REF TO lcl_table_buffer,
           END OF ts_map.
    CLASS-DATA gt_map TYPE SORTED TABLE OF ts_map
      WITH UNIQUE KEY name.
    METHODS constructor
      IMPORTING it_keys TYPE tt_fieldname
                is_struct TYPE any
      RAISING lcx_buffer_error.
ENDCLASS.


*----------------------------------------------------------------------*
*       CLASS lcl_table_buffer IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_table_buffer IMPLEMENTATION.


  METHOD factory.
    DATA ls_map TYPE ts_map.
    DATA lt_keys TYPE tt_fieldname.
    IF it_keys IS INITIAL.
      APPEND iv_key TO lt_keys.
    ELSE.
      lt_keys = it_keys.
    ENDIF.
    READ TABLE gt_map INTO ls_map
      WITH KEY name = iv_text.
    IF sy-subrc NE 0.
      CREATE OBJECT ls_map-buffer
        EXPORTING it_keys = lt_keys
                  is_struct = iv_value.
      ls_map-name = iv_text.
      INSERT ls_map INTO TABLE gt_map.
    ENDIF.
    ro_buffer = ls_map-buffer.
  ENDMETHOD.                    "create


  METHOD constructor.
    FIELD-SYMBOLS <lv_comp> TYPE any.
    FIELD-SYMBOLS <ls_struct> TYPE any.
    FIELD-SYMBOLS <lv_key> TYPE fieldname.
    super->constructor( ).
    LOOP AT it_keys ASSIGNING <lv_key>.
      AT FIRST.
        mv_key = <lv_key>.
      ENDAT.
      ASSIGN COMPONENT <lv_key> OF STRUCTURE is_struct TO <lv_comp>.
      CHECK sy-subrc NE 0.
      RAISE EXCEPTION TYPE lcx_buffer_error.
    ENDLOOP.
    CREATE DATA mr_buffer LIKE SORTED TABLE OF is_struct
      WITH UNIQUE KEY (it_keys).
  ENDMETHOD.


  METHOD free.
    DATA ls_map TYPE ts_map.
    READ TABLE gt_map INTO ls_map
      WITH KEY name = iv_text.
    IF sy-subrc EQ 0.
      DELETE gt_map INDEX sy-index.
      FREE ls_map-buffer.
    ELSEIF iv_text IS INITIAL.
      CLEAR gt_map.
    ENDIF.
  ENDMETHOD.


  METHOD clear.
    CLEAR mr_buffer.
  ENDMETHOD.


  DEFINE assign_buffer.
    FIELD-SYMBOLS <lt_buffer> TYPE SORTED TABLE.
    ASSIGN mr_buffer->* TO <lt_buffer>.
    CHECK <lt_buffer> IS ASSIGNED.
  END-OF-DEFINITION.


  METHOD size.
    CLEAR rv_size.
    assign_buffer.
    rv_size = lines( <lt_buffer> ).
  ENDMETHOD.                    "size


  METHOD isempty.
    rv_empty = abap_true.
    assign_buffer.
    IF <lt_buffer> IS NOT INITIAL.
      rv_empty = abap_false.
    ENDIF.
  ENDMETHOD.                    "isEmpty


  METHOD contains_key.
*   Search for already buffered value
    CLEAR rv_idx.
    assign_buffer.
    READ TABLE <lt_buffer> TRANSPORTING NO FIELDS
      WITH TABLE KEY (mv_key) = iv_key.
    CHECK sy-subrc EQ 0.
    rv_idx = sy-tabix.
  ENDMETHOD.                    "contains_key


  METHOD contains.
*   Search for already buffered value
    CLEAR rv_idx.
    assign_buffer.
    READ TABLE <lt_buffer> TRANSPORTING NO FIELDS
      FROM iv_value.
    CHECK sy-subrc EQ 0.
    rv_idx = sy-tabix.
  ENDMETHOD.                    "contains

  METHOD get.
    FIELD-SYMBOLS <ls_data> TYPE any.
    assign_buffer.
    READ TABLE <lt_buffer> ASSIGNING <ls_data>
      WITH KEY (mv_key) = iv_key.
    IF sy-subrc NE 0.
*     Value was not found
      RAISE EXCEPTION TYPE lcx_buffer_value_not_found.
    ELSE.
      ev_value = <ls_data>.
    ENDIF.
  ENDMETHOD.                    "GET
  
  METHOD put.
*   Search for already buffered value
    FIELD-SYMBOLS <ls_data> TYPE any.
    assign_buffer.
    READ TABLE <lt_buffer> ASSIGNING <ls_data>
      FROM iv_value.
    IF sy-subrc EQ 0.
*     key was already in the buffer
      RAISE EXCEPTION TYPE lcx_buffer_key_in_buffer.
    ELSE.
*     Value was not found, insert:
      INSERT iv_value INTO TABLE <lt_buffer>.
    ENDIF.
  ENDMETHOD.                    "insert


  METHOD delete.
*   remove existing entry - not tested yet
    FIELD-SYMBOLS <ls_data> TYPE any.
    assign_buffer.
    DELETE TABLE <lt_buffer>
      WITH TABLE KEY (mv_key) = iv_key.
  ENDMETHOD.                    "insert
ENDCLASS.


*----------------------------------------------------------------------*
*       CLASS lcl_test DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_test DEFINITION FOR TESTING
  DURATION MEDIUM RISK LEVEL HARMLESS.
  PUBLIC SECTION.
    INTERFACES lif_unit_test.
  PRIVATE SECTION.
    CONSTANTS c_max_size TYPE i VALUE 1000.
    CONSTANTS c_text_save TYPE char40 VALUE 'SAVE_BUFFER_TEST'.
    DATA mv_sbook_size TYPE i.
    DATA mv_buffer_size TYPE i.
    DATA mt_sbook TYPE STANDARD TABLE OF sbook.
    DATA mv_start TYPE i.
    DATA mv_time TYPE i.
    DATA mi_timer TYPE REF TO IF_ABAP_RUNTIME.


    METHODS setup.
    METHODS without_buffer FOR TESTING.
    METHODS filling_buffer FOR TESTING.
    METHODS select_without_buffer
      RETURNING VALUE(rv_counter) TYPE i.
    METHODS select_with_buffer
      RETURNING VALUE(ro_buffer) TYPE REF TO lcl_table_buffer
      RAISING lcx_buffer_error.
    METHODS from_buffer
      RAISING lcx_buffer_error.
    METHODS start_timer.
    METHODS stop_timer RETURNING VALUE(rv_time) TYPE i.
    METHODS buffer_runtime FOR TESTING.
    METHODS save_buffer FOR TESTING.
    METHODS contains FOR TESTING.
ENDCLASS.                    "lcl_test DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_test IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_test IMPLEMENTATION.


  METHOD setup.
    DATA lt_customid TYPE STANDARD TABLE OF sbook-customid.
    SELECT * FROM sbook INTO TABLE mt_sbook
      UP TO c_max_size ROWS.
    SELECT customid FROM sbook
      INTO TABLE lt_customid
      FOR ALL ENTRIES IN mt_sbook
      WHERE carrid = mt_sbook-carrid
        AND connid = mt_sbook-connid
        AND fldate = mt_sbook-fldate
        AND bookid = mt_sbook-bookid.
      mv_buffer_size = lines( lt_customid ).
      mv_sbook_size = lines( mt_sbook ).
      mi_timer = cl_abap_runtime=>create_hr_timer( ).
    ENDMETHOD.                    "query_sbook


    METHOD start_timer.
      mv_start = mi_timer->get_runtime( ).
    ENDMETHOD.


    METHOD stop_timer.
      rv_time = mi_timer->get_runtime( ) - mv_start.
    ENDMETHOD.


    METHOD select_without_buffer.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      CLEAR rv_counter.
      LOOP AT mt_sbook INTO ls_sbook.
        SELECT SINGLE * FROM sbuspart INTO ls_sbuspart
          WHERE buspartnum = ls_sbook-customid.
        ADD 1 TO rv_counter.
      ENDLOOP.
    ENDMETHOD.


    METHOD without_buffer.
      DATA lv_counter TYPE i.
      lv_counter = select_without_buffer( ).
      cl_aunit_assert=>assert_equals( exp = mv_sbook_size
                                      act = lv_counter
                                      msg = 'WITHOUT_BUFFER error' ).
    ENDMETHOD.                    "without_buffer


    METHOD select_with_buffer.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      ro_buffer = lcl_table_buffer=>factory(
        iv_text = 'CUSTOMER_DETAILS'
        iv_value = ls_sbuspart      " structure
        iv_key = 'BUSPARTNUM' ).
      LOOP AT mt_sbook INTO ls_sbook.
        CHECK ro_buffer->contains_key( ls_sbook-customid ) EQ 0.
*       If we haven't saved it yet, get it and save it
        SELECT SINGLE * FROM sbuspart INTO ls_sbuspart
          WHERE buspartnum = ls_sbook-customid.
        ro_buffer->put( ls_sbuspart ).
      ENDLOOP.
    ENDMETHOD.


    METHOD filling_buffer.
      DATA lo_buffer TYPE REF TO lcl_table_buffer.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lv_counter TYPE i.
      TRY.
          lo_buffer = select_with_buffer( ).
          lv_counter = lo_buffer->size( ).
          cl_aunit_assert=>assert_equals( exp = mv_buffer_size
                                          act = lv_counter
                                          msg = 'WITH_BUFFER error' ).
        CATCH lcx_buffer_error INTO lx_error.
          cl_aunit_assert=>fail( msg = | WITH_BUFFER { lx_error->get_text( ) } |  ).
      ENDTRY.
    ENDMETHOD.                    "with_buffer


    METHOD from_buffer.
      DATA lo_buffer TYPE REF TO lcl_table_buffer.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lv_counter TYPE i.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      lo_buffer = lcl_table_buffer=>factory(
        iv_text = 'CUSTOMER_DETAILS'
        iv_value = ls_sbuspart      " structure
        iv_key = 'BUSPARTNUM' ).
      TRY.
          LOOP AT mt_sbook INTO ls_sbook.
            lo_buffer->get( ls_sbook-customid ).
            ADD 1 to lv_counter.
          ENDLOOP.
        CATCH lcx_buffer_error INTO lx_error.
          cl_aunit_assert=>fail( msg = | ITERATOR { lx_error->get_text( ) } |  ).
      ENDTRY.
    ENDMETHOD.


    METHOD buffer_runtime.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lv_time_from_buffer TYPE i.
      DATA lv_time_fill_buffer TYPE i.
      DATA lv_time_wo_buffer TYPE i.
      DATA lv_flag TYPE flag.
      start_timer( ).
      select_without_buffer( ).
      lv_time_wo_buffer = stop_timer( ).
      start_timer( ).
      TRY.
          select_with_buffer( ).
          lv_time_fill_buffer = stop_timer( ).
          start_timer( ).
          from_buffer( ).
          lv_time_from_buffer = stop_timer( ).
          IF lv_time_fill_buffer LT lv_time_wo_buffer.
            lv_flag = 'X'.
          ELSE.
            lv_flag = space.
          ENDIF.
          cl_abap_unit_assert=>assert_equals(
            exp = 'X'
            act = lv_flag
            level = if_aunit_constants=>tolerable
            msg = |RUN TIME fill buffer: { lv_time_fill_buffer } w/o buffer: { lv_time_wo_buffer } from buffer: { lv_time_from_buffer } | ).
        CATCH lcx_buffer_error INTO lx_error.
          cl_aunit_assert=>fail( msg = | RUN TIME { lx_error->get_text( ) } |  ).
      ENDTRY.
    ENDMETHOD.                    "with_buffer


    METHOD contains.
      DATA ls_sbuspart TYPE sbuspart.
      DATA lv_idx TYPE sytabix.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lo_buffer TYPE REF TO lcl_table_buffer.
      TRY.
          ls_sbuspart-buspartnum = '00002075'.
          lo_buffer = lcl_table_buffer=>factory(
            iv_text = c_text_save
            iv_value = ls_sbuspart
            iv_key = 'BUSPARTNUM' ).
          lo_buffer->put( ls_sbuspart ).
          lv_idx = lo_buffer->contains( ls_sbuspart ).
          cl_abap_unit_assert=>assert_equals(
            exp = 1
            act = lv_idx
            msg = 'LCL_TABLE_BUFFER->CONTAINS Error' ).
        CATCH lcx_buffer_error INTO lx_error.
          cl_aunit_assert=>fail( msg = | CONTAINS { lx_error->get_text( ) } |  ).
      ENDTRY.
    ENDMETHOD.


    METHOD save_buffer.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lo_first TYPE REF TO lcl_table_buffer.
      DATA lo_next TYPE REF TO lcl_table_buffer.
      TRY.
          lo_first = lcl_table_buffer=>factory(
            iv_text = c_text_save
            iv_value = ls_sbuspart
            iv_key = 'BUSPARTNUM' ).
          lo_next = lcl_table_buffer=>factory(
            iv_text = c_text_save
            iv_value = ls_sbuspart
            iv_key = 'BUSPARTNUM' ).
          cl_abap_unit_assert=>assert_equals(
            exp = lo_first
            act = lo_next
            msg = |LCL_TABLE_BUFFER=>FACTORY Cache Error: { c_text_save } | ).
        CATCH lcx_buffer_error INTO lx_error.
          cl_aunit_assert=>fail( msg = | SAVE_BUFFER { lx_error->get_text( ) } |  ).
      ENDTRY.
    ENDMETHOD.
  ENDCLASS.                    "lcl_test IMPLEMENTATION




  ENDCLASS.                    "lcl_test IMPLEMENTATION

 

An ABAP implementation of an associative array (aka symbol table or map)

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*----------------------------------------------------------------------*
REPORT zz_buffer.


*----------------------------------------------------------------------*
*       CLASS lcx_buffer_error DEFINITION
*----------------------------------------------------------------------*
CLASS lcx_buffer_error DEFINITION INHERITING FROM cx_static_check.
ENDCLASS.                    "lcx_buffer_error DEFINITION
*----------------------------------------------------------------------*
*       CLASS lcx_buffer_key_in_buffer DEFINITION
*----------------------------------------------------------------------*
CLASS lcx_buffer_key_in_buffer DEFINITION INHERITING FROM lcx_buffer_error.
ENDCLASS.                    "lcx_buffer_key_in_buffer DEFINITION
*----------------------------------------------------------------------*
*       CLASS lcx_buffer_value_not_found DEFINITION
*----------------------------------------------------------------------*
CLASS lcx_buffer_value_not_found DEFINITION INHERITING FROM lcx_buffer_error.
ENDCLASS.                    "lcx_buffer_value_not_found DEFINITION


*----------------------------------------------------------------------*
*       INTERFACE lif_entry DEFINITION
*----------------------------------------------------------------------*
INTERFACE lif_entry.
  METHODS find
    IMPORTING iv_key TYPE any
    RETURNING value(rv_found) TYPE flag.
  METHODS get
    EXPORTING value(ev_value) TYPE any.
ENDINTERFACE.                    "lif_entry DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_entry DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_entry DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    INTERFACES lif_entry.

    CLASS-METHODS factory
      IMPORTING iv_key TYPE any
                iv_value TYPE any
      RETURNING value(ri_entry) TYPE REF TO lif_entry.


  PROTECTED SECTION.
    DATA mr_key   TYPE REF TO data.
    DATA mr_value TYPE REF TO data.
    METHODS constructor
      IMPORTING iv_key TYPE any
                iv_value TYPE any.
ENDCLASS.                    "lcl_entry DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_entry IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_entry IMPLEMENTATION.


  METHOD constructor.
    FIELD-SYMBOLS <lv_ref> TYPE any.
    super->constructor( ).
    CREATE DATA mr_key LIKE iv_key.
    ASSIGN mr_key->* TO <lv_ref>.
    <lv_ref> = iv_key.
    CREATE DATA mr_value LIKE iv_value.
    ASSIGN mr_value->* TO <lv_ref>.
    <lv_ref> = iv_value.
  ENDMETHOD.                    "constructor


  METHOD factory.
    CREATE OBJECT ri_entry TYPE lcl_entry
      EXPORTING
        iv_key   = iv_key
        iv_value = iv_value.
  ENDMETHOD.                    "factory


  METHOD lif_entry~find.
    FIELD-SYMBOLS <lv_ref> TYPE any.
    CLEAR rv_found.
    ASSIGN mr_key->* TO <lv_ref>.
    CHECK <lv_ref> EQ iv_key.
    rv_found = abap_true.
  ENDMETHOD.                    "lif_entry~find

  METHOD lif_entry~get.
    FIELD-SYMBOLS <lv_ref> TYPE any.
    ASSIGN mr_value->* TO <lv_ref>.
    ev_value = <lv_ref>.
  ENDMETHOD.                    "get
ENDCLASS.                    "lcl_entry IMPLEMENTATION


*----------------------------------------------------------------------*
*       CLASS lcl_map DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_map DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    METHODS insert
      IMPORTING iv_key TYPE any
                iv_value TYPE any
      RAISING lcx_buffer_key_in_buffer .


    METHODS get_size
      RETURNING value(rv_size) TYPE syindex.


    METHODS isempty
      RETURNING value(rv_empty) TYPE flag.


    METHODS contains
      IMPORTING iv_key TYPE any
      RETURNING value(rv_found) TYPE flag.


    METHODS remove
      IMPORTING iv_key TYPE any
      RETURNING value(rv_found) TYPE flag.


    METHODS lookup
      IMPORTING iv_key TYPE any
      EXPORTING ev_value TYPE any
      RAISING lcx_buffer_value_not_found.

    CLASS-METHODS factory
      IMPORTING iv_name TYPE csequence
      RETURNING value(ro_buffer) TYPE REF TO lcl_map
      RAISING lcx_buffer_error.
  PRIVATE SECTION.
    TYPES tt_buffer TYPE STANDARD TABLE OF REF TO lif_entry.

    DATA mt_buffer TYPE tt_buffer.
    DATA mv_name TYPE string.
ENDCLASS.                    "lcl_map DEFINITION

*----------------------------------------------------------------------*
*       CLASS lCL_MAP IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_map IMPLEMENTATION.


  METHOD factory.
    CREATE OBJECT ro_buffer.
    ro_buffer->mv_name = iv_name.
  ENDMETHOD.                    "create


  METHOD get_size.
    rv_size = lines( mt_buffer ).
  ENDMETHOD.                    "get_size


  METHOD isempty.
    IF mt_buffer IS INITIAL.
      rv_empty = abap_true.
    ELSE.
      rv_empty = abap_false.
    ENDIF.
  ENDMETHOD.                    "isEmpty


  METHOD contains.
*   Search for already buffered value
    DATA li_entry TYPE REF TO lif_entry.
    CLEAR rv_found.
    LOOP AT mt_buffer INTO li_entry.
      CHECK li_entry->find( iv_key ) EQ abap_true.
      rv_found = abap_true.
      RETURN.
    ENDLOOP.
  ENDMETHOD.                    "contains


  METHOD lookup.
*   Search for already buffered value
    DATA li_entry TYPE REF TO lif_entry.
    LOOP AT mt_buffer INTO li_entry.
      CHECK li_entry->find( iv_key ) EQ abap_true.
      li_entry->get( IMPORTING ev_value = ev_value ).
      RETURN.
    ENDLOOP.
*   Value was not found
    RAISE EXCEPTION TYPE lcx_buffer_value_not_found.
  ENDMETHOD.                    "GET


  METHOD insert.
*   Search for already buffered value
    DATA li_entry TYPE REF TO lif_entry.
    IF me->contains( iv_key ) EQ abap_true.
*     key was already in the buffer
      RAISE EXCEPTION TYPE lcx_buffer_key_in_buffer.
    ENDIF.
*   Value was not found, insert:
    li_entry = lcl_entry=>factory( iv_key = iv_key
                                   iv_value = iv_value ).
    INSERT li_entry INTO TABLE mt_buffer.
  ENDMETHOD.                    "insert


  METHOD remove.
*   remove existing entry
    DATA li_entry TYPE REF TO lif_entry.
    CLEAR rv_found.
    LOOP AT mt_buffer INTO li_entry.
      CHECK li_entry->find( iv_key ) EQ abap_true.
      rv_found = abap_true.
      DELETE mt_buffer.
      FREE li_entry.
      RETURN.
    ENDLOOP.
  ENDMETHOD.                    

ENDCLASS.                    "lCL_BUFFER IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS lcl_test DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_test DEFINITION FOR TESTING
  DURATION MEDIUM RISK LEVEL HARMLESS.

  PRIVATE SECTION.
    CONSTANTS c_max_size TYPE i VALUE 1000.
    DATA mv_sbook_size TYPE i.
    DATA mv_buffer_size TYPE i.
    DATA mt_sbook TYPE STANDARD TABLE OF sbook.


    METHODS setup.
    METHODS without_buffer FOR TESTING.
    METHODS with_buffer FOR TESTING.
ENDCLASS.                    "lcl_test DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_test IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_test IMPLEMENTATION.

  METHOD setup.
    DATA lt_customid TYPE STANDARD TABLE OF sbook-customid.
    SELECT * FROM sbook INTO TABLE mt_sbook
      UP TO c_max_size ROWS.
*    SELECT COUNT( DISTINCT customid ) INTO mv_buffer_size
*      FROM sbook
*      UP TO c_max_size ROWS.
* Ooops! only one row was returned
*    Have to use the convoluted logic below
    SELECT customid FROM sbook
      INTO TABLE lt_customid
      FOR ALL ENTRIES IN mt_sbook
      WHERE carrid = mt_sbook-carrid
        AND connid = mt_sbook-connid
        AND fldate = mt_sbook-fldate
        AND bookid = mt_sbook-bookid.
      mv_buffer_size = lines( lt_customid ).
      mv_sbook_size = lines( mt_sbook ).
    ENDMETHOD.                    "query_sbook

    METHOD without_buffer.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      DATA lv_counter TYPE i.
      LOOP AT mt_sbook INTO ls_sbook.
        SELECT SINGLE * FROM sbuspart INTO ls_sbuspart
          WHERE buspartnum = ls_sbook-customid.
        ADD 1 TO lv_counter.
      ENDLOOP.
      cl_aunit_assert=>assert_equals( exp = mv_sbook_size
                                      act = lv_counter
                                      msg = 'WITHOUT_BUFFER error' ).
    ENDMETHOD.                    "without_buffer

    METHOD with_buffer.
      DATA lo_buffer TYPE REF TO lcl_map.
      DATA ls_sbuspart TYPE sbuspart.
      DATA ls_sbook TYPE sbook.
      DATA lx_error TYPE REF TO cx_static_check.
      DATA lv_counter TYPE i.
      DATA lv_text TYPE string.
      TRY.
          LOOP AT mt_sbook INTO ls_sbook.
            AT FIRST.
              lo_buffer = lcl_map=>factory( 'CUSTOMER_DETAILS' ).
            ENDAT.
            CHECK lo_buffer->contains( ls_sbook-customid ) EQ abap_false.
*         If we haven't saved it yet, get it and save it
            SELECT SINGLE * FROM sbuspart INTO ls_sbuspart
              WHERE buspartnum = ls_sbook-customid.
            lo_buffer->insert( iv_key   = ls_sbook-customid
                               iv_value = ls_sbuspart ).
          ENDLOOP.
          lv_counter = lo_buffer->get_size( ).
          cl_aunit_assert=>assert_equals( exp = mv_buffer_size
                                          act = lv_counter
                                          msg = 'WITH_BUFFER error' ).
        CATCH lcx_buffer_error INTO lx_error.
          lv_text = | WITH_BUFFER { lx_error->get_text( ) } |.
          cl_aunit_assert=>fail( msg = lv_text ).
      ENDTRY.
    ENDMETHOD.                    "with_buffer
  ENDCLASS.                    "lcl_test IMPLEMENTATION
REPORT  zceil_floor .
*-----------------------------------------------------------------------------------*
*              selection screen parameters
*----------------------------------------------------------------------------------*
PARAMETERS: p_int  TYPE i ,
            p_int1 TYPE i .
*-----------------------------------------------------------------------------------*
*              data declarations
*----------------------------------------------------------------------------------*
DATA: value  TYPE p DECIMALS 2  ,
      value1  TYPE p DECIMALS 2 ,
      value2  TYPE p DECIMALS 2 .
*-----------------------------------------------------------------------------------*
*              start of selection
*----------------------------------------------------------------------------------*
START-OF-SELECTION.
  value = p_int / p_int1 .
  value1 = ceil( value  ) .
  value2 = floor( value ) .
*----display output
  WRITE:/ 'the actual value is  :           ' ,   value .
  WRITE:/ 'value using the ceil  function : ' , value1 .
  WRITE:/ 'value using the floor function : ' , value2 .
 

Horst Keller's Blog - ABAP news for release 740 SP05

100 lines of test code with a Unit Test that fails.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT YY_CORRESPONDING.
TYPES ts_sat TYPE if_atra_uml_tool=>ty_sat_record.
TYPES:  BEGIN OF ts_call,
          prog TYPE program,
          type TYPE trobjtype,
          inst TYPE satr_de_instance,
          lcl  TYPE program,
          mod  TYPE seocpdname,
        END OF ts_call.
TYPES:
  BEGIN OF ts_trace,
    id        TYPE satr_de_id,
    aus_ebene TYPE satr_de_ebene,
    caller    TYPE ts_call,
    called    TYPE ts_call,
  END OF ts_trace.
INTERFACE lif_unit_test.
ENDINTERFACE.
CLASS lcl_converter DEFINITION FRIENDS lif_unit_test.
  PUBLIC SECTION.
  PRIVATE SECTION.
    METHODS copy_fields
      IMPORTING is_trace      TYPE ts_sat
      RETURNING VALUE(rs_sat) TYPE ts_trace.
    METHODS operator
      IMPORTING is_trace      TYPE ts_sat
      RETURNING VALUE(rs_sat) TYPE ts_trace.
ENDCLASS.
CLASS ltc_converter DEFINITION
  INHERITING FROM cl_aunit_assert FOR TESTING
  RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    INTERFACES lif_unit_test.
  PRIVATE SECTION.
    DATA ms_sat TYPE ts_sat.
    DATA mo_convert TYPE REF TO lcl_converter.
    METHODS setup.
    METHODS convert FOR TESTING.
ENDCLASS.
CLASS lcl_converter IMPLEMENTATION.
  METHOD copy_fields.
    MOVE-CORRESPONDING is_trace TO rs_sat.
    rs_sat-caller = VALUE #( prog = is_trace-caller
                             type = is_trace-caller_type
                             inst = is_trace-caller_inst
                             lcl = is_trace-caller_lcl
                             mod = is_trace-caller_mod ).
    rs_sat-called = VALUE #( prog = is_trace-called
                             type = is_trace-called_type
                             inst = is_trace-called_inst
                             lcl = is_trace-called_lcl
                             mod = is_trace-called_mod ).
  ENDMETHOD.
  METHOD operator.
    rs_sat =  CORRESPONDING #( is_trace MAPPING
            ( caller = table_line MAPPING prog = caller
                                          type = caller_type
                                          inst = caller_inst
                                          lcl = caller_lcl
                                          mod = caller_mod  )
            ( called = table_line MAPPING prog = called
                                          type = called_type
                                          inst = called_inst
                                          lcl = called_lcl
                                          mod = called_mod  )   ).
  ENDMETHOD.
ENDCLASS.
CLASS ltc_converter IMPLEMENTATION.
  METHOD setup.
    mo_convert = NEW #( ).
    ms_sat = VALUE #( id = 'm'
                      caller = 'PROGRAM'
                      caller_mod = 'TEST'
                      called_type = 'CLAS'
                      called_inst = 4
                      called_lcl = 'LCL_DEMO' ).
  ENDMETHOD.
  METHOD convert.
    DATA(ls_trace) = mo_convert->copy_fields( ms_sat ).
    DATA(ls_act) = mo_convert->operator( ms_sat ).
    assert_equals(  act = ls_act
                    exp = ls_trace
                    msg = 'CONVERSION Error').
  ENDMETHOD.
ENDCLASS.


List of all pages

Pages at first level

Author: Jacques Nomssi
Submitted: 2014-01-21
Related Links:

Description Code:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT ysdnblog_jnn.
DATA: BEGIN OF gs_sel,
        matnr TYPE matnr,
        mtart TYPE mtart,
        matkl TYPE matkl,
      END OF gs_sel.
SELECTION-SCREEN BEGIN OF SCREEN 200.
SELECT-OPTIONS:
  so_matnr FOR gs_sel-matnr,
  so_mtart FOR gs_sel-mtart,
  so_matkl FOR gs_sel-matkl.
PARAMETERS p_rows TYPE count DEFAULT '100'.
SELECTION-SCREEN END OF SCREEN 200.
INTERFACE lif_unit_test.
ENDINTERFACE.
CLASS lcl_param DEFINITION FRIENDS lif_unit_test.
  PUBLIC SECTION.
    TYPES:
      tt_matnr_range TYPE RANGE OF matnr,
      tt_mtart_range TYPE RANGE OF mtart,
      tt_matkl_range TYPE RANGE OF matkl.
    CLASS-METHODS factory
      RETURNING value(ro_param) TYPE REF TO lcl_param.
    DATA mv_rows TYPE count READ-ONLY.
    DATA mt_matnr_range TYPE tt_matnr_range READ-ONLY.
    DATA mt_mtart_range TYPE tt_mtart_range READ-ONLY.
    DATA mt_matkl_range TYPE tt_matkl_range READ-ONLY.
  PRIVATE SECTION.
    METHODS get_selection.
ENDCLASS.                    "lcl_param DEFINITION
INTERFACE lif_data_source.
  METHODS get RETURNING value(rr_data) TYPE REF TO data.
ENDINTERFACE.                    "lif_data_source DEFINITION
CLASS lcl_mara DEFINITION FRIENDS lif_unit_test.
  PUBLIC SECTION.
    INTERFACES lif_data_source.
    ALIASES get FOR lif_data_source~get.
    CLASS-METHODS factory
      IMPORTING io_param TYPE REF TO lcl_param
      RETURNING value(ro_mara) TYPE REF TO lcl_mara.
  PRIVATE SECTION.
    METHODS query
      IMPORTING io_param TYPE REF TO lcl_param.
    DATA mt_mara TYPE mara_tt.
ENDCLASS.                    "lcl_mara DEFINITION
CLASS lcl_view DEFINITION CREATE PRIVATE FRIENDS lif_unit_test.
  PUBLIC SECTION.
    CLASS-METHODS factory
      IMPORTING ii_source TYPE REF TO lif_data_source
      RETURNING value(ro_view) TYPE REF TO lcl_view
      RAISING cx_salv_msg.
    METHODS display.
  PRIVATE SECTION.
    METHODS alv_init
      CHANGING ct_data TYPE STANDARD TABLE
      RAISING cx_salv_msg.
    DATA mo_alv TYPE REF TO cl_salv_table.
ENDCLASS.                    "lcl_view DEFINITION
CLASS lcl_ctrl DEFINITION FRIENDS lif_unit_test.
  PUBLIC SECTION.
    CLASS-METHODS main.
  PRIVATE SECTION.
    CLASS-METHODS create_view
      RETURNING value(ro_view) TYPE REF TO lcl_view
      RAISING cx_salv_msg.
ENDCLASS.
CLASS lcl_ctrl IMPLEMENTATION.
  METHOD create_view.
    DATA lo_param TYPE REF TO lcl_param.
    DATA lo_mara TYPE REF TO lcl_mara.
    CALL SELECTION-SCREEN 200.
    lo_param = lcl_param=>factory( ).
    lo_mara = lcl_mara=>factory( lo_param ).
    ro_view = lcl_view=>factory( lo_mara ).
  ENDMETHOD.                    "create_view
  METHOD main.
    DATA lo_view TYPE REF TO lcl_view.
    DATA lx_error TYPE REF TO cx_static_check.
    TRY.
        lo_view = create_view( ).
        lo_view->display( ).
      CATCH cx_static_check INTO lx_error.
        MESSAGE lx_error TYPE 'E' DISPLAY LIKE 'I'.
    ENDTRY.
  ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
  lcl_ctrl=>main( ).

CLASS lcl_param IMPLEMENTATION.
  METHOD factory.
    CREATE OBJECT ro_param.
    ro_param->get_selection( ).
  ENDMETHOD.                    "factory
  METHOD get_selection.
    mv_rows = p_rows.
    mt_matnr_range[] = so_matnr[].
    mt_matkl_range[] = so_matkl[].
    mt_mtart_range[] = so_mtart[].
  ENDMETHOD.                    "get_selection
ENDCLASS.                    "lcl_param IMPLEMENTATION
CLASS lcl_mara IMPLEMENTATION.
  METHOD factory.
    CREATE OBJECT ro_mara.
    ro_mara->query( io_param ).
  ENDMETHOD.                    "factory
  METHOD query.
    CLEAR mt_mara[].
    SELECT * FROM mara
      INTO CORRESPONDING FIELDS OF TABLE mt_mara
      UP TO io_param->mv_rows ROWS
      WHERE matnr IN io_param->mt_matnr_range
        AND mtart IN io_param->mt_mtart_range
        AND matkl IN io_param->mt_matkl_range.
  ENDMETHOD.                    "query
  METHOD get.
    GET REFERENCE OF mt_mara INTO rr_data.
  ENDMETHOD.                    "get_ref
ENDCLASS.                    "lcl_mara IMPLEMENTATION
CLASS lcl_view IMPLEMENTATION.
  METHOD factory.
    FIELD-SYMBOLS <lt_table> TYPE STANDARD TABLE.
    DATA lr_data TYPE REF TO data.
    CREATE OBJECT ro_view.
    lr_data = ii_source->get( ).
    ASSIGN lr_data->* TO <lt_table>.
    ro_view->alv_init( CHANGING ct_data = <lt_table> ).
  ENDMETHOD.                    "factory
  METHOD display.
    mo_alv->display( ).
  ENDMETHOD.                    "display
  METHOD alv_init.
    DATA lo_functions TYPE REF TO cl_salv_functions.
    cl_salv_table=>factory(
      IMPORTING r_salv_table   = mo_alv
      CHANGING  t_table        = ct_data ).
    lo_functions = mo_alv->get_functions( ).
    lo_functions->set_all( abap_true ).
  ENDMETHOD.                    "alv_init
ENDCLASS.                    "lcl_view IMPLEMENTATION

Author: Marcelo Ramos
Submitted: 09/22/2008

Related Links:

Class Definition

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*---------------------------------------------------------------------*
*       CLASS main DEFINITION
*---------------------------------------------------------------------*
CLASS main DEFINITION.

  PUBLIC SECTION.

    "// Instance Methods ( Note we use the statement 'METHODS'
    "// to define an instance method )
    METHODS set_data IMPORTING i_data TYPE string.
    METHODS get_data RETURNING value(r_data) TYPE string.
    METHODS print_attribute IMPORTING i_data TYPE string.

    "// Instance Methods ( Note we use the statement 'CLASS-METHODS'
    "// to define a static method )
    CLASS-METHODS set_classdata IMPORTING i_data TYPE string.
    CLASS-METHODS get_classdata RETURNING value(r_data) TYPE string.
    CLASS-METHODS print_classattribute IMPORTING i_data TYPE string.

  PROTECTED SECTION.

    "// Instance Attribute ( Note we use the statement 'DATA'
    "// to define an instance attribute )
    DATA attribute TYPE string.
    "// Static Attribute ( Note we use the statement 'CLASS-DATA'
    "// to define a static attribute )
    CLASS-DATA classattribute TYPE string.

  PRIVATE SECTION.

    "// Instace event ( Note we use the statement 'EVENTS'
    "// to define aN instance event )
    EVENTS event EXPORTING value(e_data) TYPE string.

    "// Instace event ( Note we use the statement 'CLASS-EVENTS'
    "// to define a static event )
    CLASS-EVENTS classevent EXPORTING value(e_data) TYPE string.

    "// For more informations about events see the following example:
    "// ABAP Objects - Creating your First Local Class - Using Events

ENDCLASS.                    "main DEFINITION

Class Implementation

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*---------------------------------------------------------------------*
*       CLASS main IMPLEMENTATION
*---------------------------------------------------------------------*
CLASS main IMPLEMENTATION.

  METHOD set_data.

    CONCATENATE 'Instance Attribute value' i_data
                               INTO attribute SEPARATED BY space.

  ENDMETHOD.                    "set_data

  METHOD get_data.

    MOVE attribute TO r_data.

  ENDMETHOD.                    "get_data

  METHOD set_classdata.

    CONCATENATE 'Static Attribute value' i_data
                               INTO classattribute SEPARATED BY space.

  ENDMETHOD.                    "set_classdata

  METHOD get_classdata.

    MOVE main=>classattribute TO r_data.

  ENDMETHOD.                    "get_classdata

  METHOD print_attribute.

    WRITE: i_data, /.

  ENDMETHOD.                    "print_attribute

  METHOD print_classattribute.

    WRITE: i_data, /.

  ENDMETHOD.                    "print_classattribute

ENDCLASS.                    "main IMPLEMENTATION

Data Definition

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA: var type char20.

Calling Static Methods

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
START-OF-SELECTION.

  "// Calling a Static method (note we don't have a object )
  "// instead we use the <class name>=><method name>.
  main=>set_classdata( 'SDN' ).
  var = main=>get_classdata( ).
  "// Print the var value
  main=>print_classattribute( var ).

Object Definition

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA: object_reference TYPE REF TO main.

Instance Creation

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
  CREATE OBJECT object_reference.

Calling Instance Methods

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
  "// - Calling a Instance Method( Note we have to use a object to
  "// access the insntace components of class main )
  "// - Note we're using the statment "CALL METHOD", see looking for
  "// functional & General methods for more informations
  CALL METHOD object_reference->set_data( 'BPX' ).
  var = object_reference->get_data(  ).
  object_reference->print_attribute( var ).

The result is

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
"Static Attribute value SDN
"Instance Attribute value BPX
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT ysubdel1 LINE-SIZE 120.
TYPES : BEGIN OF typ_tab ,
 name(15) TYPE c ,
 age TYPE i ,
END OF typ_tab .
DATA : num1 TYPE i VALUE 5 .
*----------------------------------------------------------------------*
*       CLASS c1 DEFINITION
*----------------------------------------------------------------------*
CLASS c1 DEFINITION .
  PUBLIC SECTION.
    METHODS : meth1 .
    DATA : l_num LIKE num1 ,
    it_tab TYPE STANDARD TABLE OF typ_tab ,
    w_tab LIKE LINE OF it_tab.
ENDCLASS.                    "c1 DEFINITION
*----------------------------------------------------------------------*
*       CLASS c1 IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS c1 IMPLEMENTATION.
  METHOD : meth1 .
    DATA : l_cnum(2) TYPE c.
    l_num = 0.
    DO 5 TIMES.
      l_num = l_num + 1.
      l_cnum = l_num.
      CONCATENATE 'Student-'
      l_cnum
      INTO w_tab-name.
      w_tab-age = num1 * l_num .
      APPEND w_tab TO it_tab.
      CLEAR w_tab.
    ENDDO.
    LOOP AT it_tab INTO w_tab.
      WRITE:/5 w_tab-name ,
      w_tab-age.
    ENDLOOP.
  ENDMETHOD.                    ":
ENDCLASS.                    "c1 IMPLEMENTATION

START-OF-SELECTION.
  DATA : obj1 TYPE REF TO c1.
  CREATE OBJECT : obj1.

  CALL METHOD obj1->meth1.


Output 
 Student-1                5   
 Student-2               10   
 Student-3               15   
 Student-4               20   
 Student-5               25  

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT yoopstests.
*----------------------------------------------------------------------*
*       CLASS class1 DEFINITION
*----------------------------------------------------------------------*
CLASS class1 DEFINITION.
  PUBLIC SECTION.
    METHODS : method1 .
ENDCLASS.                    "class1 DEFINITION
*----------------------------------------------------------------------*
*       CLASS class2 DEFINITION
*----------------------------------------------------------------------*
CLASS class2 DEFINITION.
  PUBLIC SECTION.
    METHODS : method2 .
ENDCLASS.                    "class2 DEFINITION
*----------------------------------------------------------------------*
*       CLASS class1 IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS class1 IMPLEMENTATION.
  METHOD :method1.
    DATA : i_num TYPE i VALUE 2.
    WRITE:/5 i_num.
  ENDMETHOD.                    ":method1
ENDCLASS.                    "class1 IMPLEMENTATION
*----------------------------------------------------------------------*
*       CLASS class2 IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS class2 IMPLEMENTATION.
  METHOD : method2.
    DATA : obj1 TYPE REF TO class1.
    CREATE OBJECT obj1.
    CALL METHOD obj1->method1.
  ENDMETHOD.                    ":
ENDCLASS.                    "class2 IMPLEMENTATION

START-OF-SELECTION.
  DATA : my_obj TYPE REF TO class2.
  CREATE OBJECT : my_obj.
  CALL METHOD my_obj->method2.

Types of Classes:

 
CLASS myclass DEFINITION

PUBLIC SECTION.

........................................

PRIVATE SECTION.

........................................

PROTECTED SECTION

........................................

ENDCLASS

Attributes

The syntax for the declaration of an instance attribute attr is:

CLASS-DATA

DATA attr TYPE dtype [READ-ONLY].

The syntax for the declaration of a static attribute attr is:

CLASS-DATA attr TYPE dtype [READ-ONLY].

Declaration of the Attribute of a Class

CLASS static.vehicle DEFINITION.

PUBLIC SECTION.

....................................

PRIVATE SECTION.

CLASS-DATA speed TYPE I.

ENDCLASS.

The syntax for the declaration of a constant attr is:

CONSTANTS attr TYPE dtype VALUE val.

Correspondingly, the syntax for the declaration of a static method
meth is:
CLASS-METHODS meth
.............................................

 

Declaration and Implementation of Methods :

CLASS static_vehicle DEFINITION.

PUBLIC SECTION.

CLASS-METHODS: accelerate IMPORTING delta TYPE i.

PRIVATE SECTION.

CLASS OATA speed TYPE i.

ENDCLASS.

CLASS static_vehicle IMPLEMENTATION.

METHOD accelerate.

speed = speed + delta.

ENDMETHOD.

METHOD show_speed.

DATA output TYPE string,

output = speed.

MESSAGE Output TYPE 'I'.

ENDMETHOD.

ENDCLASS.

Using a Local Class , Using Static Components

REPORT z_drive_local_static_vehicle.

CLASS static_vehicle DEFINITION.

...........................

ENDCLASS.

CLASS static_vehicle IMPLEMENTATION.

...........................

ENDCLASS.

START-OF-SELECTION.

static_vehicle => accelerate( 100 ).

static_vehicle => accelerate( 200 ).

static_vehicle => show_speed( ).

Class as a Template for Objects

REPORT z_vehicle

CLASS vehicle DEFINITION.

PUBLIC SECTION.

CLASS-METHODS: accelerate IMPORTING delta TYPE i.

PRIVATE SECTION.

DATA speed TYPE i.

ENDCLASS.

CLASS vehicle IMPLEMENTATION.

METHOD accelerate.

speed = speed + delta.

ENDMETHOD.

METHOD show_speed.

DATA output TYPE string,

output = speed.

MESSAGE Output TYPE 'I'.

ENDMETHOD.

ENDCLASS.

Creating and Referencing Objects

REPORT z_drive_veh1cles.

CLASS demo DEFINITION.

PUBLIC SECTION.

CLASS-METHODS main.

ENDCLASS.

CLASS demo IMPLEMENTATION.

METHOO main.

DATA: vehicle1 TYPE REF TO zcl_vehicle.

vehicle2 TYPE REF TO zcl_vehicle.

CREATE OBJECT: vehiclel.

   vehicle2.

vehicle1->accelerate( 100 ). Vehicle1->show_speed( ).

vehicle2->accelerate( 200 ). vehicle2->show_speed( ).

ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

 
demo->main( ).

 

A Quick Recap on Inheritance

As you all probably know Inheritance in ABAP Objects is the ability to take an existing class and create a new class in relation to it. The new class (referred to as a subclass) will inherit all common state and behavior from the existing class (referred to as the super class).

Within the subclass further specializations can be implemented. These specializations could be in the form of new methods and attributes. You could also redefine inherited methods and add custom logic specifically for use within the subclass.

When an object is instantiated, it is done so with reference to a specific type. For instance it could be typed to a class. We can access the object via any reference typed to the class the object was instantiated with.

Inheritance Polymorphism

Inheritance polymorphism allows us to make reference to that object via any variable that is typed to any super class of the class that the object was instantiated with.

The downside of referencing an object via it's superclass is you lose the ability to access certain specializations, as they can only be accessed via reference to the subclass.

The upside however is that you can still call methods that are available in the super class. If you have redefined the method in any subclass in the inheritance hierarchy. The ABAP runtime can determine the lowest possible implementation and will execute this. The ABAP runtime will only look up to the class that the object was originally instantiated with.

Conclusion

Now all of a sudden that tradeoff is looking pretty enticing. We can build complex logic with very detailed specializations and encapsulate the implementation under relevant components. If we need to add new functionality, it would be straightforward to create a new subclass and implement new specializations to handle our requirement. Then we are ready to use these in our applications.

This is a really powerful technique and if understood and applied correctly can reap massive rewards in the development of your applications.

Demo Bicycle Inheritance Polymorphism

The example below is quite detailed, but also contains many comments to supplement my thought processes here.

In a nutshell, I have created an inheritance hierarchy for different types of bicycles. They all share a common method ("get_status") that all subclasses of bicycle inherit and has been redefined. In the main program I add a reference to each object to a list typed to their super class "Bicycle". I then loop through the list and reference the common method. As you can see from the results the method implementation that is actually executed is dependent on the class that the object was instantiated with.

You can copy the below report and include programs into your system to check out how this works....

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*& Report  ZZZ_DEMO_POLYMORPHISM
*&
*&---------------------------------------------------------------------*
*& This program demonstrates examples of encapsulation, inheritance and polymorphism
*&---------------------------------------------------------------------*

REPORT  zzz_demo_polymorphism.

INCLUDE zzz_demo_gears_lib.
INCLUDE zzz_demo_passenger_lib.
INCLUDE zzz_demo_vehicle_lib.


*----------------------------------------------------------------------*
*       CLASS bicycle_demo DEFINITION
*----------------------------------------------------------------------*
* A class to execute the bicycle demo functionality
* This class is set as abstract as I do not want anyone extending
* the class or creating an instance of it as it makes no sense.
* It is only used to kick off the processing for this program
*----------------------------------------------------------------------*
CLASS bicycle_demo DEFINITION ABSTRACT FINAL.
  PUBLIC SECTION.
    CLASS-METHODS: run_demo.
ENDCLASS.                    "bicycle_demo DEFINITION

*----------------------------------------------------------------------*
*       CLASS bicycle_demo IMPLEMENTATION
*----------------------------------------------------------------------*
* In this demo we showcase the power of polymorphism via inheritance.
* As mentioned earlier we stated that objects can be referenced as
* objects of one of their super classes.  So a mountain bike could be
* referenced as a bicycle or as a vehicle.  By referencing an object
* via one of its super class means that you can only execute the methods
* defined in that super class.  However if that method is redefined in the
* subclass, then the ABAP Runtime will determine the lowest implementation
* of that method in the class hierarchy and execute that for the object
*----------------------------------------------------------------------*
CLASS bicycle_demo IMPLEMENTATION.
  METHOD run_demo.

    " Create a structured type of class bicycle
    " and also a table type based on the structured type
    TYPES: BEGIN OF lty_bike,
             bike TYPE REF TO bicycle,
           END OF lty_bike,
           ltty_bikes TYPE STANDARD TABLE OF lty_bike.

    DATA: l_bike TYPE lty_bike,
          lt_bikes TYPE ltty_bikes,
          lo_mountain_bike TYPE REF TO mountain_bike,
          lo_road_bike TYPE REF TO road_bike,
          lo_gear_system TYPE REF TO gear_system,
          lo_passenger TYPE REF TO passenger,
          lo_passenger_list TYPE REF TO passenger_list,
          l_status TYPE string.

    " Always better to use field symbols for looping
    " much better performance
    FIELD-SYMBOLS: <fs_bicycle> TYPE lty_bike.

    " Create a new instance of mountain bike and take it for a spin
    CREATE OBJECT lo_mountain_bike EXPORTING  e_max_passengers = 1
                                              e_max_gears = 10.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_mountain_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Katan' e_last_name = 'Patel' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_mountain_bike->get_gear_system( ).
    lo_mountain_bike->pedal_faster( 10 ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_mountain_bike->apply_brakes( 1 ).
    l_bike-bike = lo_mountain_bike.
    APPEND l_bike TO lt_bikes.
    FREE: lo_mountain_bike, lo_gear_system, lo_passenger_list.

    " Create another instance of mountain bike and take it for a spin
    CREATE OBJECT lo_mountain_bike EXPORTING e_max_passengers = 1
                                             e_max_gears = 18.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_mountain_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Sherlock' e_last_name = 'Holmes' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_mountain_bike->get_gear_system( ).
    lo_mountain_bike->pedal_faster( 20 ).
    lo_gear_system->change_gear_up( ).
    l_bike-bike = lo_mountain_bike.
    APPEND l_bike TO lt_bikes.
    FREE: lo_mountain_bike, lo_gear_system, lo_passenger_list.

    "Create a new instance of Road bike and take it for a spin
    CREATE OBJECT lo_road_bike EXPORTING e_max_passengers = 1
                                         e_max_gears = 20.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_road_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'James' e_last_name = 'Bond' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_road_bike->get_gear_system( ).
    lo_road_bike->pedal_faster( 20 ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_road_bike->apply_brakes( 5 ).
    l_bike-bike = lo_road_bike.
    APPEND l_bike TO lt_bikes.
    FREE: lo_road_bike, lo_gear_system, lo_passenger_list.

    " The impressive bit...
    " I can reference mountain bikes and Road Bikes as bicycles via the power of
    " inheritance.  Here I am looping through all my bicycles and executing output_status.
    " However if you run this, you will see different outputs are generated depending on the
    " type of bicycle being processed.  It it this ability that is polymorphism.
    " You can see that the ABAP runtime determines the correct method to execute by finding the
    " lowest possible implementation of the method "output_bicycle_status" for each of
    " the bicycle objects.  Setting these objects as bicycle does not mean that I cannot convert
    " them back later and use them as their respective objects. You will see in my later examples
    " how it is possible to convert them back
    LOOP AT lt_bikes ASSIGNING <fs_bicycle>.
      l_status = <fs_bicycle>-bike->get_status( ).
      WRITE:/ l_status.
    ENDLOOP.

  ENDMETHOD.                    "run_demo
ENDCLASS.                    "bicycle_demo IMPLEMENTATION


START-OF-SELECTION.
  " This is not required if you are not running a report
  " without using the classic list processing
  " Instead you could use an OO transaction
  " code instead.  It must call a static class method like
  " our 'run_demo' method
  bicycle_demo=>run_demo( ).
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_GEARS_LIB
*&---------------------------------------------------------------------*

*** Class Definitions ***
*----------------------------------------------------------------------*
*       CLASS gear_system DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS gear_system DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_gear(2) TYPE n.

    METHODS: constructor IMPORTING e_max_gears TYPE gear_system=>lty_gear,
             change_gear_up,
             change_gear_down,
             get_current_gear RETURNING value(e_current_gear) TYPE lty_gear.

  PRIVATE SECTION.
    DATA: l_current_gear TYPE lty_gear,
          l_max_gears TYPE lty_gear.
ENDCLASS.                    "gear_system DEFINITION

*** Class Implementations ***
*----------------------------------------------------------------------*
*       CLASS gear_system IMPLEMENTATION
*----------------------------------------------------------------------*
* Class defines a generic gear system for use in any object that uses
* gears
*----------------------------------------------------------------------*
CLASS gear_system IMPLEMENTATION.
  METHOD constructor.
    l_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD change_gear_up.
    l_current_gear = l_current_gear + 1.
  ENDMETHOD.                    "change_gear_up
  METHOD change_gear_down.
    l_current_gear = l_current_gear - 1.
  ENDMETHOD.                    "change_gear_down
  METHOD get_current_gear.  "This is the only way to access this field of the class
    e_current_gear = l_current_gear.
  ENDMETHOD.                    "get_current_gear
ENDCLASS.                    "gear_system IMPLEMENTATION
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_PASSENGER_LIB
*&---------------------------------------------------------------------*


*----------------------------------------------------------------------*
*       CLASS passenger DEFINITION
*----------------------------------------------------------------------*
* A generic class for a passenger.
*----------------------------------------------------------------------*
CLASS passenger DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_name TYPE string,
           lty_dest TYPE string.

    METHODS: constructor IMPORTING e_first_name TYPE lty_name
                                   e_last_name TYPE lty_name,
             set_first_name IMPORTING e_first_name TYPE lty_name,
             set_last_name IMPORTING e_last_name TYPE lty_name,
             get_full_name RETURNING value(i_full_name) TYPE lty_name,
             set_current_destination IMPORTING e_destination TYPE lty_dest,
             get_current_destination EXPORTING i_destination TYPE lty_dest.

  PRIVATE SECTION.
    DATA: l_first_name TYPE lty_name,
          l_last_name TYPE lty_name,
          l_current_destination TYPE lty_dest.
ENDCLASS.                    "passenger DEFINITION


*----------------------------------------------------------------------*
*       CLASS passenger_list DEFINITION
*----------------------------------------------------------------------*
*  A class to manage a list of passengers.  This should not be extended
* thus it is set as final.  It handles the management of all passengers
* I can use this in other objects and not worry about this when using
* instances of this class
*----------------------------------------------------------------------*
CLASS passenger_list DEFINITION FINAL.
  PUBLIC SECTION.
    TYPES: BEGIN OF lty_passengers,
             full_name TYPE passenger=>lty_name,
             passenger TYPE REF TO passenger,
           END OF lty_passengers,
           ltty_passengers TYPE SORTED TABLE OF lty_passengers
            WITH UNIQUE KEY full_name.

    METHODS: constructor IMPORTING e_max_passengers TYPE i,
             add_passenger IMPORTING e_passenger TYPE REF TO passenger
                           RETURNING value(i_added_successfully) TYPE REF TO cl_boolean,
             add_passenger_by_name IMPORTING e_first_name TYPE passenger=>lty_name
                                             e_last_name TYPE passenger=>lty_name
                           RETURNING value(i_added_successfully) TYPE REF TO cl_boolean,
             remove_passenger IMPORTING e_passenger TYPE REF TO passenger
                              RETURNING value(i_removed_successfully) TYPE REF TO cl_boolean,
             check_passenger_exists IMPORTING e_passenger TYPE REF TO passenger
                                    RETURNING value(i_does_exist) TYPE REF TO cl_boolean,
             set_max_passengers IMPORTING e_max_passengers TYPE i,
             get_max_passengers RETURNING VALUE(i_max_passengers) TYPE i,
             get_passengers RETURNING value(it_passengers) TYPE ltty_passengers,
             get_status RETURNING value(i_status) TYPE string.

  PRIVATE SECTION.
    DATA: lt_passengers TYPE ltty_passengers,
          l_max_passengers TYPE i.

ENDCLASS.                    "passenger_list DEFINITION

*----------------------------------------------------------------------*
*       CLASS passenger IMPLEMENTATION
*----------------------------------------------------------------------*
*  The implementation of the passenger
*----------------------------------------------------------------------*
CLASS passenger IMPLEMENTATION.
  METHOD constructor.
    l_first_name = e_first_name.
    l_last_name = e_last_name.
  ENDMETHOD.                    "constructor
  METHOD set_first_name.
    l_first_name = e_first_name.
  ENDMETHOD.                    "set_first_name
  METHOD set_last_name.
    l_last_name = e_last_name.
  ENDMETHOD.                    "set_last_name
  METHOD get_full_name.
    CONCATENATE l_first_name l_last_name INTO i_full_name
        SEPARATED BY space.
  ENDMETHOD.                    "get_full_name
  METHOD set_current_destination.
    l_current_destination = e_destination.
  ENDMETHOD.                    "set_current_destination
  METHOD get_current_destination.
    i_destination = l_current_destination.
  ENDMETHOD.                    "get_current_destination
ENDCLASS.                    "passenger IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS passenger_list IMPLEMENTATION
*----------------------------------------------------------------------*
*  The implementation of class passenger_list
*----------------------------------------------------------------------*
CLASS passenger_list IMPLEMENTATION.
  METHOD constructor.
    l_max_passengers = e_max_passengers.
  ENDMETHOD.                    "constructor
  METHOD check_passenger_exists.
    DATA: l_full_name TYPE passenger=>lty_name.

    "Implicitly this should be false
    i_does_exist = cl_boolean=>false.

    " Get the passengers full name
    l_full_name = e_passenger->get_full_name( ).

    " Read the table to see if an entry already exists for the passenger
    READ TABLE lt_passengers
      WITH TABLE KEY full_name = l_full_name
      TRANSPORTING NO FIELDS.

    " If it does exist then set it to true
    IF sy-subrc = 0.
      i_does_exist = cl_boolean=>true.
    ENDIF.
  ENDMETHOD.                    "check_passenger_exists
  METHOD add_passenger.
    DATA: l_full_name TYPE passenger=>lty_name,
          l_passenger_record TYPE lty_passengers,
          l_no_records TYPE i.

    DESCRIBE TABLE lt_passengers LINES l_no_records.
    IF l_no_records = l_max_passengers.
      WRITE:/ 'Too many passengers on board.  No record added'.
      EXIT.
    ENDIF.

    "Implicitly this should be false
    i_added_successfully = cl_boolean=>false.

    "If the passenger does not already exist we can add it
    IF check_passenger_exists( e_passenger ) = cl_boolean=>false.
      l_passenger_record-full_name = e_passenger->get_full_name( ).
      l_passenger_record-passenger = e_passenger.
      INSERT l_passenger_record INTO TABLE lt_passengers .

      i_added_successfully = cl_boolean=>true.
    ELSE.
      WRITE:/ 'Passenger ', l_full_name, ' already exists'.
    ENDIF.
  ENDMETHOD.                    "add_passenger
  METHOD remove_passenger.
    DATA: l_full_name TYPE passenger=>lty_name.

    " Get the passengers full name
    l_full_name = e_passenger->get_full_name( ).

    "Implicitly this should be false
    i_removed_successfully = cl_boolean=>false.

    "If the passenger exists we can remove it
    IF check_passenger_exists( e_passenger ) = cl_boolean=>true.
      DELETE lt_passengers
        WHERE full_name = l_full_name.
      i_removed_successfully = cl_boolean=>true.
    ELSE.
      WRITE:/ 'Passenger ', l_full_name, ' does not exist'.
    ENDIF.
  ENDMETHOD.                    "remove_passenger
  METHOD set_max_passengers.
    l_max_passengers = e_max_passengers.
  ENDMETHOD.                    "set_max_passengers
  METHOD get_max_passengers.
    i_max_passengers = l_max_passengers.
  ENDMETHOD.                    "get_max_passengers
  METHOD add_passenger_by_name.
    "This method acts as a quick way to create passengers and add them
    " to my list
    DATA: lo_passenger TYPE REF TO passenger.

    CREATE OBJECT lo_passenger EXPORTING e_first_name = e_first_name
                                         e_last_name = e_last_name.
    add_passenger( lo_passenger ).
  ENDMETHOD.                    "add_passenger_by_name
  METHOD get_status.
    DATA: l_full_name TYPE passenger=>lty_name.

    FIELD-SYMBOLS: <fs_passenger> TYPE lty_passengers.

    i_status = 'My list of passengers includes: '.

    " Loop through all the passengers and return a string of passengers
    LOOP AT lt_passengers ASSIGNING <fs_passenger>.
      l_full_name = <fs_passenger>-passenger->get_full_name( ).
      IF sy-tabix = 1.
        CONCATENATE i_status l_full_name INTO i_status SEPARATED BY space.
      ELSE.
        CONCATENATE i_status ',' INTO i_status.
        CONCATENATE i_status l_full_name INTO i_status SEPARATED BY space.
      ENDIF.
    ENDLOOP.
    IF sy-subrc <> 0.
      i_status = 'I have no passengers'.
    ENDIF.
  ENDMETHOD.                    "get_status
  METHOD get_passengers.
    it_passengers = lt_passengers.
  ENDMETHOD.
ENDCLASS.                    "passenger_list IMPLEMENTATION
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_VEHICLE_LIB
*&---------------------------------------------------------------------*

*** Class Definitions ***
*----------------------------------------------------------------------*
*       CLASS vehicle DEFINITION
*----------------------------------------------------------------------*
* A generic implementation for vehicles
*----------------------------------------------------------------------*
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_speed(4) TYPE n.

    METHODS: constructor IMPORTING eo_max_passengers TYPE i,
             speed_up IMPORTING e_increment_speed TYPE lty_speed,
             slow_down IMPORTING e_decrement_speed TYPE lty_speed,
             get_current_speed RETURNING value(i_current_speed) TYPE lty_speed,
             get_passengers_list RETURNING value(io_passenger_list) TYPE REF TO passenger_list.

  PRIVATE SECTION.
    DATA: l_speed TYPE lty_speed,
          lo_passengers_list TYPE REF TO passenger_list.

ENDCLASS.                    "vehicle DEFINITION

*----------------------------------------------------------------------*
*       CLASS bicycle DEFINITION
*----------------------------------------------------------------------*
* A class for bicycles.  This is a sub class of vehicle
*----------------------------------------------------------------------*
CLASS bicycle DEFINITION INHERITING FROM vehicle.
  PUBLIC SECTION.
    METHODS: get_status RETURNING value(e_status) TYPE string,
             pedal_faster IMPORTING e_increment_speed TYPE vehicle=>lty_speed,
             apply_brakes IMPORTING e_decrement_speed TYPE vehicle=>lty_speed.
ENDCLASS.                    "bicycle DEFINITION

*----------------------------------------------------------------------*
*       CLASS mountain_bike DEFINITION
*----------------------------------------------------------------------*
* Mountain bikes have gears and so gear system is an attribute of
* mountain bike class.  This is a subclass of bicycle
*----------------------------------------------------------------------*
CLASS mountain_bike DEFINITION INHERITING FROM bicycle.

  PUBLIC SECTION.
    METHODS: constructor IMPORTING e_max_passengers TYPE i
                                   e_max_gears TYPE gear_system=>lty_gear,
             get_status REDEFINITION,
             get_gear_system RETURNING value(i_gear_system) TYPE REF TO gear_system.

  PRIVATE SECTION.
    DATA: l_gear_system TYPE REF TO gear_system.

ENDCLASS.                    "mountain_bike DEFINITION

*----------------------------------------------------------------------*
*       CLASS road_bike DEFINITION
*----------------------------------------------------------------------*
*   This is a subclass of bicycle
*----------------------------------------------------------------------*
CLASS road_bike DEFINITION INHERITING FROM bicycle.
  PUBLIC SECTION.
    METHODS: constructor IMPORTING e_max_passengers TYPE i
                          e_max_gears TYPE gear_system=>lty_gear,
             get_status REDEFINITION,
             get_gear_system RETURNING value(i_gear_system) TYPE REF TO gear_system.

  PRIVATE SECTION.
    DATA: l_gear_system TYPE REF TO gear_system.
ENDCLASS.                    "road_bike DEFINITION

*----------------------------------------------------------------------*
*       CLASS tandem_bike DEFINITION
*----------------------------------------------------------------------*
* This is a subclass of bicycle
*----------------------------------------------------------------------*
CLASS tandem_bike DEFINITION INHERITING FROM bicycle.
  PUBLIC SECTION.
    METHODS: constructor IMPORTING e_max_passengers TYPE i,
             get_status REDEFINITION.
ENDCLASS.                    "tandem_bike DEFINITION


*** Class Implementations ***
*----------------------------------------------------------------------*
*       CLASS vehicle IMPLEMENTATION
*----------------------------------------------------------------------*
* Superclass of all vehicles
*----------------------------------------------------------------------*
CLASS vehicle IMPLEMENTATION.
  METHOD constructor.
    CREATE OBJECT lo_passengers_list
        EXPORTING e_max_passengers = eo_max_passengers.
  ENDMETHOD.                    "constructor
  METHOD speed_up.
    l_speed = l_speed + e_increment_speed.
  ENDMETHOD.                    "speed_up
  METHOD slow_down.
    l_speed = l_speed - e_decrement_speed.

    "Speed cannot be less than 0
    IF l_speed LT 0.
      l_speed = 0.
    ENDIF.
  ENDMETHOD.                    "apply_breaks
  METHOD get_current_speed.
    i_current_speed = l_speed.
  ENDMETHOD.                    "get_current_speed
  METHOD get_passengers_list.
    io_passenger_list = lo_passengers_list.
  ENDMETHOD.                    "get_passengers_list
ENDCLASS.                    "vehicle IMPLEMENTATION


*----------------------------------------------------------------------*
*       CLASS bicycle IMPLEMENTATION
*----------------------------------------------------------------------*
* Superclass of all bicycles
*----------------------------------------------------------------------*
CLASS bicycle IMPLEMENTATION.
  METHOD get_status.
    DATA: l_output TYPE string,
          l_speed TYPE vehicle=>lty_speed.

    l_speed = get_current_speed( ).

    CONCATENATE 'I am a bicycle.  My speed is' l_speed
      INTO e_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status
  METHOD apply_brakes.
    me->slow_down( e_decrement_speed ).
  ENDMETHOD.                    "apply_breaks
  METHOD pedal_faster.
    me->speed_up( e_increment_speed ).
  ENDMETHOD.                    "pedal_faster
ENDCLASS.                    "bicycle IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS mountain_bike IMPLEMENTATION
*----------------------------------------------------------------------*
* Used to implement a Mountain Bike
*----------------------------------------------------------------------*
CLASS mountain_bike IMPLEMENTATION.
  METHOD constructor.
    " This calls the super class constructor passing this parameter
    " In the super class is our passenger_list and it will hand the creation
    " of the instance of that class.  You've got to love inheritance.
    " You get all that functionality for free from the super class.
    super->constructor( e_max_passengers ).

    " Initiate the gear systen for a mountain bike
    CREATE OBJECT l_gear_system EXPORTING e_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD get_status.
    " This method was re-implemented and is more specific to a mountain bike

    DATA: l_speed TYPE vehicle=>lty_speed,
          l_current_gear TYPE gear_system=>lty_gear,
          l_passenger_status TYPE string,
          lo_passenger_list TYPE REF TO passenger_list.


    l_speed = get_current_speed( ).

    l_current_gear = l_gear_system->get_current_gear( ).

    lo_passenger_list = get_passengers_list( ).
    l_passenger_status = lo_passenger_list->get_status( ).


    CONCATENATE 'I am a mountain bike.  My current gear is'
                l_current_gear
                '.  My speed is'
                l_speed '.'
      INTO e_status SEPARATED BY space.

    CONCATENATE e_status l_passenger_status INTO e_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status
  METHOD get_gear_system.
    i_gear_system = l_gear_system.
  ENDMETHOD.                    "get_gear_system
ENDCLASS.                    "mountain_bike IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS road_bike IMPLEMENTATION
*----------------------------------------------------------------------*
* Used to implement road bike
*----------------------------------------------------------------------*
CLASS road_bike IMPLEMENTATION.
  METHOD constructor.
    " This calls the super class constructor passing this parameter
    " In the super class is our passenger_list and it will hand the creation
    " of the instance of that class.  You've got to love inheritance.
    " You get all that functionality for free from the super class.
    super->constructor( e_max_passengers ).

    " Initiate the gear systen for a mountain bike
    CREATE OBJECT l_gear_system EXPORTING e_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD get_gear_system.
    i_gear_system = l_gear_system.
  ENDMETHOD.                    "get_gear_system
  METHOD get_status.
    " This method was re-implemented and is more specific to a mountain bike

    DATA: l_speed TYPE vehicle=>lty_speed,
          l_current_gear TYPE gear_system=>lty_gear,
          l_passenger_status TYPE string,
          lo_passenger_list TYPE REF TO passenger_list.

    l_speed = get_current_speed( ).

    l_current_gear = l_gear_system->get_current_gear( ).

    lo_passenger_list = get_passengers_list( ).
    l_passenger_status = lo_passenger_list->get_status( ).

    CONCATENATE 'I am a road bike.  My current gear is'
                l_current_gear
                '.  My speed is'
                l_speed '.'
      INTO e_status SEPARATED BY space.

    CONCATENATE e_status l_passenger_status INTO e_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status

ENDCLASS.                    "road_bike IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS tandem_bike IMPLEMENTATION
*----------------------------------------------------------------------*
* Used to implement tandem bike.  It took me 2 minutes to create all
* the code for this.  All thanks to inheritance
*----------------------------------------------------------------------*
CLASS tandem_bike IMPLEMENTATION.
  METHOD constructor.
    " This calls the super class constructor passing this parameter
    " In the super class is our passenger_list and it will hand the creation
    " of the instance of that class.  You've got to love inheritance.
    " You get all that functionality for free from the super class.
    super->constructor( e_max_passengers ).

  ENDMETHOD.                    "constructor

  METHOD get_status.
    " This method was re-implemented and is more specific to a tandem

    DATA: l_speed TYPE vehicle=>lty_speed,
          l_passenger_status TYPE string,
          lo_passenger_list TYPE REF TO passenger_list.

    l_speed = get_current_speed( ).

    lo_passenger_list = get_passengers_list( ).
    l_passenger_status = lo_passenger_list->get_status( ).

    CONCATENATE 'I am a tandem bike.'
                'My speed is'
                l_speed '.'
      INTO e_status SEPARATED BY space.

    CONCATENATE e_status l_passenger_status INTO e_status SEPARATED BY space.

  ENDMETHOD.                    "get_status
ENDCLASS.                    "tandem_bike DEFINITION

The result

It would look a bit like this. I just can't work out how to load an image here...

ZZZKP_DEMO_POLYMORPHISM

I am a mountain bike. My current gear is 02 . My speed is 0009 . My list of passengers includes: Katan Patel
I am a mountain bike. My current gear is 01 . My speed is 0020 . My list of passengers includes: Sherlock Holmes
I am a road bike. My current gear is 03 . My speed is 0015 . My list of passengers includes: James Bond

A Quick Recap on Interfaces

In its most common form, an interface is a group of related methods with empty bodies. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler.

If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully activate. A class can implement more than one interface.

Interface Polymorphism

In the same way that a class can be used to type a reference to an object. It is also possible to use an interface to type a reference to an object. You can only do this if your interface is implemented in the class that object was instantiated to. This also includes all super classes of the class. Thus polymorphism can be achieved via interfaces.

Similar to inheritance polymorphism, the downside of referencing an object via an interface that it implements, is that you lose the ability to access all methods of the class the object was instantiated with that are not defined in the interface.

Again similar to inheritance polymorphism, the upside is that you can still call methods available in the interface. The ABAP runtime can determine the class that the object was instantiated from and execute the implementation in this class.

When would you use this technique?

The main reason to use this is when you need to provide common functionality across unrelated classes. If you are to provide common functionality across related classes, it would make more sense to use inheritance instead.

Conclusion

By having a contract with developers who implement this interface with a tightly defined signature, we can guarantee they can develop a unit of code that will fit exactly within our existing code and can be accessed with reference to the interface.

I know that seems like a massive sentence to take in, so let's work it through in a demo.

Demo Bicycle Interface Polymorphism

In this program we define an interface "object_status" to allow any object that implements it to output it's status via the method "get_status".

We then have a complimentary class called "status_handler" that can be used to store references to any object that implements the interface "object_status".

In the demo program we add objects to the list and then can execute a method of list to output the statuses of all the objects in the list.

Now the beauty of this is that, as long as any class I use implements my list, I can use the list to store them and generate outputs. So if I create new classes I can reuse all of this logic, just by implementing the interface and it's method. Talk about getting something for free....

You can copy the below report and include programs into your system to check out how this works....

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*& Report  ZZZ_DEMO_INTERFACE
*&
*&---------------------------------------------------------------------*
*& In this example we have created an interface "object_status" to define
*& the methods for handling the output of status for objects. As interfaces
*& can be used for typing object instances any object that implements
*& this interface can assigned a reference with that type.  By implementing
*& the interface is like a contractually binding agreement that the
*& implementing class promises to provide the functionality outlined in the
*& interface definition
*&
*& We then have a class implemented that handles a list of objects
*& referenced to the type of the interface "status_handler".  Here we
*& have used the singleton design pattern to get us instances of itself
*& An instance of this class can be used to store any object that
*& implements interface "object_status" and output all the status for
*& each object in the list.  I can confidently know that any object
*& being passed here will implement the methods defined in the interface
*& and so I can call these within this class to provide functionality
*& to output statuses of all the objects listed
*&
*& The cool thing is that any new objects I create that implement this
*& can implicitly be used with the class "status_handler".  In short I
*& am using this technique for providing common functionality to
*& unrelated classes.
*&
*& One thing you cannot do with interfaces is change them once they are
*& created and released.  To provide common functionality among related
*& classes it is always better to use an abstract class
*&---------------------------------------------------------------------*

REPORT  zzz_demo_interface.

INCLUDE zzz_status_int_lib.
INCLUDE zzz_demo_gears_int_lib.
INCLUDE zzz_demo_passenger_int_lib.
INCLUDE zzz_demo_vehicle_int_lib.


*----------------------------------------------------------------------*
*       CLASS bicycle_demo DEFINITION
*----------------------------------------------------------------------*
* A class to execute the bicycle demo functionality
* This class is set as abstract as I do not want anyone extending
* the class or creating an instance of it as it makes no sense.
* It is only used to kick off the processing for this program
*----------------------------------------------------------------------*
CLASS bicycle_demo DEFINITION ABSTRACT FINAL.
  PUBLIC SECTION.
    CLASS-METHODS: run_demo.
ENDCLASS.                    "bicycle_demo DEFINITION

*----------------------------------------------------------------------*
*       CLASS bicycle_demo IMPLEMENTATION
*----------------------------------------------------------------------*
* Implement the bicycle demo functionaility.  Here I am creating
* all of these objects which implement the object_status interface
* I am then adding them to a status_handler_list although tehy are not
* explicitly typed as status_handler, because the class they belong to
* implements the interface
*----------------------------------------------------------------------*
CLASS bicycle_demo IMPLEMENTATION.
  METHOD run_demo.

    DATA: lo_mountain_bike TYPE REF TO mountain_bike,
          lo_road_bike TYPE REF TO road_bike,
          lo_gear_system TYPE REF TO gear_system,
          lo_passenger TYPE REF TO passenger,
          lo_passenger_list TYPE REF TO passenger_list,
          lo_status_handler type REF TO status_handler.

    " Get an instance of status handler
    " This class was implemented using the singleton design pattern
    " so I get the instance via method "get_instance"
    lo_status_handler = status_handler=>get_instance( ).

    " Create a new instance of mountain bike and take it for a spin
    CREATE OBJECT lo_mountain_bike EXPORTING  e_max_passengers = 1
                                              e_max_gears = 10.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_mountain_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Katan' e_last_name = 'Patel' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_mountain_bike->get_gear_system( ).
    lo_mountain_bike->pedal_faster( 10 ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_mountain_bike->apply_brakes( 1 ).
    lo_status_handler->add_object_to_monitor( lo_mountain_bike ).
    FREE: lo_mountain_bike, lo_gear_system, lo_passenger_list.

    " Create another instance of mountain bike and take it for a spin
    CREATE OBJECT lo_mountain_bike EXPORTING e_max_passengers = 1
                                             e_max_gears = 18.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_mountain_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Sherlock' e_last_name = 'Holmes' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_mountain_bike->get_gear_system( ).
    lo_mountain_bike->pedal_faster( 20 ).
    lo_gear_system->change_gear_up( ).
    " Add the mountain bike to the status handler method
    lo_status_handler->add_object_to_monitor( lo_mountain_bike ).
    FREE: lo_mountain_bike, lo_gear_system, lo_passenger_list.

    "Create a new instance of Road bike and take it for a spin
    CREATE OBJECT lo_road_bike EXPORTING e_max_passengers = 1
                                         e_max_gears = 20.
    " Get the reference to the passengers list for the mountain bike
    " and assign it to the passenger list field then add a new passenger
    lo_passenger_list = lo_road_bike->get_passengers_list( ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'James' e_last_name = 'Bond' ).
    " Get the reference to the gear system for the mountain bike
    " and assign it to the gear_system field
    lo_gear_system = lo_road_bike->get_gear_system( ).
    lo_road_bike->pedal_faster( 20 ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_gear_system->change_gear_up( ).
    lo_road_bike->apply_brakes( 5 ).
    " Add the mountain bike to the status handler method
    lo_status_handler->add_object_to_monitor( lo_road_bike ).
    FREE: lo_road_bike, lo_gear_system, lo_passenger_list.

    " Create a passenger list object
    CREATE OBJECT lo_passenger_list
      EXPORTING e_max_passengers = 5.
    " Add some passengers
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Harry' e_last_name = 'Potter' ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Mary' e_last_name = 'Poppins' ).
    lo_passenger_list->add_passenger_by_name( e_first_name = 'Basil' e_last_name = 'Fawlty' ).
    " Add the passenger objects to my object_status table.
    lo_status_handler->add_object_to_monitor( lo_passenger_list ).
    FREE: lo_passenger_list.

    " Execute this method to output the status for all the objects added to
    " the status handler list
    lo_status_handler->output_status_for_all_objs( ).

  ENDMETHOD.                    "run_demo
ENDCLASS.                    "bicycle_demo IMPLEMENTATION


START-OF-SELECTION.
  " This is not required if you are not running a report
  " without using the classic list processing
  " Instead use an ALV as output and use an OO transaction
  " code instead.  It must call a static class method like
  " our run_demo
  bicycle_demo=>run_demo( ).
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_GEARS_INT_LIB
*&---------------------------------------------------------------------*

*** Class Definitions ***
*----------------------------------------------------------------------*
*       CLASS gear_system DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS gear_system DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_gear(2) TYPE n.

    METHODS: constructor IMPORTING e_max_gears TYPE gear_system=>lty_gear,
             change_gear_up,
             change_gear_down,
             get_current_gear RETURNING value(e_current_gear) TYPE lty_gear.

    INTERFACES: object_status.

  PRIVATE SECTION.
    DATA: l_current_gear TYPE lty_gear,
          l_max_gears TYPE lty_gear.
ENDCLASS.                    "gear_system DEFINITION

*** Class Implementations ***
*----------------------------------------------------------------------*
*       CLASS gear_system IMPLEMENTATION
*----------------------------------------------------------------------*
* Class defines a generic gear system for use in any object that uses
* gears
*----------------------------------------------------------------------*
CLASS gear_system IMPLEMENTATION.
  METHOD constructor.
    l_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD change_gear_up.
    l_current_gear = l_current_gear + 1.
  ENDMETHOD.                    "change_gear_up
  METHOD change_gear_down.
    l_current_gear = l_current_gear - 1.
  ENDMETHOD.                    "change_gear_down
  METHOD get_current_gear.  "This is the only way to access this field of the class
    e_current_gear = l_current_gear.
  ENDMETHOD.                    "get_current_gear
  METHOD object_status~get_status.
    CONCATENATE 'My gear system has ' l_max_gears
                'and is currently in gear' l_current_gear
      INTO i_status SEPARATED BY space.
  ENDMETHOD.                    "object_status~get_status
ENDCLASS.                    "gear_system IMPLEMENTATION

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_PASSENGER_INT_LIB
*&---------------------------------------------------------------------*


*----------------------------------------------------------------------*
*       CLASS passenger DEFINITION
*----------------------------------------------------------------------*
* A generic class for a passenger.
*----------------------------------------------------------------------*
CLASS passenger DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_name TYPE string,
           lty_dest TYPE string.

    METHODS: constructor IMPORTING e_first_name TYPE lty_name
                                   e_last_name TYPE lty_name,
             set_first_name IMPORTING e_first_name TYPE lty_name,
             set_last_name IMPORTING e_last_name TYPE lty_name,
             get_full_name RETURNING value(i_full_name) TYPE lty_name,
             set_current_destination IMPORTING e_destination TYPE lty_dest,
             get_current_destination EXPORTING i_destination TYPE lty_dest.

  PRIVATE SECTION.
    DATA: l_first_name TYPE lty_name,
          l_last_name TYPE lty_name,
          l_current_destination TYPE lty_dest.
ENDCLASS.                    "passenger DEFINITION


*----------------------------------------------------------------------*
*       CLASS passenger_list DEFINITION
*----------------------------------------------------------------------*
*  A class to manage a list of passengers.  This should not be extended
* thus it is set as final.  It handles the management of all passengers
* I can use this in other objects and not worry about this when using
* instances of this class
*----------------------------------------------------------------------*
CLASS passenger_list DEFINITION FINAL.
  PUBLIC SECTION.
    TYPES: BEGIN OF lty_passengers,
             full_name TYPE passenger=>lty_name,
             passenger TYPE REF TO passenger,
           END OF lty_passengers,
           ltty_passengers TYPE SORTED TABLE OF lty_passengers
            WITH UNIQUE KEY full_name.

    INTERFACES: object_status.

    METHODS: constructor IMPORTING e_max_passengers TYPE i,
             add_passenger IMPORTING e_passenger TYPE REF TO passenger
                           RETURNING value(i_added_successfully) TYPE REF TO cl_boolean,
             add_passenger_by_name IMPORTING e_first_name TYPE passenger=>lty_name
                                             e_last_name TYPE passenger=>lty_name
                           RETURNING value(i_added_successfully) TYPE REF TO cl_boolean,
             remove_passenger IMPORTING e_passenger TYPE REF TO passenger
                              RETURNING value(i_removed_successfully) TYPE REF TO cl_boolean,
             check_passenger_exists IMPORTING e_passenger TYPE REF TO passenger
                                    RETURNING value(i_does_exist) TYPE REF TO cl_boolean,
             set_max_passengers IMPORTING e_max_passengers TYPE i,
             get_max_passengers EXPORTING i_max_passengers TYPE i.

  PRIVATE SECTION.
    DATA: lt_passengers TYPE ltty_passengers,
          l_max_passengers TYPE i.

ENDCLASS.                    "passenger_list DEFINITION

*----------------------------------------------------------------------*
*       CLASS passenger IMPLEMENTATION
*----------------------------------------------------------------------*
*  The implementation of the passenger
*----------------------------------------------------------------------*
CLASS passenger IMPLEMENTATION.
  METHOD constructor.
    l_first_name = e_first_name.
    l_last_name = e_last_name.
  ENDMETHOD.                    "constructor
  METHOD set_first_name.
    l_first_name = e_first_name.
  ENDMETHOD.                    "set_first_name
  METHOD set_last_name.
    l_last_name = e_last_name.
  ENDMETHOD.                    "set_last_name
  METHOD get_full_name.
    CONCATENATE l_first_name l_last_name INTO i_full_name
        SEPARATED BY space.
  ENDMETHOD.                    "get_full_name
  METHOD set_current_destination.
    l_current_destination = e_destination.
  ENDMETHOD.                    "set_current_destination
  METHOD get_current_destination.
    i_destination = l_current_destination.
  ENDMETHOD.                    "get_current_destination
ENDCLASS.                    "passenger IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS passenger_list IMPLEMENTATION
*----------------------------------------------------------------------*
*  The implementation of class passenger_list
*----------------------------------------------------------------------*
CLASS passenger_list IMPLEMENTATION.
  METHOD constructor.
    l_max_passengers = e_max_passengers.
  ENDMETHOD.                    "constructor
  METHOD check_passenger_exists.
    DATA: l_full_name TYPE passenger=>lty_name.

    "Implicitly this should be false
    i_does_exist = cl_boolean=>false.

    " Get the passengers full name
    l_full_name = e_passenger->get_full_name( ).

    " Read the table to see if an entry already exists for the passenger
    READ TABLE lt_passengers
      WITH TABLE KEY full_name = l_full_name
      TRANSPORTING NO FIELDS.

    " If it does exist then set it to true
    IF sy-subrc = 0.
      i_does_exist = cl_boolean=>true.
    ENDIF.
  ENDMETHOD.                    "check_passenger_exists
  METHOD add_passenger.
    DATA: l_full_name TYPE passenger=>lty_name,
          l_passenger_record TYPE lty_passengers,
          l_no_records TYPE i.

    DESCRIBE TABLE lt_passengers LINES l_no_records.
    IF l_no_records = l_max_passengers.
      WRITE:/ 'Too many passengers on board.  No record added'.
      EXIT.
    ENDIF.

    "Implicitly this should be false
    i_added_successfully = cl_boolean=>false.

    "If the passenger does not already exist we can add it
    IF check_passenger_exists( e_passenger ) = cl_boolean=>false.
      l_passenger_record-full_name = e_passenger->get_full_name( ).
      l_passenger_record-passenger = e_passenger.
      INSERT l_passenger_record INTO TABLE lt_passengers .

      i_added_successfully = cl_boolean=>true.
    ELSE.
      WRITE:/ 'Passenger ', l_full_name, ' already exists'.
    ENDIF.
  ENDMETHOD.                    "add_passenger
  METHOD remove_passenger.
    DATA: l_full_name TYPE passenger=>lty_name.

    " Get the passengers full name
    l_full_name = e_passenger->get_full_name( ).

    "Implicitly this should be false
    i_removed_successfully = cl_boolean=>false.

    "If the passenger does not already exist we can add it
    IF check_passenger_exists( e_passenger ) = cl_boolean=>true.
      DELETE lt_passengers
        WHERE full_name = l_full_name.
      i_removed_successfully = cl_boolean=>true.
    ELSE.
      WRITE:/ 'Passenger ', l_full_name, ' does not exist'.
    ENDIF.
  ENDMETHOD.                    "remove_passenger
  METHOD set_max_passengers.
    l_max_passengers = e_max_passengers.
  ENDMETHOD.                    "set_max_passengers
  METHOD get_max_passengers.
    i_max_passengers = l_max_passengers.
  ENDMETHOD.                    "get_max_passengers
  METHOD add_passenger_by_name.
    "This method acts as a quick way to create passengers and add them
    " to my list
    DATA: lo_passenger TYPE REF TO passenger.

    CREATE OBJECT lo_passenger EXPORTING e_first_name = e_first_name
                                         e_last_name = e_last_name.
    add_passenger( lo_passenger ).
  ENDMETHOD.                    "add_passenger_by_name
  METHOD object_status~get_status.
    DATA: l_full_name TYPE passenger=>lty_name.

    FIELD-SYMBOLS: <fs_passenger> TYPE lty_passengers.

    i_status = 'My list of passengers includes: '.

    " Loop through all the passengers and return a string of passengers
    LOOP AT lt_passengers ASSIGNING <fs_passenger>.
      l_full_name = <fs_passenger>-passenger->get_full_name( ).
      IF sy-tabix = 1.
        CONCATENATE i_status l_full_name INTO i_status SEPARATED BY space.
      ELSE.
        CONCATENATE i_status ',' l_full_name INTO i_status SEPARATED BY space.
      ENDIF.
    ENDLOOP.
    IF sy-subrc <> 0.
      i_status = 'I have no passengers'.
    ENDIF.
  ENDMETHOD.                    "get_status
ENDCLASS.                    "passenger_list IMPLEMENTATION
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_DEMO_VEHICLE_INT_LIB
*&---------------------------------------------------------------------*

*** Class Definitions ***
*----------------------------------------------------------------------*
*       CLASS vehicle DEFINITION
*----------------------------------------------------------------------*
* A generic implementation for vehicles
*----------------------------------------------------------------------*
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    TYPES: lty_speed(4) TYPE n.

    METHODS: constructor IMPORTING eo_max_passengers TYPE i,
    speed_up IMPORTING e_increment_speed TYPE lty_speed,
    slow_down IMPORTING e_decrement_speed TYPE lty_speed,
    get_current_speed RETURNING value(i_current_speed) TYPE lty_speed,
    get_passengers_list RETURNING value(io_passenger_list) TYPE REF TO passenger_list.

  PRIVATE SECTION.
    DATA: l_speed TYPE lty_speed,
          lo_passengers_list TYPE REF TO passenger_list.

ENDCLASS.                    "vehicle DEFINITION

*----------------------------------------------------------------------*
*       CLASS bicycle DEFINITION
*----------------------------------------------------------------------*
* A class for bicycles.  This is a sub class of vehicle
*----------------------------------------------------------------------*
CLASS bicycle DEFINITION INHERITING FROM vehicle.
  PUBLIC SECTION.
    INTERFACES: object_status.

    METHODS: pedal_faster IMPORTING e_increment_speed TYPE vehicle=>lty_speed,
             apply_brakes IMPORTING e_decrement_speed TYPE vehicle=>lty_speed.
ENDCLASS.                    "bicycle DEFINITION

*----------------------------------------------------------------------*
*       CLASS mountain_bike DEFINITION
*----------------------------------------------------------------------*
* Mountain bikes have gears and so gear system is an attribute of
* mountain bike class.  This is a subclass of bicycle
*----------------------------------------------------------------------*
CLASS mountain_bike DEFINITION INHERITING FROM bicycle.

  PUBLIC SECTION.
    METHODS: constructor IMPORTING e_max_passengers TYPE i
                                   e_max_gears TYPE gear_system=>lty_gear,
             object_status~get_status REDEFINITION,
             get_gear_system RETURNING value(i_gear_system) TYPE REF TO gear_system.

  PRIVATE SECTION.
    DATA: l_gear_system TYPE REF TO gear_system.

ENDCLASS.                    "mountain_bike DEFINITION

*----------------------------------------------------------------------*
*       CLASS road_bike DEFINITION
*----------------------------------------------------------------------*
*   This is a subclass of bicycle
*----------------------------------------------------------------------*
CLASS road_bike DEFINITION INHERITING FROM bicycle.
  PUBLIC SECTION.
    METHODS: constructor IMPORTING e_max_passengers TYPE i
                          e_max_gears TYPE gear_system=>lty_gear,
             object_status~get_status REDEFINITION,
             get_gear_system RETURNING value(i_gear_system) TYPE REF TO gear_system.

  PRIVATE SECTION.
    DATA: l_gear_system TYPE REF TO gear_system.
ENDCLASS.                    "road_bike DEFINITION

*** Class Implementations ***
*----------------------------------------------------------------------*
*       CLASS vehicle IMPLEMENTATION
*----------------------------------------------------------------------*
* Superclass of all vehicles
*----------------------------------------------------------------------*
CLASS vehicle IMPLEMENTATION.
  METHOD constructor.
    CREATE OBJECT lo_passengers_list
        EXPORTING e_max_passengers = eo_max_passengers.
  ENDMETHOD.                    "constructor
  METHOD speed_up.
    l_speed = l_speed + e_increment_speed.
  ENDMETHOD.                    "speed_up
  METHOD slow_down.
    l_speed = l_speed - e_decrement_speed.

    "Speed cannot be less than 0
    IF l_speed LT 0.
      l_speed = 0.
    ENDIF.
  ENDMETHOD.                    "apply_breaks
  METHOD get_current_speed.
    i_current_speed = l_speed.
  ENDMETHOD.                    "get_current_speed
  METHOD get_passengers_list.
    io_passenger_list = lo_passengers_list.
  ENDMETHOD.                    "get_passengers_list
ENDCLASS.                    "vehicle IMPLEMENTATION


*----------------------------------------------------------------------*
*       CLASS bicycle IMPLEMENTATION
*----------------------------------------------------------------------*
* Superclass of all bicycles
*----------------------------------------------------------------------*
CLASS bicycle IMPLEMENTATION.
  METHOD object_status~get_status.
    DATA: l_output TYPE string,
          l_speed TYPE vehicle=>lty_speed.

    l_speed = get_current_speed( ).

    CONCATENATE 'I am a bicycle.  My speed is' l_speed
      INTO i_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status
  METHOD apply_brakes.
    me->slow_down( e_decrement_speed ).
  ENDMETHOD.                    "apply_breaks
  METHOD pedal_faster.
    me->speed_up( e_increment_speed ).
  ENDMETHOD.                    "pedal_faster
ENDCLASS.                    "bicycle IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS mountain_bike IMPLEMENTATION
*----------------------------------------------------------------------*
* Used to implement a Mountain Bike
*----------------------------------------------------------------------*
CLASS mountain_bike IMPLEMENTATION.
  METHOD constructor.
    " This calls the super class constructor passing this parameter
    " In the super class is our passenger_list and it will hand the creation
    " of the instance of that class.  You've got to love inheritance.
    " You get all that functionality for free from the super class.
    super->constructor( e_max_passengers ).

    " Initiate the gear systen for a mountain bike
    CREATE OBJECT l_gear_system EXPORTING e_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD object_status~get_status.
    " This method was re-implemented and is more specific to a mountain bike

    DATA: l_speed TYPE vehicle=>lty_speed,
          l_current_gear TYPE gear_system=>lty_gear,
          l_passenger_status TYPE string,
          lo_passenger_list TYPE REF TO passenger_list.


    l_speed = get_current_speed( ).

    l_current_gear = l_gear_system->get_current_gear( ).

    lo_passenger_list = get_passengers_list( ).
    l_passenger_status = lo_passenger_list->object_status~get_status( ).


    CONCATENATE 'I am a mountain bike.  My current gear is'
                l_current_gear
                '.  My speed is'
                l_speed '.'
      INTO i_status SEPARATED BY space.

    CONCATENATE i_status l_passenger_status INTO i_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status
  METHOD get_gear_system.
    i_gear_system = l_gear_system.
  ENDMETHOD.                    "get_gear_system
ENDCLASS.                    "mountain_bike IMPLEMENTATION

*----------------------------------------------------------------------*
*       CLASS road_bike IMPLEMENTATION
*----------------------------------------------------------------------*
* Used to implment road bike
*----------------------------------------------------------------------*
CLASS road_bike IMPLEMENTATION.
  METHOD constructor.
    " This calls the super class constructor passing this parameter
    " In the super class is our passenger_list and it will hand the creation
    " of the instance of that class.  You've got to love inheritance.
    " You get all that functionality for free from the super class.
    super->constructor( e_max_passengers ).

    " Initiate the gear systen for a mountain bike
    CREATE OBJECT l_gear_system EXPORTING e_max_gears = e_max_gears.
  ENDMETHOD.                    "constructor
  METHOD get_gear_system.
    i_gear_system = l_gear_system.
  ENDMETHOD.                    "get_gear_system
  METHOD object_status~get_status.
    " This method was re-implemented and is more specific to a mountain bike

    DATA: l_speed TYPE vehicle=>lty_speed,
          l_current_gear TYPE gear_system=>lty_gear,
          l_passenger_status TYPE string,
          lo_passenger_list TYPE REF TO passenger_list.

    l_speed = get_current_speed( ).

    l_current_gear = l_gear_system->get_current_gear( ).

    lo_passenger_list = get_passengers_list( ).
    l_passenger_status = lo_passenger_list->object_status~get_status( ).

    CONCATENATE 'I am a road bike.  My current gear is'
                l_current_gear
                '.  My speed is'
                l_speed '.'
      INTO i_status SEPARATED BY space.

    CONCATENATE i_status l_passenger_status INTO i_status SEPARATED BY space.
  ENDMETHOD.                    "output_bicycle_status

ENDCLASS.                    "road_bike IMPLEMENTATION
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*&  Include           ZZZ_STATUS_INT_LIB
*&---------------------------------------------------------------------*
INTERFACE object_status.
  METHODS: get_status RETURNING value(i_status) TYPE string.
ENDINTERFACE.                    "object_status

*----------------------------------------------------------------------*
*       CLASS status_handler DEFINITION
*----------------------------------------------------------------------*
* A class to manage the handling of statuses of objects
*----------------------------------------------------------------------*
CLASS status_handler DEFINITION CREATE PRIVATE.
  PUBLIC SECTION.
    " Create a structured type of interface object_status
    " and also a table type based on the structured type
    TYPES: BEGIN OF lty_object_status,
             object_status TYPE REF TO object_status,
           END OF lty_object_status,
           ltty_objects TYPE STANDARD TABLE OF lty_object_status.

    CLASS-METHODS: get_instance RETURNING value(i_obj_stat)
                      TYPE REF TO status_handler.

    METHODS: add_object_to_monitor
                  IMPORTING e_object TYPE REF TO object_status,
             free_objects_to_monitor,
             output_status_for_all_objs.

  PRIVATE SECTION.
    CLASS-DATA: lo_status_handler TYPE REF TO status_handler.

    DATA: lt_object_status TYPE ltty_objects.
ENDCLASS.                    "status_handler DEFINITION

*----------------------------------------------------------------------*
*       CLASS status_handler IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS status_handler IMPLEMENTATION.
  METHOD get_instance.
    IF lo_status_handler IS INITIAL.
      CREATE OBJECT lo_status_handler.
    ENDIF.
    i_obj_stat = lo_status_handler.
  ENDMETHOD.                    "get_instance
  METHOD add_object_to_monitor.
    " This method can be used to store references to object_status objects
    DATA: l_object_status_record TYPE lty_object_status.

    l_object_status_record-object_status = e_object.
    APPEND l_object_status_record TO lt_object_status.

  ENDMETHOD.                    "add_object_to_monitor
  " This method can be used to delete all references to objects of object_status
  " stored in the list for monitoring
  METHOD free_objects_to_monitor.
    FREE: lt_object_status.
  ENDMETHOD.                    "free_objects_to_monitor
  METHOD output_status_for_all_objs.
    DATA: l_status TYPE string.
    " Always better to use field symbols for looping
    " much better performance
    FIELD-SYMBOLS: <fs_object_status> TYPE lty_object_status.

    " The impressive bit...
    " I can reference any objects that implement interface object_status via interface
    " inheritance.  Here I am looping through all my objects and executing output_status.
    " However if you run this, you will see different outputs are generated depending on the
    " type on the actual object being processed.  It it this ability that is polymorphism but via interfaces.
    " You can see that the ABAP runtime determines the correct method to execute by finding the
    " lowest possible implementation of the method "output_bicycle_status" for each of
    " the objects.  Referencing these objects via the interface does not mean that I cannot convert
    " them back later and use them as their respective objects. You will see in my later examples
    " how it is possible to convert them back
    LOOP AT lt_object_status ASSIGNING <fs_object_status>.
      l_status = <fs_object_status>-object_status->get_status( ).
      WRITE:/ l_status.
    ENDLOOP.

  ENDMETHOD.                    "output_status_for_monitored_objs
ENDCLASS.                    "status_handler IMPLEMENTATION

The Result

It would look a bit like this.

Program ZZZKP_DEMO_INTERFACE

I am a mountain bike. My current gear is 02 . My speed is 0009 . My list of passengers includes: Katan Patel
I am a mountain bike. My current gear is 01 . My speed is 0020 . My list of passengers includes: Sherlock Holmes
I am a road bike. My current gear is 03 . My speed is 0015 . My list of passengers includes: James Bond
My list of passengers includes: Harry Potter , Mary Poppins , Basil Fawlty

Hi, most of the people here on SCN try to learn object oriented programming through various available sources. I have also tried a lot to learn this beautiful OOP feature and still learning it. Even I have gone through various SAP Press Books to summarize all the aspects of it. Here I have prepared a small set of information that would be useful before, after and in-between phase of learning OOP. It also helps you to get quick understanding of any topic before you go in depth. I have not explained global class here that is skipped intentionally for your practice with reference to local class. Please check all sample abap code. As I said I am also learning so I may not give you some of your queries so please bear with me and help me to improve this document so that everyone can get benefit from it. I always try to provide best details to you if possible. Thank you.

 

Class

A class is an abstract representation, or, a set of instructions for building objects

Object

Objects are instances of classes. There can be any number of objects or instances in a class. Each object has a unique identity and its own attributes.

Encapsulation

Visibility (public, protected, private)

Inheritance

Inheritance allows you to derive a new class from an existing class.

Polymorphism

Overriding methods / redefining method - after inheriting / Interface.

Abstract

        Definition of a class cannot generate instance. You can only 

        Use an abstract class to create subclass.

Friend-Defined

 Access private attributes of another class.

Event

Invoke methods of same or other class.

Interface

Cannot have implementation, just the definition.

Exception

Static check-(check both at runtime and compile time), Dynamic check (only checks at runtime), No check (for all kind of exceptions). using CX_ROOT class

Levels

Instance, static, Constant.

Test class / Test methods

unit test (Test method class CL_AUNIT_ASSERT, #AU_DURATION_SHORT, #AU_RISK_LEVEL HARMLESS)

Persistent Class

Agent class, Base class, Class.

Refactoring Assistant

Add new class above any existing class.

Object parameters

Importing/Exporting/Returning-(receiving)/Exception and Raising

 

 

Additional Points.

->Static data shares common value across any number of its object, and it is only accessible inside static method or via => operator (cls_name=>static attribute).

->Multiple inheritance is not supported by abap (we may use interface to achieve this).

->In object parameter: Exception is non-class base exception which is triggered with statement raise / message raising.

->In object parameter: Raising is class base exception which is triggered with statement raise / message raising.

->The tilde (~) between the interface name and the interface component name is called the interface component selector operator.

->In persistent the class builder also generates a couple of additional agent classes that manage all of the low-level interaction details between objects of the persistent class and the Persistence Service.

->objects of persistent classes are referred to as managed objects.

->Transaction persistent service (We can insert data directly from persistent class to dB table using Tcode). IF_OS_TRANSACTION & IF_OS_TRANSACTION_MANAGER

General OOP Course Content that you should know:

 

  1. Class and object creation.
  2. Encapsulation (Public, Protected, Private).
  3. Constructor.
  4. Class method / class data.
  5. Final class - cannot be inherited any more.
  6. Final method - cannot be redefined any more.
  7. Inheritance.
  8. Using of super keyword.
  9. Interface.
  10. Exception handling using cx_root class.
  11. Test methods
  12. Persistent class
  13. Refactoring assistant
  14. Serialization - XML Transformation
  15. MVC pattern

 

Program Samples Index.

  • Class
  • Encapsulation
  • Inheritance
  • Polymorphism
  • Super keyword
  • Abstract
  • Friend-Deferred
  • Event
  • Interface
  • Exception
  • Test class / Test methods
  • Object parameters - Part 1
  • Object parameters - Part 2
  • MVC Pattern

 

Program Samples.

 

1.Class.

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION.
    PUBLIC SECTION.
      METHODS: METH1.
  ENDCLASS.

  CLASS CLS1 IMPLEMENTATION.
    METHOD METH1.
        WRITE : / 'OK'.
      ENDMETHOD.
    ENDCLASS.

START-OF-SELECTION.

    DATA : OBJ1 TYPE REF TO CLS1.
    CREATE OBJECT OBJ1.

    CALL METHOD OBJ1->METH1.

 

 

2. Encapsulation.

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION.
  PUBLIC SECTION.
    METHODS: METH1.
  PROTECTED SECTION.
    METHODS: METH2.
  PRIVATE SECTION.
    METHODS: METH3.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in public'.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - in protected'.
  ENDMETHOD.                                                "METH2

  METHOD METH3.
    WRITE : / 'OK -  in private'.
  ENDMETHOD.                                                "METH3
ENDCLASS.                    "CLS1 IMPLEMENTATION

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.

 

 

3. Inheritance

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION.
  PUBLIC SECTION.
    METHODS: METH1.
  PROTECTED SECTION.
    METHODS: METH2.
  PRIVATE SECTION.
    METHODS: METH3.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in public'.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - in protected'.
  ENDMETHOD.                                                "METH2

  METHOD METH3.
    WRITE : / 'OK -  in private'.
  ENDMETHOD.                                                "METH3
ENDCLASS.                    "CLS1 IMPLEMENTATION


class CLS2 DEFINITION INHERITING FROM CLS1.
  PUBLIC SECTION.
    METHODS: METH4.
ENDCLASS.

CLASS CLS2 IMPLEMENTATION.
    METHOD METH4.
        WRITE : / 'OK - in class2 public'.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS2.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.
  CALL METHOD OBJ1->METH4.

 

 

4.Polymorphism

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION.
  PUBLIC SECTION.
    METHODS: METH1.
  PROTECTED SECTION.
    METHODS: METH2.
  PRIVATE SECTION.
    METHODS: METH3.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in public'.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - in protected'.
  ENDMETHOD.                                                "METH2

  METHOD METH3.
    WRITE : / 'OK -  in private'.
  ENDMETHOD.                                                "METH3
ENDCLASS.                    "CLS1 IMPLEMENTATION


class CLS2 DEFINITION INHERITING FROM CLS1.
  PUBLIC SECTION.
    METHODS: METH4.
    METHODS: METH1 REDEFINITION.
ENDCLASS.

CLASS CLS2 IMPLEMENTATION.
    METHOD METH4.
        WRITE : / 'OK - in class2 public'.
    ENDMETHOD.

    METHOD METH1.
      WRITE : / 'OK - in class2 public - Redefine meth1 of class1'.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS2.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.
  CALL METHOD OBJ1->METH4.

 

 

5.Super keyword

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION.
  PUBLIC SECTION.
    METHODS: METH1.
  PROTECTED SECTION.
    METHODS: METH2.
  PRIVATE SECTION.
    METHODS: METH3.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in public'.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - in protected'.
  ENDMETHOD.                                                "METH2

  METHOD METH3.
    WRITE : / 'OK -  in private'.
  ENDMETHOD.                                                "METH3
ENDCLASS.                    "CLS1 IMPLEMENTATION


class CLS2 DEFINITION INHERITING FROM CLS1.
  PUBLIC SECTION.
    METHODS: METH4.
    METHODS: METH1 REDEFINITION.
ENDCLASS.

CLASS CLS2 IMPLEMENTATION.
    METHOD METH4.
        WRITE : / 'OK - in class2 public'.
    ENDMETHOD.

    METHOD METH1.
      WRITE : / 'OK - in class2 public - Redefine meth1 of class1'.
      CALL METHOD SUPER->METH1.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS2.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.
  CALL METHOD OBJ1->METH4.

 

 

6.Abstract

 

REPORT ZAVI_LOGIC.
class cls0 DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS: METH0.
ENDCLASS.

CLASS CLS0 IMPLEMENTATION.
    METHOD METH0.
        WRITE : / 'Inside Abstract'.
      ENDMETHOD.
ENDCLASS.

CLASS CLS1 DEFINITION INHERITING FROM cls0.
  PUBLIC SECTION.
    METHODS: METH1.
    METHODS: METH0 REDEFINITION.
  PROTECTED SECTION.
    METHODS: METH2.
  PRIVATE SECTION.
    METHODS: METH3.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in public'.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - in protected'.
  ENDMETHOD.                                                "METH2

  METHOD METH3.
    WRITE : / 'OK -  in private'.
  ENDMETHOD.                                                "METH3

  METHOD METH0.
      WRITE : / 'OK -  From abstract'.
    ENDMETHOD.
ENDCLASS.                    "CLS1 IMPLEMENTATION


class CLS2 DEFINITION INHERITING FROM CLS1.
  PUBLIC SECTION.
    METHODS: METH4.
    METHODS: METH1 REDEFINITION.
ENDCLASS.

CLASS CLS2 IMPLEMENTATION.
    METHOD METH4.
        WRITE : / 'OK - in class2 public'.
    ENDMETHOD.

    METHOD METH1.
      WRITE : / 'OK - in class2 public - Redefine meth1 of class1'.
      CALL METHOD SUPER->METH1.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS2.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.
  CALL METHOD OBJ1->METH4.
  CALL METHOD OBJ1->METH0.

 

 

7.Friend-Definition

 

REPORT ZAVI_LOGIC.

class CLS2 DEFINITION DEFERRED.

CLASS CLS1 DEFINITION FRIENDS CLS2.
  PRIVATE SECTION.
    METHODS: METH1.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in private'.
  ENDMETHOD.                                                "METH1
ENDCLASS.                    "CLS1 IMPLEMENTATION

class CLS2 DEFINITION INHERITING FROM CLS1.
  PUBLIC SECTION.
    METHODS: METH2.
  ENDCLASS.

CLASS CLS2 IMPLEMENTATION.
    METHOD METH2.
        WRITE : / 'OK - in class2 private'.

        DATA : OBFN TYPE REF TO CLS1.
        CREATE OBJECT OBFN.
        CALL METHOD OBFN->METH1.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS2.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH2.

 

 

8.Event

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION .

  PUBLIC SECTION.
    EVENTS: EVT1.
    METHODS: METH1.
    METHODS : METH2 FOR EVENT EVT1 OF CLS1.

ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    WRITE : / 'OK - in PUBLIC'.

    RAISE EVENT EVT1.
  ENDMETHOD.                                                "METH1

  METHOD METH2.
    WRITE : / 'OK - CALLED VIA EVENT'.
    ENDMETHOD.
ENDCLASS.                    "CLS1 IMPLEMENTATION

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.
  SET HANDLER OBJ1->METH2 FOR OBJ1.
  CALL METHOD OBJ1->METH1.

 

 

9.Interface

 

REPORT ZAVI_LOGIC.

INTERFACE INTF1.
  METHODS : METH_INTF1,METH_INTF2.
ENDINTERFACE.                                               "INTF1

CLASS CLS1 DEFINITION .
  PUBLIC SECTION.
    INTERFACES INTF1.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD INTF1~METH_INTF1.
    WRITE : / ' INSIDE CLASS 1 INTERFACE METHOD1'.
  ENDMETHOD.                    "INTF1~METH_INTF1

  METHOD INTF1~METH_INTF2.
    WRITE : / ' INSIDE CLASS 1 INTERFACE METHOD2'.
  ENDMETHOD.                    "INTF1~METH_INTF2

ENDCLASS.                    "CLS1 IMPLEMENTATION

CLASS CLS2 DEFINITION.
  PUBLIC SECTION.
    INTERFACES INTF1.
ENDCLASS.                    "CLS2 DEFINITION

CLASS CLS2 IMPLEMENTATION.
  METHOD INTF1~METH_INTF1.
    WRITE : / ' INSIDE CLASS 2 INTERFACE METHOD1'.
  ENDMETHOD.                    "INTF1~METH_INTF1

  METHOD INTF1~METH_INTF2.
    WRITE : / ' INSIDE CLASS 2 INTERFACE METHOD2'.
  ENDMETHOD.                    "INTF1~METH_INTF2
ENDCLASS.                    "CLS2 IMPLEMENTATION


START-OF-SELECTION.
  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->INTF1~METH_INTF1.
  CALL METHOD OBJ1->INTF1~METH_INTF2.

  DATA : OBJ2 TYPE REF TO CLS2.
  CREATE OBJECT OBJ2.
  CALL METHOD OBJ2->INTF1~METH_INTF1.
  CALL METHOD OBJ2->INTF1~METH_INTF2.

 

 

10.Exception

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION .
  PUBLIC SECTION.
    METHODS METH1.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    DATA : LR_EX TYPE REF TO CX_ROOT.
    DATA : VAL1 TYPE I VALUE 10 ,
          VAL2 TYPE I VALUE 0,
          VAL3 TYPE I.

    DATA : PRG_NAM TYPE SYREPID,
           INCL TYPE SYREPID,
           SRC_LIN TYPE I,
           GTEXT TYPE STRING,
           GTLTX TYPE STRING.
    TRY.
        VAL3 = VAL1 / VAL2.
      CATCH CX_ROOT INTO LR_EX.
        CALL METHOD LR_EX->GET_SOURCE_POSITION
          IMPORTING
            PROGRAM_NAME = PRG_NAM
            INCLUDE_NAME = INCL
            SOURCE_LINE  = SRC_LIN.

        CALL METHOD LR_EX->IF_MESSAGE~GET_TEXT
          RECEIVING
            RESULT = GTEXT.
        CALL METHOD LR_EX->IF_MESSAGE~GET_LONGTEXT
          RECEIVING
            RESULT = GTLTX.

        WRITE : / 'Program Name : ',PRG_NAM.
        WRITE : / 'Include Name : ',INCL.
        WRITE : / 'Error Line No: ',SRC_LIN.
        WRITE : / 'Description: ',GTEXT.
        WRITE : / 'Long Text: ',GTLTX.

    ENDTRY.
  ENDMETHOD.                                                "METH1
ENDCLASS.                    "CLS1 IMPLEMENTATION

START-OF-SELECTION.

  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.
  CALL METHOD OBJ1->METH1.

 

 

11.Test class / Test methods

*How to execute this type of test: from menu path Program->Test->Unit Test.

 

REPORT ZAVI_LOGIC.

CLASS CLS1 DEFINITION .
  PUBLIC SECTION.
    METHODS METH1.
ENDCLASS.                    "CLS1 DEFINITION

CLASS CLS1 IMPLEMENTATION.
  METHOD METH1.
    DATA : LR_EX TYPE REF TO CX_ROOT.
    DATA : VAL1 TYPE I VALUE 10 ,
           VAL2 TYPE I VALUE 0,
           VAL3 TYPE I.

    DATA : PRG_NAM TYPE SYREPID,
           INCL TYPE SYREPID,
           SRC_LIN TYPE I,
           GTEXT TYPE STRING,
           GTLTX TYPE STRING.
    TRY.
        VAL3 = VAL1 / VAL2.
      CATCH CX_ROOT INTO LR_EX.
        RAISE EXCEPTION LR_EX.
        CALL METHOD LR_EX->GET_SOURCE_POSITION
          IMPORTING
            PROGRAM_NAME = PRG_NAM
            INCLUDE_NAME = INCL
            SOURCE_LINE  = SRC_LIN.
        CALL METHOD LR_EX->IF_MESSAGE~GET_TEXT
          RECEIVING
            RESULT = GTEXT.
        CALL METHOD LR_EX->IF_MESSAGE~GET_LONGTEXT
          RECEIVING
            RESULT = GTLTX.
        WRITE : / 'Program Name : ',PRG_NAM.
        WRITE : / 'Include Name : ',INCL.
        WRITE : / 'Error Line No: ',SRC_LIN.
        WRITE : / 'Description: ',GTEXT.
        WRITE : / 'Long Text: ',GTLTX.
    ENDTRY.
  ENDMETHOD.                                                "METH1
ENDCLASS.                    "CLS1 IMPLEMENTATION

CLASS TST1 DEFINITION "#AU Duration Short
     FOR TESTING.     "#AU Risk_Level Harmless
  PUBLIC SECTION.
    METHODS TST FOR TESTING.

ENDCLASS.                    "TST1 DEFINITION

CLASS TST1 IMPLEMENTATION.
  METHOD TST.
    DATA : OBJ1 TYPE REF TO CLS1.
    CREATE OBJECT OBJ1.
    CALL METHOD OBJ1->METH1.
  ENDMETHOD.                    "TST
ENDCLASS.                    "TST1 IMPLEMENTATION

 

 

12.Object parameters - Part 1

 

REPORT ZAVI_LOGIC.

class cls1 DEFINITION.
    PUBLIC SECTION.
        methods ADDITION 
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I RETURNING VALUE(R1) TYPE I.
        methods DIVISION 
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I RETURNING VALUE(R1) TYPE I.
        methods MULTIPLI 
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I RETURNING VALUE(R1) TYPE I.
        methods SUBSTRAC 
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I RETURNING VALUE(R1) TYPE I.

     PRIVATE SECTION.
        DATA : ANS TYPE I.
  endclass.

class cls1 IMPLEMENTATION.

    method ADDITION.
      CLEAR ans.
      ANS = V1 + V2.
      R1 = ANS.
    ENDMETHOD.

    method DIVISION.
      CLEAR ans.
      ANS = V1 / V2.
      R1 = ANS.
    ENDMETHOD.

    method MULTIPLI.
      CLEAR ans.
      ANS = V1 * V2.
      R1 = ANS.
    ENDMETHOD.

    method SUBSTRAC.
      CLEAR ans.
      ANS = V1 - V2.
      R1 = ANS.
    ENDMETHOD.

ENDCLASS.



  START-OF-SELECTION.
  DATA : ANS TYPE I.
  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.

  CALL METHOD OBJ1->ADDITION EXPORTING V1 = 10 V2 = 20 RECEIVING R1 = ANS.
  WRITE : / 'Addition is: ',ans.

  CALL METHOD OBJ1->DIVISION EXPORTING V1 = 10 V2 = 20 RECEIVING R1 = ANS.
  WRITE : / 'Division is: ',ans.

  CALL METHOD OBJ1->MULTIPLI EXPORTING V1 = 10 V2 = 20 RECEIVING R1 = ANS.
  WRITE : / 'Multiplication is: ',ans.

  CALL METHOD OBJ1->SUBSTRAC EXPORTING V1 = 10 V2 = 20 RECEIVING R1 = ANS.
  WRITE : / 'Substraction is: ',ans.

 

 

13.Object parameters - Part 2 (Exception and Raising)

A. Raising->Automatic error handling.

 

REPORT ZAVI_LOGIC.

class cls1 DEFINITION.
    PUBLIC SECTION.
        methods DIVISION
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I
            RETURNING VALUE(R1) TYPE I RAISING cx_sy_arithmetic_error.

     PRIVATE SECTION.
        DATA : ANS TYPE I.
  endclass.

class cls1 IMPLEMENTATION.
    method DIVISION.
      CLEAR ans.
      ANS = V1 / V2.
      R1 = ANS.
    ENDMETHOD.

ENDCLASS.


  START-OF-SELECTION.
  DATA : ANS TYPE I.
  data : err type ref to cx_sy_arithmetic_error.
  data : txt type string.
  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.

  try.
  CALL METHOD OBJ1->DIVISION EXPORTING V1 = 10 V2 = 0 RECEIVING R1 = ANS.
  catch cx_sy_arithmetic_error INTO err.
      txt = err->get_text( ).
  endtry.

  WRITE : / 'Division is: ',ans.
  WRITE : / 'Error is : ',txt.

 

 

B. Exception->manually error code assign and handle.

 

class cls1 DEFINITION.
    PUBLIC SECTION.
        methods DIVISION
          IMPORTING VALUE(V1) TYPE I VALUE(V2) TYPE I
            RETURNING VALUE(R1) TYPE I EXCEPTIONS err.

     PRIVATE SECTION.
        DATA : ANS TYPE I.
  endclass.

class cls1 IMPLEMENTATION.
    method DIVISION.
      CLEAR ans.
      try.
      ANS = V1 / V2.
      catch cx_sy_arithmetic_error.
          RAISE ERR.
      ENDTRY.
      R1 = ANS.
    ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  DATA : ANS TYPE I.
  data : err type ref to cx_sy_arithmetic_error.
  data : txt type string.
  DATA : OBJ1 TYPE REF TO CLS1.
  CREATE OBJECT OBJ1.

  CALL METHOD OBJ1->DIVISION
  EXPORTING V1 = 10 V2 = 0 RECEIVING R1 = ANS EXCEPTIONS ERR = 11.

IF SY-SUBRC EQ 0.
      WRITE : ANS.
  ELSEIF SY-SUBRC EQ 11.
     WRITE : / 'Divide zero error'.
    ENDIF.

 

 

14.MVC Pattern

 

REPORT ZAVI_LOGIC.

DATA : IT TYPE TABLE OF MARA .

CLASS MODEL DEFINITION.
  PUBLIC SECTION.
    METHODS: QUERY.
ENDCLASS.

CLASS MODEL IMPLEMENTATION.
    METHOD QUERY.
      SELECT * FROM MARA INTO TABLE IT UP TO 50 ROWS.
    ENDMETHOD.
ENDCLASS.

CLASS CTRL DEFINITION.
  PUBLIC SECTION.
    DATA : MODEL TYPE REF TO MODEL.
    METHODS: CONSTRUCTOR,
             DSP_REPORT.
    PRIVATE SECTION.
      DATA : GRID TYPE REF TO CL_SALV_TABLE.
      METHODS: SHOW_GRID.
ENDCLASS.

CLASS CTRL IMPLEMENTATION.
  METHOD CONSTRUCTOR.
    CREATE OBJECT MODEL.
  ENDMETHOD.

  METHOD DSP_REPORT.
      CALL METHOD MODEL->QUERY.
      SHOW_GRID( ).
  ENDMETHOD.

  METHOD SHOW_GRID.
      CL_SALV_TABLE=>FACTORY( IMPORTING R_SALV_TABLE = GRID CHANGING T_TABLE = IT ).
      GRID->DISPLAY( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
DATA : LR_CTRL TYPE REF TO CTRL.
CREATE OBJECT LR_CTRL.
CALL METHOD LR_CTRL->DSP_REPORT.

 



 

Author: Chetanpal Singh
Submitted: December 14, 2006

As the number of calls to programs (or class-methods) that raise class-based exceptions increases, so can (highly likely) be the code to handle the exceptions expected from the called programs. This article presents an approach and utility to simplify capturing, evaluating and communicating class-based exceptions.

 Simplifying the Capturing, Evaluating, and Communicating Class-Based Except

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclasses   LINE-SIZE 120.

*----------------------------------------------------------------------*
*       CLASS parentclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS parentclass DEFINITION .
  PUBLIC SECTION.
    DATA : commondata(30) TYPE c VALUE 'Accessible to all'.
    METHODS : showval.
  PROTECTED SECTION.
    DATA : protectdata(40) TYPE c VALUE 'Protected data'.
  PRIVATE SECTION.
    DATA : privatedata(30) TYPE c VALUE 'Private data'.
ENDCLASS.                    "parentclass DEFINITION
*----------------------------------------------------------------------*
*       CLASS parentclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS parentclass IMPLEMENTATION.
  METHOD : showval.
    WRITE:/5 'All data from parentclass shown:-'.
    WRITE:/ sy-uline.
    WRITE:/5 commondata,
          /5 protectdata,
          /5 privatedata.
  ENDMETHOD.                    ":
ENDCLASS.                    "parentclass IMPLEMENTATION
*----------------------------------------------------------------------*
*       CLASS childclass DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS childclass DEFINITION INHERITING FROM parentclass.
  PUBLIC SECTION .
    METHODS : subval.
ENDCLASS.                    "childclass DEFINITION
*----------------------------------------------------------------------*
*       CLASS childclass IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS childclass IMPLEMENTATION.
  METHOD : subval.
    SKIP 1.
    WRITE:/5 'Data of parent shown from child-'.
    WRITE:/5 sy-uline.
    WRITE:/5 commondata,
          /5 protectdata.
    commondata = 'Public data changed in subclass'.
    protectdata = 'Protected data changed in subclass'.
    WRITE:/5 sy-uline.
    WRITE:/5 commondata,
          /5 protectdata.
  ENDMETHOD.                    ":
ENDCLASS.                    "childclass IMPLEMENTATION

START-OF-SELECTION.

  DATA : parent TYPE REF TO parentclass ,
        child TYPE REF TO childclass .
  CREATE OBJECT : parent ,
                  child .
  CALL METHOD : parent->showval ,
                child->subval.
  SKIP 2.
  parent->commondata = 'User changing public data'.
  WRITE:/5 parent->commondata.

Create a Class dynamically by passing class name at run time:

CREATE OBJECT

CREATE OBJECT oref
   TYPE class|(name)
    parameter list.

... PARAMETER-TABLE ptab

... EXCEPTION-TABLE etab

Effect

We can use these additions when the instanced class is specified dynamically in name. You use the special internal tables ptab and etab to assign actual parameters to the input parameters of the instance constructor or return values to not class-based exceptions.
The internal tables ptab and etab must be defined with reference to the tables ABAP_PARMBIND_TAB and ABAP_EXCPBIND_TAB.
Sample program where the class name is passed as variable and the exporting parameter is passed in Parameter-table.

REPORT z_dyn_classname.

CLASS cl_abap_objectdescr DEFINITION LOAD.
DATA: container TYPE REF TO object,
      pic_container TYPE REF TO cl_gui_container,
      exc_ref TYPE REF TO cx_root,
      lo_cast_error TYPE REF TO cx_sy_move_cast_error,
      exc_text TYPE string.
* Picture Control
DATA picture TYPE REF TO cl_gui_picture.

DATA: class TYPE string VALUE 'CL_GUI_DIALOGBOX_CONTAINER',
      ptab TYPE abap_parmbind_tab,
      ptab_line TYPE abap_parmbind.

CALL SCREEN 100.

*----------------------------------------------------------------------*
*  MODULE STATUS_0100 OUTPUT
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.

  ptab_line-name = 'WIDTH'.
  ptab_line-kind = cl_abap_objectdescr=>exporting.
  GET REFERENCE OF 1000 INTO ptab_line-value.
  INSERT ptab_line INTO TABLE ptab.

  ptab_line-name = 'PARENT'.
  ptab_line-kind = cl_abap_objectdescr=>exporting.
  GET REFERENCE OF cl_gui_container=>desktop
                INTO ptab_line-value.
  INSERT ptab_line INTO TABLE ptab.

  ptab_line-name = 'HEIGHT'.
  ptab_line-kind = cl_abap_objectdescr=>exporting.
  GET REFERENCE OF 300 INTO ptab_line-value.
  INSERT ptab_line INTO TABLE ptab.

  TRY.
      CREATE OBJECT container TYPE (class)
        PARAMETER-TABLE ptab.
    CATCH cx_sy_create_object_error INTO exc_ref.
      exc_text = exc_ref->get_text( ).
      MESSAGE exc_text TYPE 'I'.
  ENDTRY.
  TRY.
* Now, the Widening cast to move the reference from the
* generic object to dialogbox parent container class (more specific class).
      pic_container ?= container.
    CATCH cx_sy_move_cast_error INTO lo_cast_error.
      WRITE: / 'Widening cast failed'.
  ENDTRY.

  CREATE OBJECT picture
    EXPORTING
      parent = pic_container.

* Request an URL from the data provider by exporting the pic_data.
  DATA url(255).
  CLEAR url.
  PERFORM load_pic_from_db CHANGING url.

* load picture
  CALL METHOD picture->load_picture_from_url
    EXPORTING
      url = url.

  CALL METHOD cl_gui_cfw=>flush
    EXCEPTIONS
      cntl_system_error = 1
      cntl_error        = 2.
  IF sy-subrc <> 0.
* error handling
  ENDIF.
ENDMODULE.                    "STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
*&      Form  load_pic_from_db
*&---------------------------------------------------------------------*
FORM load_pic_from_db CHANGING url.
  DATA query_table LIKE w3query OCCURS 1 WITH HEADER LINE.
  DATA html_table LIKE w3html OCCURS 1.
  DATA return_code LIKE w3param-ret_code.
  DATA content_type LIKE  w3param-cont_type.
  DATA content_length LIKE  w3param-cont_len.
  DATA pic_data LIKE w3mime OCCURS 0.
  DATA pic_size TYPE i.

  REFRESH query_table.
  query_table-name = '_OBJECT_ID'.
  query_table-value = 'ENJOYSAP_LOGO'.
  APPEND query_table.

  CALL FUNCTION 'WWW_GET_MIME_OBJECT'
    TABLES
      query_string        = query_table
      html                = html_table
      mime                = pic_data
    CHANGING
      return_code         = return_code
      content_type        = content_type
      content_length      = content_length
    EXCEPTIONS
      object_not_found    = 1
      parameter_not_found = 2
      OTHERS              = 3.
  IF sy-subrc = 0.
    pic_size = content_length.
  ENDIF.

  CALL FUNCTION 'DP_CREATE_URL'
    EXPORTING
      type     = 'image'
      subtype  = cndp_sap_tab_unknown
      size     = pic_size
      lifetime = cndp_lifetime_transaction
    TABLES
      data     = pic_data
    CHANGING
      url      = url
    EXCEPTIONS
      OTHERS   = 1.

ENDFORM.                    "load_pic_from_db
 
*&---------------------------------------------------------------------*
*& Report  Y_MY_CASE_STUDY                                     *
*&                                                                     *
*&---------------------------------------------------------------------*
*& Simple example for handling events in Object Oriented Technique     *                                                                *
*& using buyer and seller scenario                                     *
*&---------------------------------------------------------------------*
REPORT  y_my_case_study                 .
*---------------------------------------------------------------------*
*       Global Data
*---------------------------------------------------------------------*
DATA: t_stock TYPE c LENGTH 6,   " Total Availabale Stock- Screen Field
      ok_code TYPE sy-ucomm.     " Contains Function Code
*---------------------------------------------------------------------*
*       CLASS storage_location DEFINITION
*---------------------------------------------------------------------*
* This class represents storage location
*---------------------------------------------------------------------*
CLASS storage_location DEFINITION.
  PUBLIC SECTION.
    METHODS: display.                      " Method to display available stock
    EVENTS : threshold,                    " Event to warn when threshold value of stock reached
             max,                          " Event to warn when maximum value of stock reached
             no_stock.                     " Event to warn when stock is zero
  PROTECTED SECTION.
    CLASS-DATA : w_stock TYPE i VALUE 0.   " Available stock
    DATA : w_max TYPE i VALUE 10,          " Maximum capacity of storage location
           w_threshold TYPE i VALUE 8.     " Threshold Value of stock
ENDCLASS.                    "storage_location DEFINITION
*---------------------------------------------------------------------*
*       CLASS storage_location IMPLEMENTATION
*---------------------------------------------------------------------*
* Implementation of storage_location class
*---------------------------------------------------------------------*
CLASS storage_location IMPLEMENTATION.
  METHOD display.
    WRITE : / 'Available Stock : ', w_stock.
  ENDMETHOD.                               "display
ENDCLASS.                    "storage_location IMPLEMENTATION
*---------------------------------------------------------------------*
*       CLASS sales DEFINITION
*---------------------------------------------------------------------*
* Seller class, class responsible for selling the available stock
*---------------------------------------------------------------------*
CLASS sales DEFINITION INHERITING FROM storage_location.
  PUBLIC SECTION.
    METHODS: sell_the_product.              " Method responsible for selling the stock
ENDCLASS.                    "sales DEFINITION
*---------------------------------------------------------------------*
*       CLASS sales IMPLEMENTATION
*---------------------------------------------------------------------*
* Seller class implementation
*---------------------------------------------------------------------*
CLASS sales IMPLEMENTATION.
  METHOD sell_the_product.
    IF w_stock = 0.                         " Raise Event no_stock when stock is zero
      RAISE EVENT no_stock.
    ELSE.
      w_stock = w_stock - 1.                " Else decrement the available stock
      t_stock = w_stock.
    ENDIF.
  ENDMETHOD.                    "sale_the_product
ENDCLASS.                    "sales IMPLEMENTATION
*---------------------------------------------------------------------*
*       CLASS buying DEFINITION
*---------------------------------------------------------------------*
* Buyer class, class responsible for buying the stock
*---------------------------------------------------------------------*
CLASS buying DEFINITION INHERITING FROM storage_location.
  PUBLIC SECTION.
    METHODS: buy_the_product.               " Buys the stock
ENDCLASS.                    "buying DEFINITION
*---------------------------------------------------------------------*
*       CLASS buying IMPLEMENTATION
*---------------------------------------------------------------------*
* Buyer class implementation
*---------------------------------------------------------------------*
CLASS buying IMPLEMENTATION.
  METHOD buy_the_product.
    IF w_stock = w_max.                    " Raises event max when stock is maximum
      RAISE EVENT max.
    ELSE.
      IF w_stock GE w_threshold.           " Raises event threshold when stock reaches nearer to maximum
        RAISE EVENT threshold.             " example if max is 10 then it raises when stock reaches 8
      ENDIF.
      w_stock = w_stock + 1.               " Else buy the stock
      t_stock = w_stock.
    ENDIF.
  ENDMETHOD.                    "buy_the_product
ENDCLASS.                    "buying IMPLEMENTATION
*---------------------------------------------------------------------*
*       CLASS event_handler DEFINITION
*---------------------------------------------------------------------*
* Class to handle the events no_stock, threshold and max.
*---------------------------------------------------------------------*
CLASS event_handler DEFINITION.
  PUBLIC SECTION.
    METHODS : max_handler FOR EVENT max OF storage_location,
              threshold_handler FOR EVENT threshold OF storage_location,
              no_stock_handler FOR EVENT no_stock OF storage_location.
ENDCLASS.                    "event_handler DEFINITION
*---------------------------------------------------------------------*
*       CLASS event_handler IMPLEMENTATION
*---------------------------------------------------------------------*
* Event-handler class implementation
*---------------------------------------------------------------------*
CLASS event_handler IMPLEMENTATION.
  METHOD max_handler.
    MESSAGE 'Stop buying the product, No space at storage location' TYPE 'I'.
  ENDMETHOD.                    "max_handler
  METHOD threshold_handler.
    MESSAGE 'Threshold Value Reached, Check storage space before next buying' TYPE 'I'.
  ENDMETHOD.                    "threshold_handler
  METHOD no_stock_handler.
    MESSAGE 'No product available for sale. Buy the product to sell' TYPE 'I'.
  ENDMETHOD.                    "no_stock_handler
ENDCLASS.                    "event_handler IMPLEMENTATION
*---------------------------------------------------------------------*
*       START-OF-SELECTION
*---------------------------------------------------------------------*
START-OF-SELECTION.
  DATA : buyer TYPE REF TO buying,               " Buyer Object
         seller TYPE REF TO sales,               " Seller object
         ehandler TYPE REF TO event_handler.     " Event handler object
  CREATE OBJECT : buyer,                         " Creation of all the above mentioned objects
                  seller,
                  ehandler.
  SET HANDLER ehandler->max_handler              " Assignes all event handler methods to
              ehandler->threshold_handler        " event handler object
              ehandler->no_stock_handler
              FOR ALL INSTANCES.
**** Initial screen **********
  CALL SCREEN 500.
*&---------------------------------------------------------------------*
*&      Module  STATUS_0500  OUTPUT
*&---------------------------------------------------------------------*
* Status module of screen 500
*----------------------------------------------------------------------*
MODULE status_0500 OUTPUT.
*---------------------------------------------------------------------*
* sets status with 3 buttons on application toolbar, 1- Buyer 2- Seller
* 3- Exit
*---------------------------------------------------------------------*
  SET PF-STATUS 'Ys_MYCASESTUDY'.
  SET TITLEBAR '001'.                       " Title - Buyer Seller Problem
ENDMODULE.                 " STATUS_0500  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0500  INPUT
*&---------------------------------------------------------------------*
* This module is used to handle all user-commands
*----------------------------------------------------------------------*
MODULE user_command_0500 INPUT.
  CASE ok_code.
    WHEN 'BUYER'.                               " When Buyer Button is pressed
      CALL METHOD buyer->buy_the_product.
    WHEN 'SELLER'.                              " When Seller Button is pressed
      CALL METHOD seller->sell_the_product.
    WHEN 'EXIT'.                                " When Exit Button is pressed
      LEAVE PROGRAM.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0500  INPUT
 

Author:  Timo John ( cimt-ag )
Submitted:        2010-04-14
Related Links:

In other development tools like Eclipse it is pretty standard that you are able to generate all GET and SET methodsfor your classes.
I decided to write a Report program that does the generation of GET and SET methods for you (source code below)

The  report will ask you for class in the Selection Screen. While running it,
all attributes are analysed and the Methods are created and activated right away.

Aditionaly there are 2 other programms needed: Report Z_SRCGEN_GET_SET  and Include Z_TMPL_GET_SET which are also listed below. 

TO-DO (for me):
1. Option to delete old GET / SET Methods
2. Get rid of German in the Code

The program is new, so I look forward for your hints or improvements. 
Kind Regards.

Timo John


Z_TJ_GENARATE_GET_SET

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*& Report  Z_TJ_GENARATE_GET_SET
*&
*&---------------------------------------------------------------------*
*& Author:  Timo John
*& Contact: Timo.John@cimt-ag.de
*&
*& Program to gernerate GET and SET Methods for ABAP Object Classes.
*&
*& State: Early Beta. !!!
*&
*& This report directly generates GET and SET Methods for all attributes
*& in the selected Class.
*&
*& Methods that exist are not touched.
*&
*&  Precondition:
*&    1. The Attributes have to follow a naming convention starting
*&       with "XX_" like gf_myGlobalField
*&
*&
*&  TO-DO:
*&    1. Enable option to delete old methods there the attribute is gone.
*&
*&
*&---------------------------------------------------------------------*
REPORT  z_tj_genarate_get_set.

TYPE-POOLS: seoo,
            ostyp.

DATA:     gf_count          TYPE i,
          lf_method_name    TYPE string,
          gf_mtdname        TYPE seocpdname,
          gf_classname      TYPE seoclskey,
          ls_method         TYPE seoo_method_r,
          lt_parameters     TYPE seos_parameters_r,
          ls_parameters     TYPE seos_parameter_r,
          lt_exceptions     TYPE seos_exceptions_r,
          gt_attributes     TYPE seoo_attributes_r,
          ls_attributes     LIKE LINE OF gt_attributes.

DATA:     ls_meth_key           TYPE seocpdkey,
          gt_impl_data          TYPE abap_parmbind_tab,
          ls_data               LIKE LINE OF gt_impl_data,
          gf_attribute          TYPE objname.

DATA:   gf_temlate TYPE schemename,
        gc_templ_prog TYPE schemeprog VALUE 'Z_TMPL_GET_SET',
        gc_build TYPE ostyp_build VALUE '000001'.

DATA: gi_orsal       TYPE REF TO cl_osral_oo,
      gi_naming      TYPE REF TO if_oo_class_incl_naming.


SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE text-b01.
PARAMETERS: so_clnam TYPE seoclass-clsname MEMORY ID class MATCHCODE OBJECT sfbeclname.
SELECTION-SCREEN END OF BLOCK b01.


* Map Parameter of Classname
gf_classname =  so_clnam.

* Setup:
gi_naming ?= cl_oo_include_naming=>get_instance_by_name( so_clnam ).


* Start Generation class
gi_orsal = cl_osral_oo=>get_repository_obj( gf_classname ).
gi_orsal->set_generator('Z_SRCGEN_GET_SET').

* Get information about Class
CALL FUNCTION 'SEO_CLASS_TYPEINFO_GET'
  EXPORTING
    clskey     = gf_classname
  IMPORTING
    attributes = gt_attributes
  EXCEPTIONS
    OTHERS     = 1.

* Set common data for all methods:
ls_method-clsname           = gf_classname.
ls_parameters-clsname       = gf_classname.
ls_method-state             = seoc_state_implemented. "1.

*  for implementation
ls_meth_key-clsname = gf_classname.

LOOP AT gt_attributes INTO ls_attributes.

* Data for both Methods:
*  for parameters
  ls_parameters-typtype       = ls_attributes-typtype.  " Type of parametery type type, like ref to etc ...)
  ls_parameters-sconame       = ls_attributes-cmpname.  "name of current attribut
  TRANSLATE ls_parameters-sconame TO LOWER CASE.

  IF ls_attributes-cmpname+2(1) = '_'.
    lf_method_name = ls_attributes-cmpname+3.
  ELSE.
    lf_method_name = ls_attributes-cmpname.
  ENDIF.

** SET defintion *****************************
* check if method exists
  CONCATENATE 'SET_' lf_method_name INTO ls_method-cmpname.
  gf_mtdname = ls_method-cmpname.
  CALL METHOD gi_naming->get_include_by_mtdname
    EXPORTING
      mtdname = gf_mtdname
    EXCEPTIONS
      OTHERS  = 1.
  IF sy-subrc <> 0 .

    ls_method-exposure = seoc_exposure_public. "2.

* Parameters for SET
    ls_parameters-cmpname       = ls_method-cmpname.
    ls_parameters-sconame(1)  = 'i'.
    ls_parameters-type        = ls_attributes-type.
    ls_parameters-pardecltyp  = seos_pardecltyp_importing.
    APPEND ls_parameters TO lt_parameters.

* Create method SET
    gi_orsal->method_def_modify( i_method     = ls_method
                                 i_parameters = lt_parameters
                                 i_exceptions = lt_exceptions ).

**********************************************************************
* Create method implementation SET.
    ls_meth_key-cpdname = ls_method-cmpname.

    ls_data-name   =  'CLASS_NAME'.
    GET REFERENCE OF gf_classname INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'SOURCE'.
    GET REFERENCE OF gc_templ_prog INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'BUILD'.
    GET REFERENCE OF gc_build INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gf_temlate = 'PM_SET_METHOD'.
    ls_data-name   =  'TEMPLATE'.
    GET REFERENCE OF gf_temlate INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'IMPORTING_VAR'.
    GET REFERENCE OF ls_parameters-sconame INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gf_attribute = ls_attributes-cmpname.
    ls_data-name   =  'ATTRIBUTE'.
    GET REFERENCE OF gf_attribute INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gi_orsal->method_imp_create( i_method    = ls_meth_key
                                 i_data      = gt_impl_data ).
    gf_count = gf_count + 1.
  ENDIF.

    CLEAR: gt_impl_data,
           lt_parameters.

**********************************************************************
** GET defintion

  CONCATENATE 'GET_' ls_attributes-cmpname+3 INTO ls_method-cmpname.
* check if method exist: IF than skip creation
  gf_mtdname = ls_method-cmpname.
  CALL METHOD gi_naming->get_include_by_mtdname
    EXPORTING
      mtdname = gf_mtdname
    EXCEPTIONS
      OTHERS  = 1.
  IF sy-subrc <> 0.
*   parameters for GET
    ls_parameters-cmpname     = ls_method-cmpname.
    ls_parameters-sconame(1)  = 'r'.
    ls_parameters-pardecltyp  = seos_pardecltyp_returning .
    APPEND ls_parameters TO lt_parameters.

*   create method
    gi_orsal->method_def_modify( i_method     = ls_method
                                 i_parameters = lt_parameters
                                 i_exceptions = lt_exceptions ).

**********************************************************************
*   getter implementatiuon
    ls_meth_key-cpdname = ls_method-cmpname.

    ls_data-name   =  'CLASS_NAME'.
    GET REFERENCE OF gf_classname INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'SOURCE'.
    GET REFERENCE OF gc_templ_prog INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'BUILD'.
    GET REFERENCE OF gc_build INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gf_temlate     = 'PM_GET_METHOD'.
    ls_data-name   =  'TEMPLATE'.
    GET REFERENCE OF gf_temlate INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    ls_data-name   =  'RETURNING_VAR'.
    GET REFERENCE OF ls_parameters-sconame INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gf_attribute = ls_attributes-cmpname.
    ls_data-name   =  'ATTRIBUTE'.
    GET REFERENCE OF gf_attribute INTO ls_data-value.
    INSERT ls_data INTO TABLE gt_impl_data.

    gi_orsal->method_imp_create( i_method    = ls_meth_key
                                 i_data      = gt_impl_data ).
**********************************************************************
    CLEAR: gt_impl_data,
          lt_parameters.

    gf_count = gf_count + 1.
  ENDIF.

ENDLOOP.

* Speichern !
gi_orsal->save( ).


MESSAGE s037(bsp_wd_tools) WITH gf_count.
*   &1 Methode(n) ist/sind generiert

Z_SRCGEN_GET_SET Generator Report

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*& Report  Z_SRCGEN_GET_SET                                            *
*&                                                                     *
*&---------------------------------------------------------------------*
*&                                                                     *
*&---------------------------------------------------------------------*
REPORT Z_SRCGEN_GET_SET .
TYPE-POOLS: SEOP, OSTYP, OSCON, ABAP.
** global field symbols
field-symbols:  <CLNAME>    type seoclskey, "Name der Anwendungsklasse
                <SOURCE>    type schemeprog, "Source
                <TEMPLATE>  type schemename, "Template
                <BUILD>     type OSTYP_BUILD, "BUILD
                <ATTRIBUTE> type OBJNAME,
                <ATTRIBUTE_LIST> type OSTYP_OBJNAME_TAB,
                <ATTRIBUTE_TNOUPD> type OS_BOOLEAN,
                <IMPORTING_VAR> type OBJNAME,
                <RETURNING_VAR> type OBJNAME.
** variables for scheme instantiation
types: begin of TYP_ATTRIBUTE,
         NAME type OBJNAME,
       end of TYP_ATTRIBUTE.
data: ATTRIBUTE_TAB type standard table of TYP_ATTRIBUTE
                         with header line, "#EC *
      ATTRIBUTE     type OBJNAME, "#EC NEEDED
      ATTRIBUTE_TNOUPD type OS_BOOLEAN value OSCON_FALSE, "#EC NEEDED
      ATTR_NS       type OBJNAME, "#EC NEEDED
      ATTR_NA       type OBJNAME, "#EC NEEDED
      CLASS_NAME    type seoclskey, "#EC NEEDED
      IMPORTING_VAR type OBJNAME, "#EC NEEDED
      RETURNING_VAR type OBJNAME. "#EC NEEDED
data: THISPROG  like SY-REPID.
***************  Subroutines data access  ************************
data DATA       type abap_parmbind.
form SET_DATA
  using DATA_BLOCK type ABAP_PARMBIND_TAB. "#EC CALLED
  data: FDPOS type syfdpos.
  loop at DATA_BLOCK into DATA.
    case DATA-name.
      when 'CLASS_NAME'.
        assign DATA-value->* TO <CLNAME>.
        CLASS_NAME = <CLNAME>.
      when 'SOURCE'.
        assign DATA-value->* TO <source>.
      when 'TEMPLATE'.
        assign DATA-value->* TO <template>.
      when 'BUILD'.
        assign DATA-value->* TO <build>.
      when 'ATTRIBUTE'.
        assign DATA-value->* TO <ATTRIBUTE>.
        ATTRIBUTE = <ATTRIBUTE>.
      when 'ATTRIBUTE_TNOUPD'.
        assign DATA-value->* TO <ATTRIBUTE_TNOUPD>.
        ATTRIBUTE_TNOUPD = <ATTRIBUTE_TNOUPD>.
      when 'ATTRIBUTES'.
        refresh ATTRIBUTE_TAB.
        assign DATA-value->* TO <ATTRIBUTE_LIST>.
        append lines of <ATTRIBUTE_LIST> to ATTRIBUTE_TAB.
      when 'IMPORTING_VAR'.
        assign DATA-value->* TO <IMPORTING_VAR>.
        IMPORTING_VAR = <IMPORTING_VAR>.
      when 'RETURNING_VAR'.
        assign DATA-value->* TO <RETURNING_VAR>.
        RETURNING_VAR = <RETURNING_VAR>.
    endcase. "DATA-name
  endloop. "at DATA_BLOCK
* * Namespace
  clear ATTR_NS.
  ATTR_NA = ATTRIBUTE.
  if ATTRIBUTE(1) = '/'.
    if ATTRIBUTE+1 ca '/'.
      FDPOS = SY-FDPOS + 2.
      ATTR_NS = ATTRIBUTE(FDPOS).
      ATTR_NA = ATTRIBUTE+FDPOS.
    endif.
  endif.
endform. "SET_DATA

FORM get_data
  CHANGING data_block TYPE ABAP_PARMBIND_TAB. "#EC CALLED
  data-name  = 'CLASS_NAME'.
  GET REFERENCE OF <clname> INTO data-value.
  INSERT data INTO TABLE data_block.
  data-name  = 'SOURCE'.
  GET REFERENCE OF <source> INTO data-value.
  INSERT data INTO TABLE data_block.
  data-name  = 'TEMPLATE'.
  GET REFERENCE OF <template> INTO data-value.
  INSERT data INTO TABLE data_block.
ENDFORM. "get_data

***************  Subroutine for instantiation  ************************
FORM method
  TABLES t_coding            TYPE seop_source. "#EC CALLED
  REFRESH  t_coding.
  thisprog = sy-repid.
  CALL FUNCTION 'SCHEME_INSTANTIATE'
       EXPORTING  CALLING_PROGRAM      = thisprog
                  SCHEME_PROGRAM       = <source>
                  SCHEME_NAME          = <template>
       TABLES     RESULT_TAB           = t_coding
       EXCEPTIONS SCHEMEPROG_NOT_FOUND = 1
                  SCHEME_NOT_FOUND     = 2
                  SCHEME_SYNTAX_ERROR  = 3
                  GENERATE_ERROR       = 4
                  FORCED_LINESPLIT     = 5
                  TABLE_NOT_EXISTS     = 6
                  OTHERS               = 7.
  if <build> is assigned.
    concatenate '***BUILD' <build> into t_coding separated by space.
    insert t_coding index 1.
  endif.
ENDFORM. "method

Z_TMPL_GET_SET Template Include

***INCLUDE Z_TMPL_GET_SET
***BUILD 000001
*
* Z ABAP OO Template:
* To generate Getter and Setter
*
/>PM_SET_METHOD</
* This is a generated SET Method for attribute: &ATTRIBUTE&:
  &ATTRIBUTE& = &IMPORTING_VAR&.
/>END</
/>PM_GET_METHOD</
* This is a generated GET Method for attribute: &ATTRIBUTE&:
   &RETURNING_VAR& = &ATTRIBUTE&.
/>END</

List of all pages

Pages at first level

* This program will make you clear about the usage of GET CURSOR FIELD and SET PARAMETER ID statements.

Requirement: 

Create a basic list to display orders for the given customers in the selection screen and perform the following: (Display the customer number, customer name and the order number on the basic list)
Provide two push buttons 'Customer Info' and 'Order Info' on the basic list.
Display the transaction 'Display customer' when the user places the cursor on the customer and clicks on the button 'Customer Info'. The customer number should be displayed on the initial screen of the transaction.
Display the transaction 'Display Sales order' when the user places the cursor on the order and clicks on the button 'Order Info'. The order number should be displayed on the initial screen of the transaction.
On line selection, display the order details. (Order details include: Item number, Material number, ordered quantity, and price.)

Note:

 Create a PF STATUS with two pushbuttons of function codes CUSTOMER and ORDER.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT ZDEMO.
*Table declaration...................................................
TABLES:
 vbak.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-003.
SELECT-OPTIONS:
  s_kunnr FOR vbak-kunnr.
SELECTION-SCREEN END OF BLOCK b1.
*--------------------------------------------------------------------*
*            TYPE DECLARATION TO HOLD CUSTOMER DETAILS
*--------------------------------------------------------------------*
TYPES:
 BEGIN OF type_s_cust,
  kunnr TYPE kna1-kunnr,               " Customer Number
  name1 TYPE kna1-name1,               " Customer Name
  vbeln TYPE vbak-vbeln,               " Order Number
 END OF type_s_cust,
*--------------------------------------------------------------------*
*              TYPE DECLARATION TO HOLD ORDER DETAILS
*--------------------------------------------------------------------*
 BEGIN OF type_s_order,
  posnr TYPE vbap-posnr,               " Sales Document Item
  matnr TYPE vbap-matnr,               " Material Number
  kwmeng TYPE vbap-kwmeng,             " Ordered Quantity
  meins TYPE vbap-meins,               " Unit of Measure
  netpr TYPE vbap-netpr,               " Net Price
  waerk TYPE vbap-waerk,               " Currency
 END OF type_s_order.
DATA:
*--------------------------------------------------------------------*
*                FIELD STRING TO HOLD CUSTOMER DETAILS
*--------------------------------------------------------------------*
 fs_cust TYPE type_s_cust,
*--------------------------------------------------------------------*
*               INTERNAL TABLE TO HOLD CUSTOMER DETAILS
*--------------------------------------------------------------------*
 t_cust LIKE TABLE OF fs_cust,
*--------------------------------------------------------------------*
*                 FIELD STRING TO HOLD ORDER DETAILS
*--------------------------------------------------------------------*
 fs_order TYPE type_s_order,
*--------------------------------------------------------------------*
*                 INTERNAL TABLE TO HOLD ORDER DETAILS
*--------------------------------------------------------------------*
 t_order LIKE TABLE OF fs_order,
 w_field(20).                          " Cursor Position
*--------------------------------------------------------------------*
*                        START-OF-SELECTION
*--------------------------------------------------------------------*
START-OF-SELECTION.
  SET PF-STATUS 'CUST'.
  PERFORM selection.
*--------------------------------------------------------------------*
*                         END-OF-SELECTION
*--------------------------------------------------------------------*
END-OF-SELECTION.
  PERFORM display.
*--------------------------------------------------------------------*
*                             TOP-OF-PAGE
*--------------------------------------------------------------------*
TOP-OF-PAGE.
  PERFORM top-of-page.
*--------------------------------------------------------------------*
*                         AT LINE-SELECTION
*--------------------------------------------------------------------*
AT LINE-SELECTION.
  PERFORM at_line_selection.
*--------------------------------------------------------------------*
*              AT LINE-SELECTION DURING LINE SELECTION
*--------------------------------------------------------------------*
TOP-OF-PAGE DURING LINE-SELECTION.
  PERFORM top_of_page_during.
*--------------------------------------------------------------------*
*                         AT USER-COMMAND
*--------------------------------------------------------------------*
AT USER-COMMAND.
  PERFORM user_command.
*&---------------------------------------------------------------------*
*&      Form  SELECTION
*&---------------------------------------------------------------------*
* Subroutine to fetch data from KNA1 and VBAK
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM selection .
  SELECT   a~kunnr                     " Customer Number
           a~name1                     " Customer Name
           b~vbeln                     " Order Number
           FROM kna1 AS a
           INNER JOIN vbak AS b
           ON a~kunnr = b~kunnr
           INTO CORRESPONDING FIELDS OF TABLE t_cust
           WHERE a~kunnr IN s_kunnr.
ENDFORM.                               " SELECTION
*&---------------------------------------------------------------------*
*&      Form  DISPLAY
*&---------------------------------------------------------------------*
* Subroutine to display data
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM display .
  LOOP AT t_cust INTO fs_cust.
    WRITE:
      /1 fs_cust-kunnr COLOR 4,
      20 fs_cust-name1 COLOR 4,
      40 fs_cust-vbeln COLOR 4.
    HIDE:
    fs_cust-kunnr,
    fs_cust-name1,
    fs_cust-vbeln.
  ENDLOOP.                             " LOOP AT T_CUST
ENDFORM.                               " DISPLAY
*&---------------------------------------------------------------------*
*&      Form  TOP-OF-PAGE
*&---------------------------------------------------------------------*
* Subroutine for heading
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM top-of-page .
  WRITE:
       /1 text-011 COLOR 5,
       20 text-005 COLOR 5,
       40 text-006 COLOR 5.
ENDFORM.                               " TOP-OF-PAGE
*&---------------------------------------------------------------------*
*&      Form  AT_LINE_SELECTION
*&---------------------------------------------------------------------*
* Subroutine to fetch data from VBAP
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM at_line_selection .
  SELECT  posnr                        " Sales Document Item
          matnr                        " Material Number
          kwmeng                       " Ordered Quantity
          meins                        " Unit of Measure
          netpr                        " Net Price
          waerk                        " Currency
          FROM vbap INTO CORRESPONDING FIELDS OF TABLE t_order
          WHERE vbeln EQ fs_cust-vbeln.
  CLEAR fs_cust-vbeln.
  IF sy-subrc <> 0.
    MESSAGE text-004 TYPE 'I'.
  ENDIF.                               " IF SY-SUBRC <> 0.
  LOOP AT t_order INTO fs_order .
    WRITE:
   /1 fs_order-posnr COLOR 4,
   20 fs_order-matnr COLOR 4,
   27 fs_order-kwmeng UNIT fs_order-meins COLOR 4,
   53 fs_order-netpr CURRENCY fs_order-waerk COLOR 4.
  ENDLOOP.                             " LOOP AT T_ORDER
ENDFORM.                               " AT_LINE_SELECTION
*&---------------------------------------------------------------------*
*&      Form  TOP_OF_PAGE_DURING
*&---------------------------------------------------------------------*
* Subroutine for secondary list heading
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM top_of_page_during .
  WRITE:
     /1 text-007 COLOR 5,
      20 text-008 COLOR 5,
      40 text-009 COLOR 5,
      60 text-010 COLOR 5.
ENDFORM.                               " TOP_OF_PAGE_DURING
*&---------------------------------------------------------------------*
*&      Form  USER_COMMAND
*&---------------------------------------------------------------------*
* Subroutine for pushbuttons
*----------------------------------------------------------------------*
* There are no interface parameters to be passed to this subroutine
*----------------------------------------------------------------------*
FORM user_command .
  CASE sy-ucomm.
    WHEN 'CUSTOMER'.
      GET CURSOR FIELD w_field.
      IF w_field EQ 'FS_CUST-KUNNR'.
        SET PARAMETER ID 'KUN' FIELD fs_cust-kunnr.
        CALL TRANSACTION 'VD03'.
      ELSEIF w_field NE 'FS_CUST-KUNNR'.
        MESSAGE text-001 TYPE 'E'.
      ENDIF.                           " IF W_FIELD
    WHEN 'ORDER'.
      GET CURSOR FIELD w_field.
      IF w_field EQ 'FS_CUST-VBELN'.
        SET PARAMETER ID 'AUN' FIELD fs_cust-vbeln.
        CALL TRANSACTION 'VA03'.
      ELSEIF  w_field NE 'FS_CUST-VBELN'.
        MESSAGE text-002 TYPE 'E'.
      ENDIF.                           " IF W_FIELD
  ENDCASE.                             " CASE SY-UCOMM
ENDFORM.                               " USER_COMMAND

Here I will discuss about Memory id concept .Concept of memory id can be very useful in different cases. In cases where we need to transfer values from one program to other program

which are not having any connection from which we can take those values. we use export- imort for this purpose.

Here is the form where this concept has been used :

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FORM  f_fetch_details   TABLES  fp_it_input_tab STRUCTURE itcsy
                                fp_it_ouput_tab STRUCTURE itcsy.

  FIELD-SYMBOLS: <l_fs_output>  TYPE itcsy.

  READ TABLE fp_it_input_tab INTO l_wa_input INDEX 1.
  IF sy-subrc EQ 0.
    l_v_belnr = l_wa_input-value.
  ENDIF.

  IMPORT v_id TO l_it_with_item FROM MEMORY ID l_v_belnr.
  IF sy-subrc IS INITIAL.
    FREE MEMORY ID l_v_belnr.
  ENDIF.

  IF l_it_with_item IS INITIAL.

    SELECT  augbl FROM with_item INTO TABLE tb_clrng_doc
      WHERE belnr EQ l_v_belnr.

    SORT tb_clrng_doc.
    DELETE ADJACENT DUPLICATES FROM tb_clrng_doc.

    IF NOT tb_clrng_doc[] IS INITIAL.

      SELECT witht INTO TABLE l_it_with_item
          FROM with_item
     FOR ALL ENTRIES IN tb_clrng_doc
          WHERE belnr = tb_clrng_doc-augbl
          AND   bukrs = `1065`
          AND NOT ctnumber = ``.
    ELSE.

      SELECT witht INTO TABLE l_it_with_item
          FROM with_item
          WHERE belnr = l_v_belnr
         AND   bukrs = `1065`
         AND NOT ctnumber = ``.
    ENDIF.
  ENDIF.

*  read the contents at index 1
  CLEAR wa_it_with_item.
  READ TABLE l_it_with_item INTO wa_it_with_item INDEX 1.
  IF sy-subrc IS INITIAL.
    l_v_witht = wa_it_with_item-witht.
    DELETE l_it_with_item INDEX sy-tabix.
    IF   l_it_with_item IS NOT INITIAL.
      EXPORT v_id FROM l_it_with_item TO MEMORY ID l_v_belnr.
    ENDIF.
  ENDIF.

  CLEAR l_v_heading.
  SELECT SINGLE text40
    INTO l_v_heading FROM t059u
    WHERE spras EQ 'S' AND
          land1 EQ 'AR' AND
          witht EQ l_v_witht.

  READ TABLE fp_it_ouput_tab ASSIGNING <l_fs_output> INDEX  1.
  MOVE l_v_heading TO <l_fs_output>-value.
  CLEAR l_v_witht.

ENDFORM.                    "f_fetch_details
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  zsap_memory.
SET PARAMETER ID 'AUN' FIELD '5227'.
CALL TRANSACTION 'VA03' AND SKIP FIRST SCREEN.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT yclii_memories01.
DATA: val(10) TYPE c VALUE 'Hello'.

START-OF-SELECTION.

  SET PARAMETER ID 'PARA1' FIELD val.
  IF sy-subrc = 0.
    MESSAGE s037(yclii_mc01).
  ELSE.
    MESSAGE s038(yclii_mc01) DISPLAY LIKE 'E'.
  ENDIF.

*************************************************************

REPORT yclii_memories02.
DATA valu(15) TYPE c.

GET PARAMETER ID 'PARA1' FIELD valu.

WRITE:/5 valu.

Create the corresponding message in SE91.

List of all pages

Pages at first level

The following are the open sql statements....

1.aggregate functions
2.select distinct
3.outer join
4.package size
5.bypassing buffer
6.client specified
7.sub query
8.having
9.for all entries in
10.fields in internal table
11.where condition in internal table
12.order by in internal table

AGGREGATE FUNCTIONS:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT yclii_osql01 LINE-SIZE 140.
DATA: matnr    TYPE matnr,
      maktx    TYPE maktx,
      vrkme    TYPE vrkme,
      cont     TYPE i,
      total    TYPE fkimg,
      max      TYPE fkimg,
      min      TYPE fkimg.
*******************************************
START-OF-SELECTION.
  SELECT matnr maktx vrkme COUNT( * )  SUM( fkimg ) MAX( fkimg ) MIN( fkimg ) FROM
   yclii_vbrp_makt INTO (matnr,maktx,vrkme,cont,total,max,min) GROUP BY matnr maktx vrkme.
    WRITE:/5(4) sy-dbcnt, matnr USING NO EDIT MASK, maktx, vrkme, cont, total, max, min.
  ENDSELECT.

SELECT DISTINCT:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql02 LINE-SIZE 100.
DATA: BEGIN OF cust_stru,
       kunnr  TYPE kunnr,
       name1  TYPE name1_gp,
       ort01  TYPE ort01_gp,
      END OF cust_stru.
*************************************
START-OF-SELECTION.
  SELECT DISTINCT kunnr name1 ort01 FROM yclii_kna1_vbrk INTO cust_stru ORDER BY kunnr.
    WRITE:/5(4) sy-dbcnt, cust_stru-kunnr USING NO EDIT MASK, cust_stru-name1, cust_stru-ort01.
  ENDSELECT.

OUTER JOIN:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql03.
TYPES: BEGIN OF cust_bills_tp,
        kunnr     TYPE kunnr,
        name1     TYPE name1_gp,
        vbeln     TYPE vbeln,
        fkdat_rl  TYPE fkdat_rl,
       END OF cust_bills_tp.
*********************************
DATA: cust_bills_stru TYPE cust_bills_tp,
      cust_bills_tab  TYPE STANDARD TABLE OF cust_bills_tp.
******************************************************************
START-OF-SELECTION.
  SELECT kna1~kunnr kna1~name1 vbrk~vbeln vbrk~fkdat_rl
         INTO TABLE cust_bills_tab
         FROM kna1
         LEFT OUTER JOIN vbrk ON  kna1~mandt     =  vbrk~mandt
                                  AND kna1~kunnr = vbrk~kunag.
  LOOP AT cust_bills_tab INTO cust_bills_stru.
    WRITE :/5(5) sy-tabix,cust_bills_stru-kunnr USING NO EDIT MASK, cust_bills_stru-name1,
     cust_bills_stru-vbeln, cust_bills_stru-fkdat_rl.
  ENDLOOP.

PACKAGE SIZE:

1)

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql04 LINE-SIZE 120.
DATA: cust_tab TYPE yclii_cust_tab WITH HEADER LINE,
      cntr(3)  TYPE p DECIMALS 0.
PARAMETERS: pksz(4)  TYPE n DEFAULT 1000.

START-OF-SELECTION.
**************************************************************************************
* if no of rows/data is very large putting pressure on ram, the in this scenario     *
* data can be fetched in batches of smaller size.                                    *
* in the present scenario,you are fetching data in batches of 1000 rows at a time.   *
* this batch size can be specified with the phrase PACKAGE SIZE & a literal/variable.*
* every time batch of rows is fetched, existing data in the internal table is washed *
* /deleted. so at any instant only one batch of data/rows is existing in the internal*
* table.                                                                             *
**************************************************************************************
  SELECT kunnr anred name1 stras ort01 pstlz FROM kna1 INTO TABLE cust_tab PACKAGE SIZE
   pksz.
    LOOP AT cust_tab.
      cntr = cntr + 1.
      WRITE:/5(5) cntr, cust_tab-kunnr USING NO EDIT MASK, cust_tab-name1, cust_tab-ort01.
    ENDLOOP.
    SKIP 2.
  ENDSELECT.

2)

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql05 LINE-SIZE 120.
DATA: cust_tab TYPE yclii_cust_tab WITH HEADER LINE,
      cntr(3)  TYPE p DECIMALS 0.
PARAMETERS: pksz(4)  TYPE n DEFAULT 1000.

START-OF-SELECTION.
**************************************************************************************
* if no of rows/data is very large putting pressure on network, then in this scenario*
* data can be fetched in batches of smaller size & appended to the internal table    *
* in the present scenario,you are fetching data in batches of 1000 rows at a time.   *
* this batch size can be specified with the phrase PACKAGE SIZE & a literal/variable.*
* every time batch of rows is fetched,existing data in the internal table is appended*
* to. at the end of SELECT.. ENDSELECT loop, internal table contains all the fetched *
* in the batches.                                                                    *
**************************************************************************************
  SELECT kunnr anred name1 stras ort01 pstlz FROM kna1 APPENDING TABLE cust_tab
    PACKAGE SIZE pksz.
  ENDSELECT.
  LOOP AT cust_tab.
    WRITE:/5(5) sy-tabix, cust_tab-kunnr USING NO EDIT MASK, cust_tab-name1, cust_tab-ort01.
    cntr = sy-tabix MOD pksz.
    IF cntr = 0.
      SKIP 2.
    ENDIF.
  ENDLOOP.

SUBQUERY:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql06.
DATA: BEGIN OF bill_stru,
       vbeln     TYPE vbeln,
       fkdat_rl  TYPE fkdat_rl,
       netwr     TYPE netwr,
       waerk     TYPE waerk,
      END OF bill_stru,
      bill_tab LIKE STANDARD TABLE OF bill_stru.
PARAMETERS: city TYPE ort01_gp DEFAULT 'CHICAGO'.
***************************************************
* bills of customers of a specified city **********
***************************************************
START-OF-SELECTION.
  SELECT vbeln fkdat_rl netwr waerk FROM vbrk INTO TABLE bill_tab WHERE kunag IN
   ( SELECT kunnr FROM kna1 WHERE ort01 = city ).
  LOOP AT bill_tab INTO bill_stru.
    WRITE:/5(5) sy-tabix, bill_stru-vbeln, bill_stru-fkdat_rl, (15) bill_stru-netwr,
     bill_stru-waerk.
  ENDLOOP.

FOR ALL ENTRIES IN:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql07.
DATA: BEGIN OF vbrk_tab OCCURS 0,
       vbeln   TYPE vbrk-vbeln,
       fkdat   TYPE vbrk-fkdat,
       kunag   TYPE vbrk-kunag,
       netwr   TYPE vbrk-netwr,
       waerk   TYPE vbrk-waerk,
      END OF vbrk_tab,
      BEGIN OF vbrp_tab OCCURS 0,
       vbeln   TYPE vbrp-vbeln,
       matnr   TYPE vbrp-matnr,
       fkimg   TYPE vbrp-fkimg,
       vrkme   TYPE vbrp-vrkme,
      END OF vbrp_tab.
***************************************
SELECT-OPTIONS cust_cd FOR vbrk_tab-kunag.
******************************************
INITIALIZATION.
  cust_cd-sign    = 'I'.
  cust_cd-option  = 'EQ'.
  cust_cd-low     = '0000000099'.
  APPEND cust_cd.
*****************************************
START-OF-SELECTION.
  SELECT vbeln fkdat kunag netwr waerk FROM vbrk INTO TABLE vbrk_tab WHERE kunag IN
   cust_cd.
  SELECT vbeln matnr fkimg vrkme FROM vbrp INTO TABLE vbrp_tab FOR ALL ENTRIES IN vbrk_tab
   WHERE vbeln = vbrk_tab-vbeln.
  BREAK-POINT.

FIELDS IN INTERNAL TABLE:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql08 LINE-SIZE 140.
TABLES: kna1.
*DATA KNA1 TYPE KNA1.
DATA: fields(15) TYPE c OCCURS 0 WITH HEADER LINE.

START-OF-SELECTION.
  fields = 'KUNNR'.
  APPEND fields.
  fields = 'NAME1'.
  APPEND fields.
  fields = 'STRAS'.
  APPEND fields.
  fields = 'ORT01'.
  APPEND fields.
  SELECT (fields) FROM kna1 INTO CORRESPONDING FIELDS OF kna1.
    WRITE:/5(5) sy-dbcnt, kna1-kunnr USING NO EDIT MASK, kna1-name1, kna1-stras, kna1-ort01.
  ENDSELECT.

WHERE CONDITION IN INTERNAL TABLE:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql09 LINE-SIZE 120.
DATA: cust_tab       TYPE yclii_cust_tab WITH HEADER LINE,
      conditions(70) TYPE c OCCURS 0 WITH HEADER LINE.

START-OF-SELECTION.
  conditions = 'ORT01 = ''BERLIN'' AND '.
  APPEND conditions.
  conditions = '( NAME1 LIKE ''A%'' OR NAME1 LIKE ''G%'' )'.
  APPEND conditions.
  SELECT kunnr anred name1 stras ort01 pstlz FROM kna1 INTO TABLE cust_tab WHERE
   (conditions).
  SORT cust_tab BY name1.
  LOOP AT cust_tab.
    WRITE:/5(5) sy-tabix, cust_tab-kunnr USING NO EDIT MASK, cust_tab-name1, cust_tab-ort01.
  ENDLOOP.

ORDER BY IN INTERNAL TABLE:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql10 LINE-SIZE 130.
DATA : cust_tab     TYPE yclii_cust_tab,
       cust_stru    TYPE LINE OF yclii_cust_tab,
       sort_ed(50)  TYPE c,
       sort_ar      LIKE STANDARD TABLE OF sort_ed.
****************************************
START-OF-SELECTION.
  sort_ed  = 'ORT01 ASCENDING NAME1 DESCENDING'.
  APPEND sort_ed TO sort_ar.
  SELECT kunnr anred name1 stras ort01 pstlz FROM kna1 INTO TABLE cust_tab WHERE
   ort01 <> ' ' ORDER BY (sort_ar).
  LOOP AT cust_tab INTO cust_stru.
    WRITE:/5(5) sy-tabix, cust_stru-ort01, cust_stru-name1, cust_stru-kunnr
     USING NO EDIT MASK.
  ENDLOOP.

CLIENT SPECIFIED:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  yclii_osql11.
DATA : BEGIN OF cust_stru,
        mandt   TYPE kna1-mandt,
        kunnr   TYPE kna1-kunnr,
        name1   TYPE kna1-name1,
       END OF cust_stru,
       cust_tab LIKE STANDARD TABLE OF cust_stru.
SELECT-OPTIONS client FOR cust_stru-mandt.

START-OF-SELECTION.
  SELECT mandt kunnr name1 FROM kna1 CLIENT SPECIFIED INTO TABLE cust_tab WHERE
   mandt IN client.
  LOOP AT cust_tab INTO cust_stru.
    WRITE:/5(5) sy-tabix, cust_stru-mandt, cust_stru-kunnr USING NO EDIT MASK,
     cust_stru-name1.
  ENDLOOP.

Group-by statement is really helpful to avoid fetching high-volume of data into your program when you need that data sum(collect) on currency and quantity fields. 

*Extracts from program Ztab2002
* START-OF-SELECTION

SELECT kalnr kalka bwvar meeht SUM( menge )
  INTO TABLE i_ckis FROM ckis
  WHERE kadky <= sy-datum
    AND tvers = '01'
    AND kalka IN ('01','Z1','Z2')
    AND bwvar IN ('Z01','Z02','Z03','Z04','Z07')
*     and kkzst = ' '
    AND kkzma = ' '
    AND typps = 'E'
    AND ( kstar <> 800040 OR kstar <> 800050 )
    AND ( meeht = 'MIN' OR meeht = 'H' )
  GROUP BY kalnr kalka bwvar meeht.

* Perform actual processing
PERFORM get_associated_labour_hours.

*&---------------------------------------------------------------------*
*&      Form  get_associated_labour_hours
*&---------------------------------------------------------------------*
FORM get_associated_labour_hours.
* Determine start position and then process single record for given key
* i_ckis is sorted on kalnr kalka bwvar meeht with menge summated.
  READ TABLE i_ckis WITH KEY kalnr = w_keko-kalnr
                             kalka = w_keko-kalka
                             bwvar = w_keko-bwvar
                             meeht = 'H'          BINARY SEARCH.
  IF sy-subrc = 0.
    d_lab_hrs =  i_ckis-menge * 60.
  ENDIF.

  READ TABLE i_ckis WITH KEY kalnr = w_keko-kalnr
                             kalka = w_keko-kalka
                             bwvar = w_keko-bwvar
                             meeht = 'MINS'       BINARY SEARCH.
  IF sy-subrc = 0.
    d_lab_hrs =  d_lab_hrs + i_ckis-menge.
  ENDIF.

  d_lab_hrs = d_lab_hrs / w_keko-losgr.
  d_lab_hrs = d_lab_hrs / 60.          "Convert from mins into hours
ENDFORM.                               " GET_LABOUR_HOURS_ASSOCIATED
 

Submitted By:  Ramganesan Karuppaiyah

Submitted On: February 7, 2007 

This  is mainly for Executing a Query Statement by passing the Parameter to It.The Great advantage of it is we can pass the table and fields at run time.It leads to minimize the development time. This can be achieved by Using Macro.

What is Macro?:

Macro is a set of executable statement/s which can be called in a program.
Whenever it is called in the program its replaces the statement which is defined inside the macro.

Code:

DEFINE macro_name.
  "Set of statements to be executed.
END-OF-DEFINITION.
 

Note:
It is also possible to pass parameters to the MACRO.

Steps Involved

  1. Here I am declaring a macro which can accept upto 4 Parameters during runtime.
  2. Declaring necessary data types.
  3. Calling Macro in the Program.

 

DEFINE s.
  select &1
  from &2
  into table &3
  where &4.
END-OF-DEFINITION.

DATA: t_mara TYPE mara OCCURS 0.
DATA: l_mara(4) VALUE 'MARA',
      l_s(6) VALUE 'SELECT',
      l_field(5) VALUE '*',
      l_table(6) VALUE 'T_MARA',
      l_query TYPE string VALUE 'MATNR = ''000000000000000001'''.

FIELD-SYMBOLS: <fs> TYPE table.

ASSIGN t_mara TO <fs>.
s (l_field) (l_mara) <fs> (l_query).
 

Things to remember before using for all entries:

1>     Always select all the key fields, even you are not using the fields further in program.

2>     Sort the table by fields in where clause.

3>     Check table is not blank before using for all entries.

4>    Delete the adjacent duplicates from the driver table. Other wise, for the same entry system will check redundantly.

 

Select field1 field2 field3 into table it_tab1
      From table1 where conditions.

Sort it_tab1 by field1 field2.

Delete adjacent duplicates from it_itab1 comparing field1 field2.

If not it_tab1[] is initial.
   Select key_field1   key_field2   key_field3.....   Key_fieldn  field1
   From table2 into it_tab2
   For all entries in it_tab1
   Where key_field1 = field1
  And key_field2 = field2.
Endif.


 Important Notice: While For All Entries has its uses (for example in BI Routines), in most cases INNER JOIN is more efficient, and leads to more compact, more readable code. INNER JOIN should ALWAYS be used in preference to For All Entries. This is especially true if for ABAP with HANA


Author: Sangyeul Han
Submitted: July 26, 2007
Description: Sometimes, you want to process abap code with parallel processing. In help you read the syntax following.

  • CALL FUNCTION func STARTING NEW TASK TASK
  • CALL FUNCTION func IN BACKGROUND TASK

But, you do not satisfied with "STARTING NEW TASK TASK" because of the session count 6. So, you decide to use "IN BACKGROUND TASK". After a while you also find that this syntax does not make parallel processing. This time, You can add "AS SEPARATE UNIT". First of all, your Function Module must be RFC. Let's go into the code.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  y_test_syhan_008.

TABLES : mara,
         ysyhan_01.

DATA : BEGIN OF itab OCCURS 0,
         mtart LIKE ysyhan_01-mtart,
         quant LIKE ysyhan_01-quant,
         meins LIKE ysyhan_01-meins,
       END OF itab.

SELECT mtart INTO mara-mtart FROM mara.
  itab-mtart = mara-mtart.
  itab-quant = itab-quant + 1.
  itab-meins = 'EA'.
  COLLECT itab.  CLEAR itab.
ENDSELECT.

DELETE FROM ysyhan_01.

LOOP AT itab.
  CALL FUNCTION 'YSYH_MTART_QUANT'
    IN BACKGROUND TASK
    AS SEPARATE UNIT
*    IN UPDATE TASK
    EXPORTING
      mtart = itab-mtart
      quant = itab-quant
      meins = itab-meins.
  COMMIT WORK.
  WAIT UP TO 10 SECONDS.
ENDLOOP.

Code summary and explanation!

  • AS SEPARATE UNIT 
  • COMMIT WORK

Execute this ABAP Program and monitor SM50. In interval 10 seconds, dialog processes occur.
Caution. if processes count exceeds the restriction no, other SAP user will complain to you.

Good luck~

??






REPORT zhashed_table .

TYPES: BEGIN OF t_foo,
        field1 TYPE char2,
        field2 TYPE char2,
        field3 TYPE char2,
        field4 TYPE i,
       END OF t_foo.

DATA: lt_foo TYPE HASHED TABLE OF t_foo
               WITH UNIQUE KEY field1 field2 field3.

DATA: ls_foo LIKE LINE OF lt_foo.

FIELD-SYMBOLS: <ls_foo> LIKE LINE OF lt_foo.

* Must assign it to use it.
ASSIGN ls_foo TO <ls_foo>.

CLEAR <ls_foo>.
<ls_foo>-field1 = 'AB'.
<ls_foo>-field2 = 'CD'.
<ls_foo>-field3 = 'EF'.
<ls_foo>-field4 = '2'.
INSERT <ls_foo> INTO TABLE lt_foo.

CLEAR <ls_foo>.
<ls_foo>-field1 = 'AB'.
<ls_foo>-field2 = 'CD'.
<ls_foo>-field3 = 'EF'.
<ls_foo>-field4 = '2'.
INSERT <ls_foo> INTO TABLE lt_foo.
IF sy-subrc  NE 0.
  WRITE:/ 'this is  duplicate key '.
ENDIF.
 

Description
For Example The Stack Memory of the execution of a program is this:

  1. Program Z1 --> call function F2
  2. Function F2 of function group Z2 --> call function F3
  3. Function F3 of function group Z3.

 You are inside the FM F3 and you want to access the internal table LT_IT that is declare in program Z1 and you don't have it in the interface of the function.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA: l_stack(30) TYPE c.
DATA: lw_it TYPE xxx.

FIELD-SYMBOLS: <lt_it> TYPE STANDARD TABLE.

CLEAR l_stack.
MOVE '(Z1)LT_IT[]' TO l_stack.
ASSIGN (l_stack) TO <lt_it>.

LOOP AT <lt_it> INTO lw_it.
* here you access to the table.
ENDLOOP.

Important: You must know the sequence of the stack to do that. Otherwise if the function F3 is call from an other program you will not have access to the lt_it table.


List of all pages

Pages at first level


I have been working on an upgrade project for the past 6 months and recently came across a dump on ECC 6.0. The dump analysis says "Relationship ATTA Can No Longer Be Used with this Interface". The problem occurred because of a function module SREL_GET_NEXT_NEIGHBORS which doesn't work as desired in ECC like it worked in 4.6. I searched on SDN and googled for the same. But no great results. Finally I managed to find a solution for the same and thought of sharing it with the people out here.

I am attaching a code snippet that might help people facing similar problem in upgrade projects.

4.6 Code :

CALL FUNCTION 'SREL_GET_NEXT_NEIGHBORS'
  EXPORTING
    object         = g_bor_object
    roletype       = 'APPLOBJ'
    relationtype   = 'ATTA'
  TABLES
    neighbors      = l_neighbors
  EXCEPTIONS
    internal_error = 1
    no_logsys      = 2
    OTHERS         = 3.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
 

ECC Replacement :

TRY.
    DATA: l_rol TYPE oblroltype.
    l_rol = 'GOSAPPLOBJ'.
    CALL METHOD cl_binary_relation=>read_links_of_binrel
      EXPORTING
        is_object   = g_bor_object
        ip_logsys   = g_bor_logsys
        ip_relation = 'ATTA'
        ip_role     = l_rol
      IMPORTING
        et_links    = l_neighbors.
  CATCH cx_obl_parameter_error .
  CATCH cx_obl_internal_error .
  CATCH cx_obl_model_error .
ENDTRY.
 

I hope this helps many and solve the problems faced by them in upgrade issues.

This page contains ABAP snippets which send emails.

The program is used to convert output of ALV/CLASSICAL reports into HTML format and mail it as attachment to the mail id’s specified in a custom distribution list.The distribution lists can be maintained using transaction SO23 or please check following link http://help.sap.com/saphelp_nw04/helpdata/en/a8/809d1dfc8711d2a2b400a0c943858e/content.htm

General program flow.

Step 1: With input values the report is executed using Submit and Return ,and exported to spool

Step 2: The spool is retrieved.

Step 3: Using Fun.Mod. Compress the table .

Step 4: Create attachment .

Step 5: Send mail using SO_NEW_DOCUMENT_ATT_SEND_API1.

Step 6: Run report "rsconn01" to release the queue and send mails.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------*
*& Report  ZALV_MAIL
*&---------------------------------------------------------------------*
REPORT  zalv_mail.
*=======================================================================*
*PROGRAM ID           :   zalv_mail
*PROGRAM TITLE        :   Mail ALV Report
*AUTHOR               :   Harikrishnan.S
*SUPPLIER             :
*DATE                 :   10.03.2011
*DEVELOPMENT ID       :
*CHANGE REQUEST NO    :
*DESCRIPTION          :   Mail any ALV/classical report output as
*                         Attachment(HTML)
*=======================================================================*
INCLUDE zalv_mail_top.        "TOP
INCLUDE zalv_mail_performs.   "PERFORMS
INCLUDE zalv_mail_forms.      "FORMS
*&---------------------------------------------------------------------*
*&  Include           ZALV_MAIL_TOP                                    *
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*                     DECLARATIONS
*&---------------------------------------------------------------------*
TABLES: tsp01,zdmail1.
DATA: docdata    LIKE sodocchgi1,
      objpack    LIKE sopcklsti1 OCCURS  1 WITH HEADER LINE,
      objhead    LIKE solisti1   OCCURS  1 WITH HEADER LINE,
      objtxt     LIKE solisti1   OCCURS 10 WITH HEADER LINE,
      objbin     LIKE solisti1   OCCURS 10 WITH HEADER LINE,
      objhex     LIKE solix      OCCURS 10 WITH HEADER LINE,
      reclist    LIKE somlreci1  OCCURS  1 WITH HEADER LINE.
DATA: tab_lines  TYPE i,
      doc_size   TYPE i,
      att_type   LIKE soodk-objtp.
DESCRIBE TABLE objbin LINES tab_lines.
DATA:t_msg_att  TYPE STANDARD TABLE OF solisti1 WITH HEADER LINE.
DATA:mstr_print_parms LIKE pri_params,
     mc_valid(1)      TYPE c,
     mi_bytecount     TYPE i,
     mi_length        TYPE i,
     mi_rqident       LIKE tsp01-rqident.
DATA:it_zdmail TYPE TABLE OF zdmail1,
     wa_zdmail LIKE LINE  OF it_zdmail.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME.
PARAMETER: p_repid      TYPE sy-repid OBLIGATORY,
           p_varnt(25)  TYPE c ,
           p_attnam(25) TYPE c OBLIGATORY,
           p_title(25) TYPE c  OBLIGATORY,
           p_body(255)  TYPE c.
PARAMETER p_dlid TYPE zdmail1-dlid OBLIGATORY.
SELECTION-SCREEN END OF BLOCK b2.
SELECTION-SCREEN END OF BLOCK b1.
*&---------------------------------------------------------------------*
*&  Include           ZALV_MAIL_PERFORMS                               *
*&---------------------------------------------------------------------*
*  EXECUTE THE REPORT AND EXPORT TO SPOOL
PERFORM call_report.
*  GET SPOOL REQUEST NO
PERFORM get_spool_number USING p_repid
                               sy-uname
                               CHANGING mi_rqident.
*  GET DATA FRM SPOOL AND SEND MAIL
PERFORM get_data_mail.
*&---------------------------------------------------------------------*
*&  Include           ZALV_MAIL_FORMS                                  *
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  call_report
*&---------------------------------------------------------------------*
*       Call any ALV REPORT
*----------------------------------------------------------------------*
FORM call_report .
*SUBMIT ALV GRID REPORT  TO SPOOL AND RETURN
  SUBMIT (p_repid)  TO SAP-SPOOL
                    USING SELECTION-SET p_varnt
                    WITHOUT SPOOL DYNPRO
                    DESTINATION space
*                    COVER TEXT ''
                    NEW LIST IDENTIFICATION 'X'
                    IMMEDIATELY space
                    AND RETURN.
ENDFORM.                    " call_report
*&---------------------------------------------------------------------*
*&      Form  get_spool_number
*&---------------------------------------------------------------------*
*    GET THE SPOOL REQUEST  NO rq2name FROM TABLE TSP01
*----------------------------------------------------------------------*
FORM get_spool_number USING: f_repid
                             f_uname
                            CHANGING f_rqident.
  DATA:
    lc_rq2name LIKE tsp01-rq2name.
  CONCATENATE f_repid                                       "+0(8)
              f_uname+0(3)
    INTO lc_rq2name SEPARATED BY '_'.
  SELECT * FROM tsp01 WHERE  rq2name = lc_rq2name
  ORDER BY rqcretime DESCENDING.
    f_rqident = tsp01-rqident.
    EXIT.
  ENDSELECT.
  IF sy-subrc NE 0.
    CLEAR f_rqident.
  ENDIF.
ENDFORM." get_spool_number
*&---------------------------------------------------------------------*
*&      Form  spool_to_html
*&---------------------------------------------------------------------*
FORM spool_to_html .
ENDFORM.                    " spool_to_html
*&---------------------------------------------------------------------*
*&      Form  GET_DATA_MAIL
*&---------------------------------------------------------------------*
FORM get_data_mail .
  DATA: mem_tab LIKE abaplist OCCURS 10.
*GET DATA FRM SPOOL AND EXPORT AS LIST TO MEMORY
  SUBMIT rspolist EXPORTING LIST TO MEMORY AND RETURN
                    WITH rqident = mi_rqident
                    WITH first = '1'
                    WITH last = '0'.
  CALL FUNCTION 'LIST_FROM_MEMORY'
    TABLES
      listobject = mem_tab
    EXCEPTIONS
      not_found  = 1
      OTHERS     = 2.
*COMPRESS LIST TO TABLE
  CALL FUNCTION 'TABLE_COMPRESS'
*     IMPORTING
*       COMPRESSED_SIZE       =
    TABLES
       in                    = mem_tab
       out                   = objbin
    EXCEPTIONS
       OTHERS                = 1.
  IF sy-subrc <> 0.
    MESSAGE ID '61' TYPE 'E' NUMBER '731'
    WITH 'TABLE_COMPRESS'.
  ENDIF.
** NOTE: Creation of attachment is finished yet.
**   For your report, the attachment should be placed into table
**     objtxt for plain text or
**     objbin for binary content.
**   Now create the message and send the document.'recipients!'.
** Create Message Body
**   Title and Description
  docdata-obj_name  = 'Royal Enfield'.
  docdata-obj_descr = p_title.
**   Main Text
  objtxt = p_body.
  APPEND objtxt.
  objtxt = text-002.
  APPEND objtxt.
  objtxt = 'Have a nice day.'.
  APPEND objtxt.
*
**   Write Packing List (Main)
*
  DESCRIBE TABLE objtxt LINES tab_lines.
  READ     TABLE objtxt INDEX tab_lines.
  docdata-doc_size = ( tab_lines - 1 ) * 255 + strlen( objtxt ).
  CLEAR objpack-transf_bin.
  objpack-head_start = 1.
  objpack-head_num   = 0.
  objpack-body_start = 1.
  objpack-body_num   = tab_lines.
  objpack-doc_type   = 'RAW'.
  APPEND objpack.
** Create Message Attachment
*
**   Write Packing List (Attachment)
*
  att_type = 'ALI'.
  DESCRIBE TABLE objbin LINES tab_lines.
  READ     TABLE objbin INDEX tab_lines.
  objpack-doc_size = ( tab_lines - 1 ) * 255 + strlen( objbin ).
  objpack-transf_bin = 'X'.
  objpack-head_start = 1.
  objpack-head_num   = 0.
  objpack-body_start = 1.
  objpack-body_num   = tab_lines.
  objpack-doc_type   = att_type.
  objpack-obj_name   = 'ATTACHMENT'.
  objpack-obj_descr  = p_attnam.
  APPEND objpack.
*
** Create receiver list
  CLEAR: it_zdmail,
         wa_zdmail.
  SELECT * INTO TABLE it_zdmail FROM zdmail1 WHERE
                                                 dlid = p_dlid.
*ADD THE EMAIL IDS TO RECLIST-RECEIVER
* loop changed 10/MAY/2011 - HKS
  LOOP AT it_zdmail INTO wa_zdmail.
    reclist-receiver = wa_zdmail-email.  "<-- change address
    reclist-rec_type = 'U'.
    APPEND reclist.
  ENDLOOP.
  reclist-receiver = sy-uname.                "<-- change internal user
  reclist-rec_type = 'B'.
  APPEND reclist.
** Send Message
*
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data = docdata
      put_in_outbox = 'X'
      commit_work   = 'X'     "used from rel.6.10
    TABLES
      packing_list  = objpack
      object_header = objhead
      contents_bin  = objbin
      receivers     = reclist.
*      ADDED BY HARIKRISHNAN-HBS:06.05.2011
*      REASON:  "reclist" IF NOT CLEARED THE MAIL WILL BE REPEATEDLY
*               SENT TO SAME  ADDRESS
  CLEAR     reclist.
*      END OF ADDITION BY HARIKRISHNAN-HBS:06.05.2011
  IF sy-subrc <> 0.
*RELEASE AND SEND MESSAGES IN QUEUE
    CALL FUNCTION 'SO_DEQUEUE_UPDATE_LOCKS'
      EXCEPTIONS
        communication_failure = 1
        system_failure        = 2
        OTHERS                = 3.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    SUBMIT rsconn01 WITH mode = 'INT'
          WITH output = ' '
          AND RETURN.
  ENDIF.
ENDFORM.                    " GET_DATA_MAIL

TABLE DETAILS (ZTABLE FOR DIST LIST)

FIELD

KEY

INITIAL

DATAELEMENT

DATA TYPE

LENGTH

DECIMAL

DESCRIPTION

MANDT

X

X

MANDT

CLNT

3

0

CLIENT

SRNR

X

X

ZSRNR

INT4

10

0

SERIAL NO

DLID

 

 

ZDLID

CHAR

20

0

DISTRIBUTION LIST ID

EMAIL

 

 

AD_SMTPADR

CHAR

241

0

EMAIL ADDRESS

Now you can maintain data by creating a parameter transaction.

the signature of CL_DOCUMENT_BCS~ADD_ATTACHMENT:

suppose we already have PDF binary source with type XSTRING, variable iv_pdf_content.
i_attachment_type: value list of attachment type could be found in value table TSOTD:

 

in PDF, we should use BIN
i_attachment_size: could be filled via xstrlen( iv_pdf_content )
i_att_content_hex: cl_document_bcs=>xstring_to_solixip_xstring iv_pdf )
i_attachment_subject: for example test.pdf
finally the PDF attachment could be found in email box.


Back to Sending Mails - Home Page

I have seen many approaches for sending mail with attachment. Here i am writing a function module to send mail with attachment using object oriented approach. The use of this approach would eliminate bulky coding.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FUNCTION ZNPI_SEND_MAIL.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(SUBJECT) TYPE  SO_OBJ_DES
*"     VALUE(MESSAGE_BODY) TYPE  BCSY_TEXT
*"     VALUE(ATTACHMENTS) TYPE  RMPS_T_POST_CONTENT OPTIONAL
*"     VALUE(SENDER_UID) TYPE  SYUNAME OPTIONAL
*"     VALUE(RECIPIENT_UID) TYPE  SYUNAME OPTIONAL
*"     VALUE(SENDER_MAIL) TYPE  ADR6-SMTP_ADDR OPTIONAL
*"     VALUE(RECIPIENT_MAIL) TYPE  ADR6-SMTP_ADDR OPTIONAL
*"  EXPORTING
*"     VALUE(RESULT) TYPE  BOOLEAN
*"  TABLES
*"      RECIPIENTS STRUCTURE  UIYS_IUSR OPTIONAL
*"----------------------------------------------------------------------
*Data Declaration 
  DATA: lo_sender TYPE REF TO if_sender_bcs VALUE IS INITIAL,
          l_send type ADR6-SMTP_ADDR ,
          l_rec type  ADR6-SMTP_ADDR .
   Data : ITAB TYPE TABLE OF SVAL,
          LS_ITAB TYPE SVAL,
          i_RETURN.
     DATA:
     lo_send_request TYPE REF TO cl_bcs VALUE IS INITIAL.
*     DATA:
*    lt_message_body TYPE bcsy_text VALUE IS INITIAL,
     DATA: lx_document_bcs TYPE REF TO cx_document_bcs VALUE IS INITIAL,
     attachment_subject type SO_OBJ_DES.
 
   DATA: lo_recipient TYPE REF TO if_recipient_bcs VALUE IS INITIAL.
   data: ls_recipient like line of recipients,
   ls_attachment like line of attachments.
   DATA: lv_recipient_uid TYPE uname,
         lv_recipient_mail TYPE adr6-smtp_addr.

*Prepare Mail Object 
     CLASS cl_bcs DEFINITION LOAD.
     lo_send_request = cl_bcs=>create_persistent( ).
* Message body and subject
 data: lo_document TYPE REF TO cl_document_bcs VALUE IS INITIAL.
     lo_document = cl_document_bcs=>create_document(
     i_type = 'RAW'
     i_text =  message_body
     i_subject = subject ).
 
 
 
*Send  attachment 
 loop at attachments into ls_attachment.
     attachment_subject = ls_attachment-subject.
     TRY.
         lo_document->add_attachment(
         EXPORTING
         i_attachment_type = ls_attachment-OBJTP
         i_attachment_subject = attachment_subject
 
         i_att_content_hex = ls_attachment-CONT_HEX ).
       CATCH cx_document_bcs INTO lx_document_bcs.
     ENDTRY.
 endloop.
 
* Pass the document to send request 
     lo_send_request->set_document( lo_document ).
 try.
     if sender_mail is not initial.
       lo_sender = cl_cam_address_bcs=>create_internet_address( sender_mail ).
           elseif sender_uid is not initial.
       lo_sender = cl_sapuser_bcs=>create( sender_uid ).
     else.
       lo_sender = cl_sapuser_bcs=>create( sy-uname ).
     endif.
* Set sender 
     lo_send_request->set_sender(
     EXPORTING
     i_sender = lo_sender ).
        catch CX_ADDRESS_BCS.
          return.
        endtry.
* Set  recipients 
 if recipients[] is initial.
 
     if recipient_mail is not initial.
       lo_recipient = cl_cam_address_bcs=>create_internet_address( recipient_mail ).
           elseif recipient_uid is not initial.
       lo_recipient = cl_sapuser_bcs=>create( recipient_uid ).
     else.
       lo_recipient = cl_sapuser_bcs=>create( sy-uname ).
     endif.
 
     lo_send_request->add_recipient(
     EXPORTING
     i_recipient = lo_recipient
     i_express = 'X' ).
 else.
 
 loop at recipients into ls_recipient.
     if ls_recipient-iusrid is not initial.
       lv_recipient_uid = ls_recipient-iusrid.
       lo_recipient = cl_sapuser_bcs=>create( lv_recipient_uid ).
     elseif ls_recipient-email is not initial.
       lv_recipient_mail = ls_recipient-email .
       lo_recipient = cl_cam_address_bcs=>create_internet_address( lv_recipient_mail ).
     endif.
 
 lo_send_request->add_recipient(
     EXPORTING
     i_recipient = lo_recipient
     i_express = 'X' ).
 
 endloop.
 endif.
 try.
** Send email 
     lo_send_request->send(
     EXPORTING
     i_with_error_screen = 'X'
     RECEIVING
     result = result ).
     COMMIT WORK.
     wait up to 1 seconds.
catch cx_send_req_bcs.
      result = ''.
endtry.

ENDFUNCTION.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA method1 LIKE sy-ucomm.
DATA g_user LIKE soudnamei1.
DATA g_user_data LIKE soudatai1.
DATA g_owner LIKE soud-usrnam.
DATA g_receipients LIKE soos1 OCCURS 0 WITH HEADER LINE.
DATA g_document LIKE sood4 .
DATA g_header LIKE sood2.
DATA g_folmam LIKE sofm2.
DATA g_objcnt LIKE soli OCCURS 0 WITH HEADER LINE.
DATA g_objhead LIKE soli OCCURS 0 WITH HEADER LINE.
DATA g_objpara  LIKE selc OCCURS 0 WITH HEADER LINE.
DATA g_objparb  LIKE soop1 OCCURS 0 WITH HEADER LINE.
DATA g_attachments LIKE sood5 OCCURS 0 WITH HEADER LINE.
DATA g_references LIKE soxrl OCCURS 0 WITH HEADER LINE.

DATA g_authority LIKE sofa-usracc.
DATA g_ref_document LIKE sood4.
DATA g_new_parent LIKE soodk.
DATA: BEGIN OF g_files OCCURS 10 ,
        text(4096) TYPE c,
      END OF g_files.

DATA : fold_number(12) TYPE c,
       fold_yr(2) TYPE c,
       fold_type(3) TYPE c.

PARAMETERS ws_file(4096) TYPE c DEFAULT 'Insert ur Document' here''.
* Can me any file fromyour pc ....either xls or word or ppt etc ...
g_user-sapname = sy-uname.
CALL FUNCTION 'SO_USER_READ_API1'
  EXPORTING
    user                            = g_user
  IMPORTING
    user_data                       = g_user_data
  EXCEPTIONS
    USER_NOT_EXIST                  = 1
    PARAMETER_ERROR                 = 2
    X_ERROR                         = 3
    OTHERS                          = 4
          .

fold_type = g_user_data-outboxfol+0(3).
fold_yr = g_user_data-outboxfol+3(2).
fold_number =  g_user_data-outboxfol+5(12).
CLEAR g_files.

REFRESH : g_objcnt,
          g_objhead,
          g_objpara,
          g_objparb,
          g_receipients,
          g_attachments,
          g_references,
          g_files.

method1 = 'SAVE'.
g_document-foltp  = fold_type.
g_document-folyr   = fold_yr.
g_document-folno   = fold_number.
g_document-objtp   = g_user_data-object_typ.
*g_document-OBJYR   = '27'.
*g_document-OBJNO   = '000000002365'.
*g_document-OBJNAM = 'MESSAGE'.
g_document-objdes   = 'sap-img.com testing by program'.
g_document-folrg   = 'O'.
*g_document-okcode   = 'CHNG'.
g_document-objlen = '0'.
g_document-file_ext = 'TXT'.

g_header-objdes =  'sap-img.com testing by program'.
g_header-file_ext = 'TXT'.

CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = sy-uname
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

* File from the pc to send...
method1 = 'ATTCREATEFROMPC'.

g_files-text = ws_file.
APPEND g_files.

CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = g_owner
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

method1 = 'SEND'.

g_receipients-recnam = 'MK085'.
g_receipients-recesc = 'B'.
g_receipients-sndex = 'X'.
APPEND  g_receipients.

CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = g_owner
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

*-- End of Program

Author: Runal Singh
Submitted: 16/01/2008

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FUNCTION z_send_email_itab_uname.
*"----------------------------------------------------------------------*"
*"Local interface:
*"  IMPORTING
*"     VALUE(APPLICATION) LIKE  SOOD1-OBJNAM
*"     VALUE(EMAILTITLE) LIKE  SOOD1-OBJDES
*"     VALUE(RECEXTNAM) LIKE  SOOS1-RECEXTNAM OPTIONAL
*"     VALUE(SENDER) LIKE  SOUD-USRNAM DEFAULT SY-UNAME
*"     VALUE(UNAME) LIKE  SOOS1-RECEXTNAM OPTIONAL
*"  EXPORTING
*"     VALUE(RETURN_CODE) LIKE  SY-SUBRC
*"  TABLES
*"     TEXTTAB STRUCTURE  SOLI
*"----------------------------------------------------------------------
* tables
  TABLES: pa0105,  "Employee detail for username and email address
          usr21,   "Login addition address data
          adr6.    "Address table for email addresses
*- local data declaration
  DATA: ohd    LIKE sood1,
        oid    LIKE soodk,
        to_all LIKE sonv-flag,
        t_uname LIKE sy-uname,
        okey   LIKE swotobjid-objkey.
  DATA: BEGIN OF receivers OCCURS 0.
          INCLUDE STRUCTURE soos1.
  DATA: END OF receivers.
*- fill odh
  CLEAR ohd.
  ohd-objla    = sy-langu.
  ohd-objnam   = application.
  ohd-objdes   = emailtitle.
  ohd-objpri   = 3.
  ohd-objsns   = 'F'.
  ohd-ownnam   = sy-uname.

  IF NOT uname IS INITIAL.
* Find personnel number of username
    CONDENSE uname NO-GAPS.
    WHILE uname CS ','.
      t_uname = uname+0(sy-fdpos).
      ADD 1 TO sy-fdpos.
      SHIFT uname LEFT BY sy-fdpos PLACES.
      PERFORM find_email_address USING t_uname
                              CHANGING recextnam.
    ENDWHILE.
*Do the last record
    IF uname <> space.
      t_uname = uname.
      PERFORM find_email_address USING t_uname
                              CHANGING recextnam.
    ENDIF.
  ENDIF.
*- send Email
  IF NOT recextnam IS INITIAL.
    CONDENSE recextnam NO-GAPS.
    CHECK recextnam CS '@'.
  ENDIF.
*- for every individual recipient send an Email*
  WHILE recextnam CS ','.
    PERFORM init_rec TABLES receivers.
    READ TABLE receivers INDEX 1.    r
    eceivers-recextnam = recextnam+0(sy-fdpos).
    ADD 1 TO sy-fdpos.
    SHIFT recextnam LEFT BY sy-fdpos PLACES.
    MODIFY receivers INDEX 1.
    PERFORM so_object_send_rec  TABLES texttab receivers
                                USING ohd sender.
  ENDWHILE.
*- check last recipient in recipient list
  IF recextnam <> space.
    PERFORM init_rec TABLES receivers.
    READ TABLE receivers INDEX 1.
    receivers-recextnam = recextnam.
    MODIFY receivers INDEX 1.
    PERFORM so_object_send_rec
    TABLES texttab receivers
    USING ohd            sender.
  ENDIF.
ENDFUNCTION.

*---------------------------------------------------------------------*
*       FORM SO_OBJECT_SEND_REC                                       *
*---------------------------------------------------------------------*
FORM  so_object_send_rec TABLES  objcont STRUCTURE soli
                                 receivers    STRUCTURE soos1
                          USING  object_hd    STRUCTURE sood1
                                 sender LIKE soud-usrnam.
  DATA:   oid     LIKE soodk,
          to_all  LIKE sonv-flag,
          okey    LIKE swotobjid-objkey.
  CALL FUNCTION 'SO_OBJECT_SEND'
    EXPORTING
      extern_address             = 'X'
      object_hd_change           = object_hd
      object_type                = 'RAW'
      outbox_flag                = 'X'
      sender                     = sender
    IMPORTING
      object_id_new              = oid
      sent_to_all                = to_all
      office_object_key          = oke
    TABLES
      objcont                    = objcont
      receivers                  = receivers
    EXCEPTIONS
      active_user_not_exist      = 1
      communication_failure      = 2
      component_not_available    = 3
      folder_not_exist           = 4
      folder_no_authorization    = 5
      forwarder_not_exist        = 6
      note_not_exist             = 7
      object_not_exist           = 8
      object_not_sent            = 9
      object_no_authorization    = 10
      object_type_not_exist      = 11
      operation_no_authorization = 12
      owner_not_exist            = 13
      parameter_error            = 14
      substitute_not_active      = 15
      substitute_not_defined     = 16
      system_failure             = 17
      too_much_receivers         = 18
      user_not_exist             = 19
      x_error                    = 20
      OTHERS                     = 21.
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        MESSAGE i999(b1) WITH 'Activer user does not exist.' 'Send Mail failed!'.
      WHEN 2.
        MESSAGE i999(b1) WITH 'Communication Failure.' 'Send Mail failed!'.
      WHEN 3.
        MESSAGE i999(b1) WITH 'Component not available.'  'Send Mail failed!'.
      WHEN 4.
        MESSAGE i999(b1) WITH 'Folder does not exist.' 'Send Mail failed!'.
      WHEN 5.
        MESSAGE i999(b1) WITH 'No authorization for folder.' 'Send Mail failed!'.
      WHEN 6.
        MESSAGE i999(b1) WITH 'Forwarder does not exist.' 'Send Mail failed!'.
      WHEN 7.
        MESSAGE i999(b1) WITH 'Note does not exist.'  'Send Mail failed!'.
      WHEN 8.
        MESSAGE i999(b1) WITH 'Object does not exist.' 'Send Mail failed!'.
      WHEN 9.
        MESSAGE i999(b1) WITH 'Object not sent.' 'Send Mail failed!'.
      WHEN 10.
        MESSAGE i999(b1) WITH 'No authorization for object.'  'Send Mail failed!'.
      WHEN 11.
        MESSAGE i999(b1) WITH 'Object type does not exist.' 'Send Mail failed!'.
      WHEN 12.
        MESSAGE i999(b1) WITH 'No authorization for operation.'  'Send Mail failed!'.
      WHEN 13.
        MESSAGE i999(b1) WITH 'Owner does not exist.' 'Send Mail failed!'.
      WHEN 14.
        MESSAGE i999(b1) WITH 'Parameter Error.'   'Send Mail failed!'.
      WHEN 15.
        MESSAGE i999(b1) WITH 'Substitute not active.'  'Send Mail failed!'.
      WHEN 16.
        MESSAGE i999(b1) WITH 'Substitute not defined.'   'Send Mail failed!'.
      WHEN 17.
        MESSAGE i999(b1) WITH 'System failure.' 'Send Mail failed!'.
      WHEN 18.
        MESSAGE i999(b1) WITH 'Too many receivers.'    'Send Mail failed!'.
      WHEN 19.
        MESSAGE i999(b1) WITH 'User does not exist.' 'Send Mail failed!'.
      WHEN 20.
        MESSAGE i999(b1) WITH 'Unknown error ocurred.' 'Send Mail failed!'.
      WHEN 21.
        MESSAGE i999(b1) WITH 'Unknown error ocurred.' 'Send Mail failed!'.
    ENDCASE.
  ENDIF.
ENDFORM.                    "so_object_send_rec
*****----------------------------------------------------------------------*
*   FORM INIT_REC
**-------------------------------------------------------------------------*
FORM init_rec TABLES receivers STRUCTURE soos1.
  CLEAR receivers.
  REFRESH receivers.
  MOVE sy-datum  TO receivers-rcdat .
  MOVE sy-uzeit  TO receivers-rctim.
  MOVE '1'       TO receivers-sndpri.
  MOVE 'X'       TO receivers-sndex.
  MOVE 'U-'      TO receivers-recnam.
  MOVE 'U'       TO receivers-recesc.
  MOVE 'INT'     TO receivers-sndart.
  MOVE '5'       TO receivers-sortclass.
  APPEND receivers.
ENDFORM.                    "init_rec
*&---------------------------------------------------------------------*
*& Form  find_email_address
*&---------------------------------------------------------------------*
*       Returns the email address for a USERID whether they are an
*       employee or just a user.
*----------------------------------------------------------------------*
*      <--P_RECEXTNAM  Email address
*      -->P_UNAME      USERID
*----------------------------------------------------------------------*
FORM find_email_address USING    p_uname
                        CHANGING p_recextnam LIKE soos1-recextnam.
  DATA:   t_pernr LIKE pa0105-pernr,
          t_email LIKE pa0105-usrid_long.
* STEP 1 - Find personnel number for UNAME
  SELECT SINGLE pernr
           INTO t_pernr
           FROM pa0105
     WHERE subty = '0001'
       AND endda >= sy-datum
       AND begda <= sy-datum
       AND usrid = p_uname.
* Employee record found
  IF sy-subrc = 0.
* STEP 2 - Find email address for personnel number
    SELECT SINGLE usrid_long
             INTO t_email
             FROM pa0105
            WHERE pernr = t_pernr
              AND subty = '0022'
              AND endda >= sy-datum
              AND begda <= sy-datum.
    IF sy-subrc = 0.
      IF NOT p_recextnam IS INITIAL.
        CONCATENATE p_recextnam t_email INTO p_recextnam SEPARATED BY ','.
      ELSE.
        p_recextnam = t_email.
      ENDIF.
    ELSE.  "Never found an email address for employee
*** WHO SHOULD WE SEND TO HERE??? ***
    ENDIF.
* Employee number not found.
*Search in ADR6 table
  ELSE.
* See if user name is in the username table.
* i.e. The user is not an employee
    SELECT SINGLE addrnumber
                  persnumber
             INTO (usr21-addrnumber, usr21-persnumber)
             FROM usr21
            WHERE bname = p_uname.
    IF sy-subrc = 0.
* Found user name now let's get the email address
      SELECT SINGLE smtp_addr
               INTO t_email
               FROM adr6
              WHERE addrnumber = usr21-addrnumber
                AND persnumber = usr21-persnumber.
      IF sy-subrc <> 0 OR t_email IS INITIAL.
*** WHO SHOULD WE SEND TO HERE??? ***
      ELSE.  "Found email
        IF NOT p_recextnam IS INITIAL.
          CONCATENATE p_recextnam t_email INTO p_recextnam SEPARATED BY ','.
        ELSE.
          p_recextnam = t_email.
        ENDIF.
      ENDIF.
    ELSE.   "UNAME just does not have an email address addigned at all
*** WHO SHOULD WE SEND TO HERE??? ***
    ENDIF.
  ENDIF.
ENDFORM.                    " find_email_address

Back to Sending Mails - Home Page

Generates PDF output from pre-existing ZFHR_TRAVEL_REQUEST Adobe Form.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA : function TYPE funcname,
       ftype TYPE fpinterfacetype,
       fname TYPE funcname.
DATA : outputparams TYPE sfpoutputparams.

PARAMETER:      p_email   TYPE adr6-smtp_addr OBLIGATORY.

outputparams-nodialog = 'X'.
outputparams-preview = 'X'.
outputparams-dest = 'PDF1'.

outputparams-getpdf = 'X'.

DATA: fp_docparams TYPE sfpdocparams.
DATA: fp_formoutput TYPE fpformoutput.

CALL FUNCTION 'FP_JOB_OPEN'
  CHANGING
    ie_outputparams       = outputparams
* EXCEPTIONS
*   CANCEL                = 1
*   USAGE_ERROR           = 2
*   SYSTEM_ERROR          = 3
*   INTERNAL_ERROR        = 4
*   OTHERS                = 5
          .
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
  EXPORTING
    i_name              = 'ZFHR_TRAVEL_REQUEST'
  IMPORTING
    e_funcname          = function
    e_interface_type    = ftype
    ev_funcname_inbound = fname.

fp_docparams-langu = 'E'.
fp_docparams-country = 'IN'.
fp_docparams-fillable = 'X'.

CALL FUNCTION function
 EXPORTING
   /1bcdwb/docparams        = fp_docparams
   employeename             = '00050104'
 IMPORTING
   /1bcdwb/formoutput       = fp_formoutput
* EXCEPTIONS
*   USAGE_ERROR              = 1
*   SYSTEM_ERROR             = 2
*   INTERNAL_ERROR           = 3
*   OTHERS                   = 4
          .
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

CALL FUNCTION 'FP_JOB_CLOSE'
* IMPORTING
*   E_RESULT             =
* EXCEPTIONS
*   USAGE_ERROR          = 1
*   SYSTEM_ERROR         = 2
*   INTERNAL_ERROR       = 3
*   OTHERS               = 4
          .
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

************************************************************
*Download file

DATA: filename TYPE string,
 path TYPE string,
 fullpath TYPE string,
 default_extension TYPE string VALUE 'PDF'.
cl_gui_frontend_services=>file_save_dialog(
EXPORTING
default_extension = default_extension
CHANGING
filename = filename
path = path
fullpath = fullpath ).
CHECK fullpath IS NOT INITIAL.

DATA: data_tab TYPE TABLE OF x255.

CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
  EXPORTING
    buffer     = fp_formoutput-pdf
  TABLES
    binary_tab = data_tab.

*filename = 'E:\adobe\emptest.pdf'.

cl_gui_frontend_services=>gui_download(
EXPORTING
filename = filename
filetype = 'BIN'
CHANGING
data_tab = data_tab ).
cl_gui_frontend_services=>execute(
EXPORTING
document = filename ).

************************************************************
* Mail

* BCS data
DATA  send_request       TYPE REF TO cl_bcs.
DATA  text               TYPE bcsy_text.
DATA  document           TYPE REF TO cl_document_bcs.
DATA  recipient          TYPE REF TO if_recipient_bcs.
DATA: bcs_exception      TYPE REF TO cx_bcs.
DATA  sent_to_all        TYPE os_boolean.
DATA  pdf_content        TYPE solix_tab.
DATA  lp_pdf_size        TYPE so_obj_len.

TRY.
*   --------- create persistent send request ---------------------
    send_request = cl_bcs=>create_persistent( ).

*   --------- add document ---------------------------------------
*   get PDF xstring and convert it to BCS format
    lp_pdf_size = XSTRLEN( fp_formoutput-pdf ).

    pdf_content = cl_document_bcs=>xstring_to_solix(
        ip_xstring = fp_formoutput-pdf ).

    document = cl_document_bcs=>create_document(
          i_type    = 'PDF'
          i_hex     = pdf_content
          i_length  = lp_pdf_size
          i_subject = 'Travel Request form' ).              "#EC NOTEXT

*   add document to send request
    send_request->set_document( document ).

*   --------- add recipient (e-mail address) ---------------------
    recipient = cl_cam_address_bcs=>create_internet_address(
        i_address_string = p_email ).

*   add recipient to send request
    send_request->add_recipient( i_recipient = recipient ).

*   --------- send document --------------------------------------
    sent_to_all = send_request->send(
        i_with_error_screen = 'X' ).

    IF sent_to_all = 'X'.
      MESSAGE i022(so).
    ENDIF.

*   --------- explicit 'commit work' is mandatory! ---------------
    COMMIT WORK.

* ------------------------------------------------------------------
* *            exception handling
* ------------------------------------------------------------------
* * replace this very rudimentary exception handling
* * with your own one !!!
* ------------------------------------------------------------------
  CATCH cx_bcs INTO bcs_exception.
    WRITE: text-001.
    WRITE: text-002, bcs_exception->error_type.
    EXIT.

ENDTRY.

Hi All

I  always struggle to analyze the classes in so50 tcode, not able to debug them when triggered via a  mail ,Nevertheless I found a way of simulating it. 

Isn't standard program BCS_TEST03 sufficient for testing inbound emails?


Here is custom built code

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT z_so50_exit.

TYPES: BEGIN OF ty_range_att_type,
  zatt TYPE c LENGTH 4,
  zdesc TYPE char50,
END OF ty_range_att_type.
DATA:
  gv_rc TYPE i,
  gv_len TYPE i,
  gv_filename TYPE string.
DATA:
  gs_x TYPE bcss_t100m,
  gs_text TYPE soli.
DATA:
  gt_rc TYPE bcsy_smtpa,
  gt_doc TYPE bcsy_sodoc,
  gt_solix TYPE solix_tab,
  gt_text TYPE bcsy_text.
DATA:
  go_pdfmail TYPE REF TO if_inbound_exit_bcs,
  go_cont TYPE REF TO cl_gui_custom_container,
  go_req TYPE REF TO cl_send_request_bcs,
  go_addr TYPE REF TO cl_cam_address_bcs,
  go_document TYPE REF TO cl_document_bcs,
  go_maint TYPE REF TO cl_ibnd_rules_maint_bcs,
  lt_range_att_type TYPE TABLE OF ty_range_att_type,
  lt_bcsy_smtp2 TYPE bcsy_smtp2,
  ls_range_att_type TYPE ty_range_att_type.

PARAMETERS:
  p_file TYPE tdlen255 LOWER CASE,
  p_file1 TYPE ad_smtpadr LOWER CASE,
  p_file2 TYPE seoclsname LOWER CASE,
  p_file3(3).

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  DATA: gt_file TYPE filetable,
        gs_file TYPE file_table,
        gv_user_action TYPE i.

  CALL METHOD cl_gui_frontend_services=>file_open_dialog
    EXPORTING
      default_extension       = '*'
      file_filter             = '*'
    CHANGING
      file_table              = gt_file
      rc                      = gv_rc
      user_action             = gv_user_action
    EXCEPTIONS
      file_open_dialog_failed = 1
      cntl_error              = 2
      error_no_gui            = 3
      not_supported_by_gui    = 4
      OTHERS                  = 5.
  READ TABLE gt_file INTO gs_file INDEX 1.
  p_file = gs_file-filename.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file3.
  CLEAR:lt_range_att_type.
        ls_range_att_type-zatt = 'PDF'.
        ls_range_att_type-zdesc = 'PDF'.
  APPEND ls_range_att_type TO lt_range_att_type.
  ls_range_att_type-zatt = 'XLS'.
  ls_range_att_type-zdesc = 'XLS'.
  APPEND ls_range_att_type TO lt_range_att_type.

  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield    = 'ZDESC'
      dynpprog    = sy-repid
      dynpnr      = sy-dynnr
      dynprofield = 'P_FILE3'
      value_org   = 'S'
    TABLES
      value_tab   = lt_range_att_type.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file2.
  CLEAR:lt_bcsy_smtp2.
  CREATE OBJECT:
  go_cont
    EXPORTING container_name = 'CCONT'
  ,
  go_maint
    EXPORTING io_cont = go_cont.

  go_maint->read_smtp_entries( IMPORTING et_entries = lt_bcsy_smtp2 ).

  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield    = 'CLS_NAME'
      dynpprog    = sy-repid
      dynpnr      = sy-dynnr
      dynprofield = 'P_FILE2'
      value_org   = 'S'
    TABLES
      value_tab   = lt_bcsy_smtp2.

START-OF-SELECTION.
  gv_filename = p_file.

  cl_gui_frontend_services=>gui_upload(
    EXPORTING filename = gv_filename
              filetype = 'BIN'
    IMPORTING filelength = gv_len
    CHANGING data_tab = gt_solix
    EXCEPTIONS OTHERS = 1 ).

  CHECK sy-subrc = 0.
  go_req = cl_send_request_bcs=>create( ).
  go_addr = cl_cam_address_bcs=>create_internet_address( i_address_string = p_file1 ).
  go_req->setu_sender( go_addr ).
  go_req->set_tech_sender( go_addr ).
  gs_text = 'Hello'.
  APPEND gs_text TO gt_text.

  go_document = cl_document_bcs=>create_document(
    i_type = 'RAW'
    i_text = gt_text
    i_length = '0'
    i_subject = 'Dummy text' ).

  go_document->add_attachment( i_attachment_type = p_file3
    i_attachment_subject = 'My attachment'
    i_att_content_hex = gt_solix ).

  go_req->setu_document( i_document = go_document ).
*create object reference of type class
  CALL METHOD (p_file2)=>if_inbound_exit_bcs~create_instance
    RECEIVING
      ro_ref = go_pdfmail.
*casting of object reference to interface
  go_pdfmail->process_inbound(
    EXPORTING
      io_sreq = go_req
      it_recipients = gt_rc
      it_doctypes = gt_doc
    IMPORTING
      e_retcode = gv_rc
      es_t100msg = gs_x ).

Author: Pratik Mallick
Submitted: 5th August,2008

Description

In the code gallery I have found a number of examples showing how to attach an attachment to an email.  There are examples of multi attachments too. But what the code snippets lack is proper explanation. Most of them are just codes which needs to be copy pasted without proper understanding. I have attempted to simplify the understanding by this simple, basic example of attaching an attachment. In code comments I have tried to explain the requirement of each step. Hope this is appreciated. Thank You.

*CODE*
REPORT  z_pratik_attachment          LINE-SIZE 132
                                     LINE-COUNT 65
                                     NO STANDARD PAGE HEADING.


***********************************************************************
* INTERNAL TABLES                                                                                      *
***********************************************************************

DATA:
      i_objpack   TYPE STANDARD TABLE OF sopcklsti1,
      i_objtext   TYPE STANDARD TABLE OF solisti1,
      i_objbin    TYPE STANDARD TABLE OF solisti1,
      i_receivers TYPE STANDARD TABLE OF somlreci1.




***********************************************************************
* WORK AREAS                                                                                              *
***********************************************************************
DATA: wa_email_doc TYPE sodocchgi1,
      wa_objpack   TYPE sopcklsti1,
      wa_objtext   TYPE solisti1,
      wa_receivers TYPE somlreci1.

***********************************************************************
* CONSTANTS                                                                                                 *
***********************************************************************
CONSTANTS: c_x     TYPE flag   VALUE 'X',
           c_u     TYPE char1  VALUE 'U'.


***********************************************************************
* START-OF-SELECTION                                                                               *
***********************************************************************
START-OF-SELECTION.

***********************************************************************
* END-OF-SELECTION                                                                                   *
***********************************************************************
END-OF-SELECTION.

  wa_email_doc-obj_name = 'Attachment Example'.
  "Mail Subject
  wa_email_doc-obj_descr
  = 'How to attach Multiple Attachments to an Email'.

* Main Mail body Text in itab i_objtext
  wa_objtext+0(36)  = 'We are not going to print this line.'.
  APPEND wa_objtext TO i_objtext.
  CLEAR wa_objtext.
  wa_objtext+0(46)  = 'This is the body of the email. We have skipped'.
  APPEND wa_objtext TO i_objtext.
  CLEAR wa_objtext.
  wa_objtext+0(45)  = ' the first line of the mail and printed from '.
  wa_objtext+45(12)  = 'second line.'.
  APPEND wa_objtext TO i_objtext.
  CLEAR wa_objtext.

* Text for the attachments in itab i_objbin
  wa_objtext+0(21)
  = 'This is attachment 1.'.
  APPEND wa_objtext TO i_objbin.
  CLEAR wa_objtext.
  wa_objtext+0(31) = 'We have got another attachment.'.
  APPEND wa_objtext TO i_objbin.
  CLEAR wa_objtext.
  wa_objtext+0(28) = 'This is attachment number 2.'.
  APPEND wa_objtext TO i_objbin.
  CLEAR wa_objtext.




** Creating the entry for the compressed document
*--(1): Creating entry for the Main Mail body text in itab i_objtext

  " wa_objpack-transf_bin
  " Flag for indicating an obj. to be transported in binary form.
  " If this flag is activated ('X'), the table entry describes an
  " object stored in binary format. The content of the object is in
  " the table CONTENTS_BIN. If the flag is not activated, the object
  " content is in the table CONTENTS_TXT in ASCII format.
  wa_objpack-transf_bin = ' '.
  " Starting index(row) For header information in the itab i_objpack
  wa_objpack-head_start = 1.
  " No of lines for the header information in itab i_objpack
  wa_objpack-head_num   = 1.
  " The row(index) of the itab i_objtext from where the Mail Body starts
  wa_objpack-body_start = 2.  "Skipped the first Line
  " The number of lines in the Mail body
  wa_objpack-body_num   = 2.  "We have two lines from the 2nd row
  " Document type. There are also whole lot of other options
  wa_objpack-doc_type   = 'RAW'.
  wa_objpack-obj_name   = 'MAIN BODY'.
  wa_objpack-obj_descr  = 'MAIL BODY TEXT'.
  wa_objpack-obj_langu  = ' '.
  " In this case one can skip this. Normally ist calculated as
  " no of linex * 255
  wa_objpack-doc_size = ' '.

  APPEND wa_objpack TO i_objpack.
  CLEAR wa_objpack.

*--(2): Creating entry for the Attachment text in itab i_objbin
*----Attachment 1----*
  wa_objpack-transf_bin = c_x.
  wa_objpack-head_start = 2.
  wa_objpack-head_num   = 1.
  wa_objpack-body_start = 1. "Itab i_objbin row number
  wa_objpack-body_num   = 2.
  wa_objpack-doc_size =  510 . "Approximately for 2 Lines-> 255 * 2
  wa_objpack-doc_type   = 'RAW'.
  wa_objpack-obj_name   = 'Attachment 1'.
  wa_objpack-obj_descr  = 'Attachment 1'.
  wa_objpack-obj_langu  = ' '.
  APPEND wa_objpack TO i_objpack.

*--(3): Creating entry for the Attachment text in itab i_objbin
*----Attachment 2----*
  wa_objpack-transf_bin = c_x.
  wa_objpack-head_start = 3.
  wa_objpack-head_num   = 1.
  wa_objpack-body_start = 3.     "Itab i_objbin row number
  wa_objpack-body_num   = 1.
  wa_objpack-doc_size   =  255 . "Approximately for 1 Line
  wa_objpack-doc_type   = 'RAW'.
  wa_objpack-obj_name   = 'Attachment 2'.
  wa_objpack-obj_descr  = 'Attachment 2'.
  wa_objpack-obj_langu  = ' '.
  APPEND wa_objpack TO i_objpack.


*Building the recepient list
** Receipient information
  wa_receivers-receiver = sy-uname.
  wa_receivers-rec_type = 'B'. "To SAP Inbox
  APPEND wa_receivers TO i_receivers.
  CLEAR wa_receivers.

  wa_receivers-receiver = 'abc@gmail.com'.
  wa_receivers-rec_type = c_u.
  APPEND wa_receivers TO i_receivers.
  CLEAR wa_receivers.

* Finally Send the Document
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = wa_email_doc
      put_in_outbox              = 'X'
      commit_work                = 'X'
    TABLES
      packing_list               = i_objpack
      contents_bin               = i_objbin
      contents_txt               = i_objtext
      receivers                  = i_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
  IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT ztsapmail.
DATA: x_object_type LIKE sood-objtp.
DATA: BEGIN OF x_object_hd_change.
        INCLUDE STRUCTURE sood1.
DATA: END OF x_object_hd_change.
DATA: BEGIN OF x_objcont OCCURS 10.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objcont.
DATA: BEGIN OF x_objhead OCCURS 0.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objhead.
DATA: BEGIN OF raw_head.
        INCLUDE STRUCTURE sorh.
DATA: END OF raw_head.
DATA: BEGIN OF x_receivers OCCURS 0.
        INCLUDE STRUCTURE soos1.
DATA: END OF x_receivers.
PARAMETERS: receiver LIKE x_receivers-recnam. " Name
*BUILD MESSAGE HEADERMOVE 'Sort field goes here' TO X_OBJECT_HD_CHANGE-OBJSRT. " Sort field
MOVE 'Name of the object goes here' TO x_object_hd_change-objnam. " Name
MOVE 'Document title goes here' TO x_object_hd_change-objdes. " Title
MOVE 'F' TO x_object_hd_change-objsns. " Functional OBJECT
MOVE 'E' TO x_object_hd_change-objla. " Language
* Object type of the new documentMOVE 'RAW' TO X_OBJECT_TYPE.
CLEAR x_objcont.
MOVE 'Contents of mail' TO x_objcont-line.
APPEND x_objcont.
CLEAR x_objcont-line.
APPEND x_objcont.
MOVE 'More contents' TO x_objcont-line.
APPEND x_objcont.
MOVE 'Still more contents'
TO x_objcont-line.
APPEND x_objcont.
MOVE ' ' TO x_objcont-line.
APPEND x_objcont.
* Specific header (Dependent on the object type, here RAW)REFRESH X_OBJHEAD.
DESCRIBE TABLE x_objcont LINES raw_head-rawsiz.
MOVE raw_head TO x_objhead.
APPEND x_objhead.
*RECEIVERS tableCLEAR X_RECEIVERS.
REFRESH x_receivers.
MOVE receiver TO x_receivers-recnam. " Name
MOVE 'B' TO x_receivers-recesc. " Receiver type
MOVE 'X' TO x_receivers-sndcp. " Send as a copy
MOVE 'X' TO x_receivers-sndex. " EXPRESS DOCUMENT
APPEND x_receivers.
CALL FUNCTION 'SO_OBJECT_SEND'
  EXPORTING
    folder_id        = 'OUTBOX'
    object_hd_change = x_object_hd_change
    object_type      = x_object_type
    outbox_flag      = 'X'
    owner            = sy-uname
    tablesobjcont    = x_objcont
    objhead          = x_objhead
    receivers        = x_receivers.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
* Sending Emails and Sap mail using ABAP
REPORT ztunixmail.

DATA : to_address LIKE sy_lisel,from_address LIKE sy-lisel,
subject LIKE sy-lisel,
attachment_name LIKE sy_lisel,
data_file_path LIKE sxpgcolist-parameters,
body_file_path LIKE sxpgcolist-parameters.
DATA : BEGIN OF int_email_attach OCCURS 0,
  txtline TYPE char255,
END OF int_email_attach.
DATA : BEGIN OF int_email_body OCCURS 0,
  txtline TYPE char255,
END OF int_email_body.
CLEAR : int_exec_protocol,int_email_attach,int_email_body.
REFRESH : int_exec_protocol,int_email_attach,int_email_body.

int_email_attach-txtline = 'Put all attachment text in this table'.
APPEND int_email_attach.
CLEAR int_email_attach.
int_email_body-txtline = 'Put all attachment text in this table'.
APPEND int_email_body.
CLEAR int_email_body.

CONCATENATE to_addressfrom_address
subject
body_file_path
data_file_path
attachment_name
INTO v_parameters.

IF NOT int_email_attach[] IS INITIAL.
  OPEN DATASET data_file_path FOR OUTPUT IN TEXT MODE.
  LOOP AT int_email_attach.
    TRANSFER int_email_attach-txtline TO data_file_path.
  ENDLOOP.
  CLOSE DATASET data_file_path.
ENDIF.

IF NOT int_email_body[] IS INITIAL.
  OPEN DATASET body_file_path FOR OUTPUT IN TEXT MODE.
  LOOP AT int_email_body.
    TRANSFER int_email_body-txtline TO body_file_path.
  ENDLOOP.
  CLOSE DATASET body_file_path.
ENDIF.

CALL FUNCTION 'SXPG_CALL_SYSTEM'
  EXPORTING
    commandname                = 'Z_EMAIL' " Command calling unix script
    parameters                 = v_parameters
    tablesexec_protocol        = int_exec_protocol
  EXCEPTIONS
    no_permission              = 1
    command_not_found          = 2
    parameters_too_long        = 3
    security_risk              = 4
    wrong_check_call_interface = 5
    program_start_error        = 6
    program_termination_error  = 7
    x_error                    = 8
    parameter_expected         = 9
    too_many_parameters        = 10
    illegal_command            = 11
    OTHERS                     = 12.

Author: Runal Singh
Submitted: 16/01/2008

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FUNCTION z_send_email_itab_uname.
*"----------------------------------------------------------------------*"
*"Local interface:
*"  IMPORTING
*"     VALUE(APPLICATION) LIKE  SOOD1-OBJNAM
*"     VALUE(EMAILTITLE) LIKE  SOOD1-OBJDES
*"     VALUE(RECEXTNAM) LIKE  SOOS1-RECEXTNAM OPTIONAL
*"     VALUE(SENDER) LIKE  SOUD-USRNAM DEFAULT SY-UNAME
*"     VALUE(UNAME) LIKE  SOOS1-RECEXTNAM OPTIONAL
*"  EXPORTING
*"     VALUE(RETURN_CODE) LIKE  SY-SUBRC
*"  TABLES
*"     TEXTTAB STRUCTURE  SOLI
*"----------------------------------------------------------------------
* tables
  TABLES: pa0105,  "Employee detail for username and email address
          usr21,   "Login addition address data
          adr6.    "Address table for email addresses
*- local data declaration
  DATA: ohd    LIKE sood1,
        oid    LIKE soodk,
        to_all LIKE sonv-flag,
        t_uname LIKE sy-uname,
        okey   LIKE swotobjid-objkey.
  DATA: BEGIN OF receivers OCCURS 0.
          INCLUDE STRUCTURE soos1.
  DATA: END OF receivers.
*- fill odh
  CLEAR ohd.
  ohd-objla    = sy-langu.
  ohd-objnam   = application.
  ohd-objdes   = emailtitle.
  ohd-objpri   = 3.
  ohd-objsns   = 'F'.
  ohd-ownnam   = sy-uname.

  IF NOT uname IS INITIAL.
* Find personnel number of username
    CONDENSE uname NO-GAPS.
    WHILE uname CS ','.
      t_uname = uname+0(sy-fdpos).
      ADD 1 TO sy-fdpos.
      SHIFT uname LEFT BY sy-fdpos PLACES.
      PERFORM find_email_address USING t_uname
                              CHANGING recextnam.
    ENDWHILE.
*Do the last record
    IF uname <> space.
      t_uname = uname.
      PERFORM find_email_address USING t_uname
                              CHANGING recextnam.
    ENDIF.
  ENDIF.
*- send Email
  IF NOT recextnam IS INITIAL.
    CONDENSE recextnam NO-GAPS.
    CHECK recextnam CS '@'.
  ENDIF.
*- for every individual recipient send an Email*
  WHILE recextnam CS ','.
    PERFORM init_rec TABLES receivers.
    READ TABLE receivers INDEX 1.
    receivers-recextnam = recextnam+0(sy-fdpos).
    ADD 1 TO sy-fdpos.
    SHIFT recextnam LEFT BY sy-fdpos PLACES.
    MODIFY receivers INDEX 1.
    PERFORM so_object_send_rec  TABLES texttab receivers
                                USING ohd sender.
  ENDWHILE.
*- check last recipient in recipient list
  IF recextnam <> space.
    PERFORM init_rec TABLES receivers.
    READ TABLE receivers INDEX 1.
    receivers-recextnam = recextnam.
    MODIFY receivers INDEX 1.
    PERFORM so_object_send_rec
    TABLES texttab receivers
    USING ohd            sender.
  ENDIF.
ENDFUNCTION.

*---------------------------------------------------------------------*
*       FORM SO_OBJECT_SEND_REC                                       *
*---------------------------------------------------------------------*
FORM  so_object_send_rec TABLES  objcont STRUCTURE soli
                                 receivers    STRUCTURE soos1
                          USING  object_hd    STRUCTURE sood1
                                 sender LIKE soud-usrnam.
  DATA:   oid     LIKE soodk,
          to_all  LIKE sonv-flag,
          okey    LIKE swotobjid-objkey.
  CALL FUNCTION 'SO_OBJECT_SEND'
    EXPORTING
      extern_address             = 'X'
      object_hd_change           = object_hd
      object_type                = 'RAW'
      outbox_flag                = 'X'
      sender                     = sender
    IMPORTING
      object_id_new              = oid
      sent_to_all                = to_all
      office_object_key          = oke
    TABLES
      objcont                    = objcont
      receivers                  = receivers
    EXCEPTIONS
      active_user_not_exist      = 1
      communication_failure      = 2
      component_not_available    = 3
      folder_not_exist           = 4
      folder_no_authorization    = 5
      forwarder_not_exist        = 6
      note_not_exist             = 7
      object_not_exist           = 8
      object_not_sent            = 9
      object_no_authorization    = 10
      object_type_not_exist      = 11
      operation_no_authorization = 12
      owner_not_exist            = 13
      parameter_error            = 14
      substitute_not_active      = 15
      substitute_not_defined     = 16
      system_failure             = 17
      too_much_receivers         = 18
      user_not_exist             = 19
      x_error                    = 20
      OTHERS                     = 21.
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        MESSAGE i999(b1) WITH 'Activer user does not exist.' 'Send Mail failed!'.
      WHEN 2.
        MESSAGE i999(b1) WITH 'Communication Failure.' 'Send Mail failed!'.
      WHEN 3.
        MESSAGE i999(b1) WITH 'Component not available.'  'Send Mail failed!'.
      WHEN 4.
        MESSAGE i999(b1) WITH 'Folder does not exist.' 'Send Mail failed!'.
      WHEN 5.
        MESSAGE i999(b1) WITH 'No authorization for folder.' 'Send Mail failed!'.
      WHEN 6.
        MESSAGE i999(b1) WITH 'Forwarder does not exist.' 'Send Mail failed!'.
      WHEN 7.
        MESSAGE i999(b1) WITH 'Note does not exist.'  'Send Mail failed!'.
      WHEN 8.
        MESSAGE i999(b1) WITH 'Object does not exist.' 'Send Mail failed!'.
      WHEN 9.
        MESSAGE i999(b1) WITH 'Object not sent.' 'Send Mail failed!'.
      WHEN 10.
        MESSAGE i999(b1) WITH 'No authorization for object.'  'Send Mail failed!'.
      WHEN 11.
        MESSAGE i999(b1) WITH 'Object type does not exist.' 'Send Mail failed!'.
      WHEN 12.
        MESSAGE i999(b1) WITH 'No authorization for operation.'  'Send Mail failed!'.
      WHEN 13.
        MESSAGE i999(b1) WITH 'Owner does not exist.' 'Send Mail failed!'.
      WHEN 14.
        MESSAGE i999(b1) WITH 'Parameter Error.'   'Send Mail failed!'.
      WHEN 15.
        MESSAGE i999(b1) WITH 'Substitute not active.'  'Send Mail failed!'.
      WHEN 16.
        MESSAGE i999(b1) WITH 'Substitute not defined.'   'Send Mail failed!'.
      WHEN 17.
        MESSAGE i999(b1) WITH 'System failure.' 'Send Mail failed!'.
      WHEN 18.
        MESSAGE i999(b1) WITH 'Too many receivers.'    'Send Mail failed!'.
      WHEN 19.
        MESSAGE i999(b1) WITH 'User does not exist.' 'Send Mail failed!'.
      WHEN 20.
        MESSAGE i999(b1) WITH 'Unknown error ocurred.' 'Send Mail failed!'.
      WHEN 21.
        MESSAGE i999(b1) WITH 'Unknown error ocurred.' 'Send Mail failed!'.
    ENDCASE.
  ENDIF.
ENDFORM.                    "so_object_send_rec
*----------------------------------------------------------------------*
*   FORM INIT_REC
*----------------------------------------------------------------------*
FORM init_rec TABLES receivers STRUCTURE soos1.
  CLEAR receivers.
  REFRESH receivers.
  MOVE sy-datum  TO receivers-rcdat .
  MOVE sy-uzeit  TO receivers-rctim.
  MOVE '1'       TO receivers-sndpri.
  MOVE 'X'       TO receivers-sndex.
  MOVE 'U-'      TO receivers-recnam.
  MOVE 'U'       TO receivers-recesc.
  MOVE 'INT'     TO receivers-sndart.
  MOVE '5'       TO receivers-sortclass.
  APPEND receivers.
ENDFORM.                    "init_rec
*&---------------------------------------------------------------------*
*& Form  find_email_address
*&---------------------------------------------------------------------*
*       Returns the email address for a USERID whether they are an
*       employee or just a user.
*----------------------------------------------------------------------*
*      <--P_RECEXTNAM  Email address
*      -->P_UNAME      USERID
*----------------------------------------------------------------------*
FORM find_email_address USING    p_uname
                        CHANGING p_recextnam LIKE soos1-recextnam.
  DATA:   t_pernr LIKE pa0105-pernr,
          t_email LIKE pa0105-usrid_long.
* STEP 1 - Find personnel number for UNAME
  SELECT SINGLE pernr
           INTO t_pernr
           FROM pa0105
     WHERE subty = '0001'
       AND endda >= sy-datum
       AND begda <= sy-datum
       AND usrid = p_uname.
* Employee record found
  IF sy-subrc = 0.
* STEP 2 - Find email address for personnel number
    SELECT SINGLE usrid_long
             INTO t_email
             FROM pa0105
            WHERE pernr = t_pernr
              AND subty = '0022'
              AND endda >= sy-datum
              AND begda <= sy-datum.
    IF sy-subrc = 0.
      IF NOT p_recextnam IS INITIAL.
        CONCATENATE p_recextnam t_email INTO p_recextnam SEPARATED BY ','.
      ELSE.
        p_recextnam = t_email.
      ENDIF.
    ELSE.  "Never found an email address for employee
*** WHO SHOULD WE SEND TO HERE??? ***
    ENDIF.
* Employee number not found.
* Search in ADR6 table
  ELSE.
* See if user name is in the username table.
* i.e. The user is not an employee
    SELECT SINGLE addrnumber
                  persnumber
             INTO (usr21-addrnumber, usr21-persnumber)
             FROM usr21
            WHERE bname = p_uname.
    IF sy-subrc = 0.
* Found user name now let's get the email address
      SELECT SINGLE smtp_addr
               INTO t_email
               FROM adr6
              WHERE addrnumber = usr21-addrnumber
                AND persnumber = usr21-persnumber.
      IF sy-subrc <> 0 OR t_email IS INITIAL.
*** WHO SHOULD WE SEND TO HERE??? ***
      ELSE.  "Found email
        IF NOT p_recextnam IS INITIAL.
          CONCATENATE p_recextnam t_email INTO p_recextnam SEPARATED BY ','.
        ELSE.
          p_recextnam = t_email.
        ENDIF.
      ENDIF.
    ELSE.   "UNAME just does not have an email address addigned at all
*** WHO SHOULD WE SEND TO HERE??? ***
    ENDIF.
  ENDIF.
ENDFORM.                    " find_email_address

  Note the code snippet for sending mails to outlook with URL

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*** Header
DATA : wa_header TYPE sodocchgi1.

*** Contents Data
DATA : it_content TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0,
       wa_content TYPE solisti1,
*** Receivers Data
       it_receivers TYPE STANDARD TABLE OF somlreci1 INITIAL SIZE 0,
       wa_receivers TYPE somlreci1,
       it_para TYPE STANDARD TABLE OF soparai1 INITIAL SIZE 0,
       wa_para TYPE soparai1.

wa_receivers-receiver = 'abc@sdn.com'.
wa_receivers-rec_type = 'U'.
wa_receivers-com_type = 'INT'.
APPEND wa_receivers TO it_receivers.
CLEAR: wa_receivers.

wa_header-obj_prio = 1.
wa_header-priority = 1.
wa_header-obj_langu = sy-langu.

wa_header-obj_descr = 'Mail with SAP SDN link'.

CONCATENATE 'Dear ' 'SDN ' INTO wa_content-line SEPARATED BY ''.
APPEND wa_content TO it_content.
CLEAR wa_content.

CONCATENATE '<a href="http://www.sdn.sap.com" " target="_blank" >'
            'SAP Developer Network (SDN) </a>'
            ' '
            INTO wa_content-line SEPARATED BY ''.
APPEND wa_content TO it_content.
CLEAR wa_content.

CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
  EXPORTING
    document_data  = wa_header
    document_type  = 'RAW'
    commit_work    = 'X'
  TABLES
    object_content = it_content
    object_para    = it_para
    receivers      = it_receivers.

Author: Mauricio Lauffer
Submitted: 08/03/2012
Related Links:

Send email with new class CL_BCS is very simple!

Follow a example:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&-------------------------------------------------------------*
*& Report  ZEMAIL_CL_BCS                                       *
*&-------------------------------------------------------------*
*& Mauricio Lauffer
*&-------------------------------------------------------------*

  REPORT  zemail_cl_bcs.


  CONSTANTS:
    gc_subject TYPE so_obj_des VALUE 'ABAP Email with CL_BCS',
    gc_raw     TYPE char03 VALUE 'RAW'.

  DATA:
    gv_mlrec         TYPE so_obj_nam,
    gv_sent_to_all   TYPE os_boolean,
    gv_email         TYPE adr6-smtp_addr,
    gv_subject       TYPE so_obj_des,
    gv_text          TYPE bcsy_text,
    gr_send_request  TYPE REF TO cl_bcs,
    gr_bcs_exception TYPE REF TO cx_bcs,
    gr_recipient     TYPE REF TO if_recipient_bcs,
    gr_sender        TYPE REF TO cl_sapuser_bcs,
    gr_document      TYPE REF TO cl_document_bcs.



  TRY.
      "Create send request
      gr_send_request = cl_bcs=>create_persistent( ).


      "Email FROM...
      gr_sender = cl_sapuser_bcs=>create( sy-uname ).
      "Add sender to send request
      CALL METHOD gr_send_request->set_sender
        EXPORTING
          i_sender = gr_sender.


      "Email TO...
      gv_email = 'frodo.baggins@outlook.com'.
      gr_recipient = cl_cam_address_bcs=>create_internet_address( gv_email ).
      "Add recipient to send request
      CALL METHOD gr_send_request->add_recipient
        EXPORTING
          i_recipient = gr_recipient
          i_express   = 'X'.


      "Email BODY
      APPEND 'Hello world! My first ABAP email!' TO gv_text.
      gr_document = cl_document_bcs=>create_document(
                      i_type    = gc_raw
                      i_text    = gv_text
                      i_length  = '12'
                      i_subject = gc_subject ).
      "Add document to send request
      CALL METHOD gr_send_request->set_document( gr_document ).


      "Send email
      CALL METHOD gr_send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = gv_sent_to_all ).
      IF gv_sent_to_all = 'X'.
        WRITE 'Email sent!'.
      ENDIF.

      "Commit to send email
      COMMIT WORK.


      "Exception handling
    CATCH cx_bcs INTO gr_bcs_exception.
      WRITE:
        'Error!',
        'Error type:',
        gr_bcs_exception->error_type.
  ENDTRY.

Back to Sending Mails - Home Page

* Before using following CODE, Need to Create ITS Service for SAP Trasaction thru tcode : SICF

Note : read comments for more details.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
* Data Declaration related to SAP Link Creation for TRIP
*********************************************************
DATA : wda_name     TYPE string,
       in_protocol  TYPE string,
       out_host     TYPE string,
       out_port     TYPE string,
       out_protocol TYPE string,
       val          TYPE string,
       g_url        TYPE string.

* Data Declaration related to Mail
***********************************
DATA :  send_request       TYPE REF TO cl_bcs,
   document           TYPE REF TO cl_document_bcs,
   send TYPE REF TO if_sender_bcs,
   i_text TYPE soli_tab,
   wa_text TYPE soli,
   receiver          TYPE REF TO if_recipient_bcs,
   sent_to_all        TYPE os_boolean,
   sender TYPE adr6-smtp_addr,
   recipient TYPE adr6-smtp_addr,
   subject TYPE so_obj_des.
DATA : temp_addr TYPE adr6-smtp_addr.
***********************************

*********************************************************
* -Generating URL for SAP Trasaction ( SAP GUI for HTML )
*********************************************************
CALL METHOD cl_http_server=>if_http_server~get_location
  EXPORTING
    protocol     = in_protocol
    server       = cl_wdr_task=>server
  IMPORTING
    host         = out_host
    port         = out_port
    out_protocol = out_protocol.

val = sy-mandt.
CONCATENATE out_protocol '://' out_host ':' out_port '/sap/bc/gui/sap/its/ztrip' INTO g_url.
*                                 "  /sap/bc/gui/sap/its/ path for ITS service
*                                 "  ztrip service name for TCODE - TRIP, created thru SICF
CALL METHOD cl_http_server=>append_field_url
  EXPORTING
    name  = 'sap-client'
    value = val
  CHANGING
    url   = g_url.

***************************************
* Sending mail to Outlook with SAP link
***************************************

send_request = cl_bcs=>create_persistent( ).
CONCATENATE 'Dear SDN,' '' INTO wa_text-line.
APPEND wa_text-line TO i_text.

CONCATENATE 'Please find below link for Travel Request ( TRIP ),' '' INTO wa_text-line.
APPEND wa_text-line TO i_text.

CONCATENATE '<a href="' g_url '"  > Link to Travel Request </a>' ' ' INTO wa_text-line.
APPEND wa_text-line TO i_text.

subject = 'SDN : Mail to Outlook with SAPLink'.
document = cl_document_bcs=>create_document(
                       i_type    = 'RAW'
                       i_text    = i_text
                       i_length  = '18'
                       i_subject = subject ).

* add document to send request
CALL METHOD send_request->set_document( document ).

* create internet address for the sender
send = cl_cam_address_bcs=>create_internet_address(
                                 i_address_string = 'SDN@SAP.COM'
                                 i_address_name = 'SAP SDN').

* set the sender to send_request instance
CALL METHOD send_request->set_sender
  EXPORTING
    i_sender = send.

temp_addr = 'sdn@sap.com'. " Receiving Address
receiver = cl_cam_address_bcs=>create_internet_address(
                                        temp_addr  ). " adding receipts

CALL METHOD send_request->add_recipient
  EXPORTING
    i_recipient = receiver
    i_express   = 'X'.

send_request->set_send_immediately( 'X' ).

* sending the mail
CALL METHOD send_request->send(
  EXPORTING
    i_with_error_screen = 'X'
  RECEIVING
    result              = sent_to_all ).
IF sent_to_all = 'X'.
  WRITE :/ 'Mail has sent successfully'.
ENDIF.

With this tutorial it is possible to create contact persons with the BAPI BAPI_ADDRCONTPART_SAVEREPLICA for customers and or vendors.

The example is for customers only.

One of the main problems is that the created contactperson with the BAPI BAPI_ADDRCONTPART_SAVEREPLICA didn't become available in Tcode XD02

This was due to the problem that the table KNVK was not updated trough this BAPI.

Other problem was that with function  SD_CUSTOMER_MAINTAIN_ALL not all necessary contact information could be managed like email adress.

DATA: st_sender TYPE bapi_sender,
      gs_kna1 TYPE kna1,
      h_kunnr TYPE kunnr,
      gt_knvk TYPE STANDARD TABLE OF fknvk,
      gs_knvk TYPE fknvk,
      new_contactid TYPE bapicontact_01-contact,
      new_contactid_create TYPE bapi4003_1-objkey_p,
      gt_bapiad3vl TYPE STANDARD TABLE OF bapiad3vl,
      gs_bapiad3vl TYPE bapiad3vl,
      gt_bapiadsmtp TYPE STANDARD TABLE OF bapiadsmtp,
      gs_bapiadsmtp TYPE bapiadsmtp,
      gt_bapiadtel TYPE STANDARD TABLE OF bapiadtel,
      gs_bapiadtel TYPE bapiadtel,
      objid_cust LIKE bapi4002_1-objkey,
      gs_return TYPE bapiret2,
      gt_return TYPE STANDARD TABLE OF bapiret2,
      gs_commit_return TYPE bapiret2,
      gs_addr_no TYPE bapi4003_1-addr_no,
      gs_pers_no TYPE bapi4003_1-pers_no.

h_kunnr = '1100'.  "example customer code
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
  EXPORTING
    input  = h_kunnr
  IMPORTING
    output = h_kunnr.

SELECT SINGLE * FROM kna1
  INTO gs_kna1
  WHERE kunnr EQ h_kunnr.

gs_knvk-kunnr = h_kunnr.
gs_knvk-name1 =  'lastname'.
gs_knvk-namev = 'firstname'.
gs_knvk-ernam = sy-uname.
gs_knvk-erdat = sy-datum.
APPEND gs_knvk TO gt_knvk.
*lastname en firstname must be the same as passed to the BAPI!
* otherwise the data of KNVK will overwrite the data entered by the BAPI
* this can be tested by entering different fpor knvk and the bapi
* if xd03 is started and double click on the contact you see the bapi details
* if xd02 is started and double click on the contact
****the lastname and firstname of the knvk overwrite the addres  data of the bapi
* other data entered with the bapi like email telephone and roomnumber maintain the values written with the BAPI

CALL FUNCTION 'SD_CUSTOMER_MAINTAIN_ALL'
  EXPORTING
    i_kna1                     = gs_kna1
    i_maintain_address_by_kna1 = ' '
    pi_postflag                = 'X'
  TABLES
    t_xknvk                    = gt_knvk
  EXCEPTIONS
    client_error               = 1
    kna1_incomplete            = 2
    knb1_incomplete            = 3
    knb5_incomplete            = 4
    knvv_incomplete            = 5
    kunnr_not_unique           = 6
    sales_area_not_unique      = 7
    sales_area_not_valid       = 8
    insert_update_conflict     = 9
    number_assignment_error    = 10
    number_not_in_range        = 11
    number_range_not_extern    = 12
    number_range_not_intern    = 13
    account_group_not_valid    = 14
    parnr_invalid              = 15
    bank_address_invalid       = 16
    tax_data_not_valid         = 17
    no_authority               = 18
    company_code_not_unique    = 19
    dunning_data_not_valid     = 20
    knb1_reference_invalid     = 21
    cam_error                  = 22
    OTHERS                     = 23.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* Instead of using BAPI_PARTNEREMPLOYEE_GETINTNUM to retrieve the next number for the parnr
* I use the function  'SD_CUSTOMER_MAINTAIN_ALL' to retrieve the next number
* so the connection with KNVK is already established
READ TABLE gt_knvk INDEX 1 INTO gs_knvk.
new_contactid_create = gs_knvk-parnr.
objid_cust = h_kunnr.
gs_bapiad3vl_x-lastname = 'X'.
gs_bapiad3vl_x-firstname = 'X'.
APPEND gs_bapiad3vl_x TO gt_bapiad3vl_x.
*common data
*lastname en firstname must be the same as passed to KNVK!
gs_bapiad3vl-lastname = 'lastname'.
gs_bapiad3vl-firstname = 'firstname'.
gs_bapiad3vl-pers_group = 'BP'.
gs_bapiad3vl-namcountry = 'NL'.
gs_bapiad3vl-langu_p = 'NL'.
gs_bapiad3vl-room_no_p = 'roomnumber'.
APPEND gs_bapiad3vl TO gt_bapiad3vl.
* email
gs_bapiadsmtp-e_mail = 'youre@email.adres'.
APPEND gs_bapiadsmtp TO gt_bapiadsmtp.
* telephone nr
gs_bapiadtel-telephone = '020-11'.
gs_bapiadtel-extension = '55111'.
APPEND gs_bapiadtel TO gt_bapiadtel.
* instead of the bapi below also the bapi
* BAPI_ADDRESSCONTPART_CHANGE can be used
CALL FUNCTION 'BAPI_ADDRCONTPART_SAVEREPLICA'
  EXPORTING
    obj_type_p       = 'BUS1006001'
    obj_id_p         = new_contactid_create
    obj_type_c       = 'KNA1'
    obj_id_c         = objid_cust
    iv_check_address = 'X'
  IMPORTING
    return           = gs_return
    address_number   = gs_addr_no
    person_number    = gs_pers_no
  TABLES
    bapiad3vl        = gt_bapiad3vl
    bapiadtel        = gt_bapiadtel
    bapiadsmtp       = gt_bapiadsmtp.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
  EXPORTING
    wait   = 'X'
  IMPORTING
    return = gs_commit_return.
 

This porgram send the email with multiple attachments. First all I wanted was to avoid the 255 character limit of the SEND_API function module, but I modified the program so that it is useful to every one.

First it appends all the character data to a string, then the string is converted to XSTRING in order to be compressed. And then attached to the mail.

After going through the code I hope you can alter it according to your needs.

Good Luck.

 
*&---------------------------------------------------------------------*
*& Report  ZTHILANKA_TEST
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ZTHILANKA_TEST.


data: binary_content type solix_tab.
data: xl_content type xstring .

constants:
con_tab  type c value cl_abap_char_utilities=>horizontal_tab,
con_cret type c value cl_abap_char_utilities=>cr_lf.

data: xlcontent type xstring,
      conlength type i,
      conlengths type so_obj_len,
      result_content type string,
      wa_string type string, "This holds all of your data
      dummy type string.

data: send_request type ref to cl_bcs.
data: text type bcsy_text.
data: document type ref to cl_document_bcs.
data: sender type ref to if_sender_bcs.
data: recipient type ref to if_recipient_bcs.
data: recipients type bcsy_smtpa.
data: bcs_exception type ref to cx_bcs.
data: sent_to_all type os_boolean.

data: e_r_page type ref to cl_rsr_www_page.
data: content_length type w3param-cont_len ,
      content_type type w3param-cont_type,
      return_code type w3param-ret_code .
data: html type standard table of w3html .
data: server type string ,
      port type string .
data: wa_rec type ad_smtpadr .
data: bcs_message type string .

data: subject type so_obj_des.
data: sender_id type ad_smtpadr.
data: email type ad_smtpadr.

data: gv_file type string,
      gv_zipfilehex type xstring,
      go_zipper type ref to cl_abap_zip. "The zip folder object

concatenate 'Customer no.'
'CUSTOMER name'
'Subcustomer'
'Sales incoterms'
'Currency'
'Material'
'Mat long text'
'level1'
'level2'
'level3'
'Level 1 description'
'Level 2 description'
'Level 3 description'
'Data'
'Valid from'
'Valid to'
into wa_string separated by con_tab.
concatenate con_cret con_tab wa_string into wa_string.
* After this keep on appending the data to the wa_string
data: i type i,
      true type string.

clear: xl_content .
* convert the string data to xstring
call function 'SCMS_STRING_TO_XSTRING'
exporting
  text = wa_string
* MIMETYPE = ' '
* ENCODING =
importing
  buffer = xl_content.
* EXCEPTIONS
* FAILED = 1
* OTHERS = 2
.
if sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
endif.

gv_file = 'Data.xls'. "Zip file name

create OBJECT go_zipper.
go_zipper->add( name    = gv_file
                content = xl_content )."If you have other content to be added to the zip folder, do it here

gv_zipfilehex = go_zipper->save( ).


concatenate 'Data list ' 'date' into  subject .

sender_id = 'your_email@yourdomain.tld'.
email = 'customer@hisdomain.tld'.

refresh binary_content .

call function 'SCMS_XSTRING_TO_BINARY'
exporting
  buffer     = gv_zipfilehex
tables
  binary_tab = binary_content.


*refresh text .
clear result_content .
*The body message
concatenate
'<p><font color="#000080">Dear Customer,</font></p>'
'<p><font color="#000080">Attached herewith is the data list you requested.</font></p>'

into result_content .
conlength = strlen( result_content ) .
conlengths = conlength .
call function 'SCMS_STRING_TO_FTEXT'
exporting
  text      = result_content
tables
  ftext_tab = text.



try.
  clear send_request .

  send_request = cl_bcs=>create_persistent( ).

  clear document .
  document = cl_document_bcs=>create_document(
  i_type    = 'HTM'
  i_text    = text
  i_length  = conlengths
  i_subject = subject ).

  call method document->add_attachment
  exporting
    i_attachment_type    = 'zip'
    i_attachment_subject = 'Price List' "Attachment name
    i_att_content_hex    = binary_content.


*You can add multiple attachments like below

*        CALL METHOD document->add_attachment
*          EXPORTING
*            i_attachment_type    = 'zip'
*            i_attachment_subject = 'Subject testing 2' "atta_sub
*            i_att_content_hex    = binary_content.
*
*        CALL METHOD document->add_attachment
*          EXPORTING
*            i_attachment_type    = 'zip'
*            i_attachment_subject = 'Subject 3' "atta_sub
*            i_att_content_hex    = binary_content.

*     add document to send request
  call method send_request->set_document( document ).

  clear sender .
  sender = cl_cam_address_bcs=>create_internet_address( sender_id ).
  call method send_request->set_sender
  exporting
    i_sender = sender.

  clear wa_rec .



*     add recipient with its respective attributes to send request
*     you can add multiple recipients in the same mail by calling
*     this method repeatedly.

 clear recipient .
  wa_rec =  email.
  recipient = cl_cam_address_bcs=>create_internet_address(
  wa_rec ).

*  call method send_request->add_recipient
*  exporting
*    i_recipient = recipient1
*    i_express   = 'X'.

*  call method send_request->add_recipient
*  exporting
*    i_recipient = recipient2
*    i_express   = 'X'.



  call method send_request->add_recipient
  exporting
    i_recipient = recipient
    i_express   = 'X'.

  call method send_request->set_status_attributes
  exporting
    i_requested_status = 'E'
    i_status_mail      = 'E'.

  call method send_request->set_send_immediately( 'X' ).
*     ---------- send document ---------------------------------------

  call method send_request->send(
  exporting
    i_with_error_screen = 'X'
    RECEIVING
    result = sent_to_all ).
  if sent_to_all = 'X'.
*APPEND 'Mail sent successfully ' TO return .
  endif.
  commit work.
catch cx_bcs into bcs_exception.
  bcs_message = bcs_exception->get_text( ).
*APPEND bcs_message TO return .
  exit.
endtry.

Submitted: Nov 16 2007

 
TABLES: ekko.  
PARAMETERS: p_email   TYPE somlreci1-receiver
                                  DEFAULT 'test@sapdev.co.uk'.
TYPES: BEGIN OF t_ekpo,
  ebeln TYPE ekpo-ebeln,
  ebelp TYPE ekpo-ebelp,
  aedat TYPE ekpo-aedat,
  matnr TYPE ekpo-matnr,
END OF t_ekpo.
DATA: it_ekpo TYPE STANDARD TABLE OF t_ekpo INITIAL SIZE 0,
      wa_ekpo TYPE t_ekpo.
TYPES: BEGIN OF t_charekpo,
  ebeln(10) TYPE c,
  ebelp(5)  TYPE c,
  aedat(8)  TYPE c,
  matnr(18) TYPE c,
END OF t_charekpo.
DATA: wa_charekpo TYPE t_charekpo.
DATA:   it_message TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                WITH HEADER LINE.
DATA:   it_attach TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                WITH HEADER LINE.
DATA:   t_packing_list LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
        t_contents LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        t_receivers LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
        t_attachment LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        t_object_header LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        w_cnt TYPE i,
        w_sent_all(1) TYPE c,
        w_doc_data LIKE sodocchgi1,
        gd_error    TYPE sy-subrc,
        gd_reciever TYPE sy-subrc.
************************************************************************
*START_OF_SELECTION
START-OF-SELECTION.
*   Retrieve sample data from table ekpo
  PERFORM data_retrieval.
*   Populate table with detaisl to be entered into .xls file
  PERFORM build_xls_data_table.
************************************************************************
*END-OF-SELECTION
END-OF-SELECTION.
* Populate message body text
  perform populate_email_message_body.
* Send file by email as .xls speadsheet
  PERFORM send_file_as_email_attachment
                               tables it_message
                                      it_attach
                                using p_email
                                      'Example .xls documnet attachment'
                                      'XLS'
                                      'filename'
                                      ' '
                                      ' '
                                      ' '
                             changing gd_error
                                      gd_reciever.
*   Instructs mail send program for SAPCONNECT to send email(rsconn01)
  PERFORM initiate_mail_execute_program.
*&---------------------------------------------------------------------*
*&      Form  DATA_RETRIEVAL
*&---------------------------------------------------------------------*
*       Retrieve data form EKPO table and populate itab it_ekko
*----------------------------------------------------------------------*
FORM data_retrieval.
  SELECT ebeln ebelp aedat matnr
   UP TO 10 ROWS
    FROM ekpo
    INTO TABLE it_ekpo.
ENDFORM.                    " DATA_RETRIEVAL
*&---------------------------------------------------------------------*
*&      Form  BUILD_XLS_DATA_TABLE
*&---------------------------------------------------------------------*
*       Build data table for .xls document
*----------------------------------------------------------------------*
FORM build_xls_data_table.
  CONSTANTS: con_cret TYPE x VALUE '0D',  "OK for non Unicode
             con_tab TYPE x VALUE '09'.   "OK for non Unicode
*If you have Unicode check active in program attributes thnen you will
*need to declare constants as follows
*class cl_abap_char_utilities definition load.
*constants:
*    con_tab  type c value cl_abap_char_utilities=>HORIZONTAL_TAB,
*    con_cret type c value cl_abap_char_utilities=>CR_LF.
  CONCATENATE 'EBELN' 'EBELP' 'AEDAT' 'MATNR'
         INTO it_attach SEPARATED BY con_tab.
  CONCATENATE con_cret it_attach  INTO it_attach.
  APPEND  it_attach.
  LOOP AT it_ekpo INTO wa_charekpo.
    CONCATENATE wa_charekpo-ebeln wa_charekpo-ebelp
                wa_charekpo-aedat wa_charekpo-matnr
           INTO it_attach SEPARATED BY con_tab.
    CONCATENATE con_cret it_attach  INTO it_attach.
    APPEND  it_attach.
  ENDLOOP.
ENDFORM.                    " BUILD_XLS_DATA_TABLE
*&---------------------------------------------------------------------*
*&      Form  SEND_FILE_AS_EMAIL_ATTACHMENT
*&---------------------------------------------------------------------*
*       Send email
*----------------------------------------------------------------------*
FORM send_file_as_email_attachment tables pit_message
                                          pit_attach
                                    using p_email
                                          p_mtitle
                                          p_format
                                          p_filename
                                          p_attdescription
                                          p_sender_address
                                          p_sender_addres_type
                                 changing p_error
                                          p_reciever.
  DATA: ld_error    TYPE sy-subrc,
        ld_reciever TYPE sy-subrc,
        ld_mtitle LIKE sodocchgi1-obj_descr,
        ld_email LIKE  somlreci1-receiver,
        ld_format TYPE  so_obj_tp ,
        ld_attdescription TYPE  so_obj_nam ,
        ld_attfilename TYPE  so_obj_des ,
        ld_sender_address LIKE  soextreci1-receiver,
        ld_sender_address_type LIKE  soextreci1-adr_typ,
        ld_receiver LIKE  sy-subrc.
  ld_email   = p_email.
  ld_mtitle = p_mtitle.
  ld_format              = p_format.
  ld_attdescription      = p_attdescription.
  ld_attfilename         = p_filename.
  ld_sender_address      = p_sender_address.
  ld_sender_address_type = p_sender_addres_type.
* Fill the document data.
  w_doc_data-doc_size = 1.
* Populate the subject/generic message attributes
  w_doc_data-obj_langu = sy-langu.
  w_doc_data-obj_name  = 'SAPRPT'.
  w_doc_data-obj_descr = ld_mtitle .
  w_doc_data-sensitivty = 'F'.
* Fill the document data and get size of attachment
  CLEAR w_doc_data.
  READ TABLE it_attach INDEX w_cnt.
  w_doc_data-doc_size =
     ( w_cnt - 1 ) * 255 + STRLEN( it_attach ).
  w_doc_data-obj_langu  = sy-langu.
  w_doc_data-obj_name   = 'SAPRPT'.
  w_doc_data-obj_descr  = ld_mtitle.
  w_doc_data-sensitivty = 'F'.
  CLEAR t_attachment.
  REFRESH t_attachment.
  t_attachment[] = pit_attach[].
* Describe the body of the message
  CLEAR t_packing_list.
  REFRESH t_packing_list.
  t_packing_list-transf_bin = space.
  t_packing_list-head_start = 1.
  t_packing_list-head_num = 0.
  t_packing_list-body_start = 1.
  DESCRIBE TABLE it_message LINES t_packing_list-body_num.
  t_packing_list-doc_type = 'RAW'.
  APPEND t_packing_list.
* Create attachment notification
  t_packing_list-transf_bin = 'X'.
  t_packing_list-head_start = 1.
  t_packing_list-head_num   = 1.
  t_packing_list-body_start = 1.
  DESCRIBE TABLE t_attachment LINES t_packing_list-body_num.
  t_packing_list-doc_type   =  ld_format.
  t_packing_list-obj_descr  =  ld_attdescription.
  t_packing_list-obj_name   =  ld_attfilename.
  t_packing_list-doc_size   =  t_packing_list-body_num * 255.
  APPEND t_packing_list.
* Add the recipients email address
  CLEAR t_receivers.
  REFRESH t_receivers.
  t_receivers-receiver = ld_email.
  t_receivers-rec_type = 'U'.
  t_receivers-com_type = 'INT'.
  t_receivers-notif_del = 'X'.
  t_receivers-notif_ndel = 'X'.
  APPEND t_receivers.
  CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
       EXPORTING
            document_data              = w_doc_data
            put_in_outbox              = 'X'
            sender_address             = ld_sender_address
            sender_address_type        = ld_sender_address_type
            commit_work                = 'X'
       IMPORTING
            sent_to_all                = w_sent_all
       TABLES
            packing_list               = t_packing_list
            contents_bin               = t_attachment
            contents_txt               = it_message
            receivers                  = t_receivers
       EXCEPTIONS
            too_many_receivers         = 1
            document_not_sent          = 2
            document_type_not_exist    = 3
            operation_no_authorization = 4
            parameter_error            = 5
            x_error                    = 6
            enqueue_error              = 7
            OTHERS                     = 8.
* Populate zerror return code
  ld_error = sy-subrc.
* Populate zreceiver return code
  LOOP AT t_receivers.
    ld_receiver = t_receivers-retrn_code.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  INITIATE_MAIL_EXECUTE_PROGRAM
*&---------------------------------------------------------------------*
*       Instructs mail send program for SAPCONNECT to send email.
*----------------------------------------------------------------------*
FORM initiate_mail_execute_program.
  WAIT UP TO 2 SECONDS.
  SUBMIT rsconn01 WITH mode = 'INT'
                WITH output = 'X'
                AND RETURN.
ENDFORM.                    " INITIATE_MAIL_EXECUTE_PROGRAM
*&---------------------------------------------------------------------*
*&      Form  POPULATE_EMAIL_MESSAGE_BODY
*&---------------------------------------------------------------------*
*        Populate message body text
*----------------------------------------------------------------------*
form populate_email_message_body.
  REFRESH it_message.
  it_message = 'Please find attached a list test ekpo records'.
  APPEND it_message.
endform.                    " POPULATE_EMAIL_MESSAGE_BODY
*& Report  ZPLXX_PRO_RE_CS0_EMAIL_INTERF
*&---------------------------------------------------------------------*
*& Program:     Application Server files to Cadbury
*& Developer:   Marcin Pciak - Nearshore PL
*& Date:        05.03.2009
*&
*& Short descr: Program to be used mainly in background jobs, however
*&              may be used directly
*&              It looks for the file on Application Server generated today
*&              and sends it to given external address. Programm uses
*&              global class to populate and dispatch the message. Here data
*&              are only prepared and later encapsulated in the class
*&
*&              If PA_FULL parameter is checked then entire file name with extension must be
*&              specified, otherwise program looks for all files matching this subname
*&
*& Prerequisites: Given file (with today's date) must reside in Application Server
*&---------------------------------------------------------------------*


REPORT  zplxx_pro_re_cs0_email_interf.


"first load class definition - provided later
CLASS lcl_email_dispatcher DEFINITION DEFERRED.


*&---------------------------------------------------------------------*
*&                      SELECTION SCREEN
*&---------------------------------------------------------------------*
DATA: recip TYPE so_recname.


SELECTION-SCREEN BEGIN OF BLOCK blk WITH FRAME TITLE text-tit.
PARAMETERS: pa_dir TYPE epsf-epsdirnam VISIBLE LENGTH 60 OBLIGATORY,  "directory
            pa_file TYPE epsf-epsfilnam VISIBLE LENGTH 40 OBLIGATORY. "file name or its part
*            pa_ext  TYPE c LENGTH 3 VISIBLE LENGTH 3 OBLIGATORY.      "extension
SELECT-OPTIONS so_recip FOR recip NO INTERVALS OBLIGATORY.
PARAMETERS: pa_full AS CHECKBOX.   "is path fully specified?
SELECTION-SCREEN END OF BLOCK blk.


SELECTION-SCREEN BEGIN OF BLOCK bl2 WITH FRAME TITLE text-mes.
PARAMETERS pa_subj TYPE so_obj_des OBLIGATORY.
SELECTION-SCREEN END OF BLOCK bl2.


*&---------------------------------------------------------------------*
*&                            TYPINGS
*&---------------------------------------------------------------------*
TYPES: tt_fdscr TYPE TABLE OF rlgrap-filename,
       tt_recip TYPE TABLE OF so_recname,
       tt_mess  TYPE TABLE OF string.


*&---------------------------------------------------------------------*
*&                          DATA OBJECTS
*&---------------------------------------------------------------------*
"tables to populate the message
DATA: it_fdscr TYPE tt_fdscr,
      it_recip TYPE tt_recip,
      it_mess  TYPE tt_mess.


DATA: gr_email_dispatcher TYPE REF TO lcl_email_dispatcher.


"full file path and name
DATA: full_path TYPE epsf-epspath.


"directory list
DATA: BEGIN OF dir_list OCCURS 0.
        INCLUDE STRUCTURE epsfili.
DATA END OF dir_list.


"file attributes
DATA: BEGIN OF file,
       mtime(6) TYPE p,     "returns time in secs from 1970
       date LIKE sy-datum,
       time(10) TYPE c,     "format 00:00:00
     END OF file.


 INCLUDE ZPLXX_PRO_IN_CS0_EMAIL_INT_C00.


*&---------------------------------------------------------------------*
*&                           GO!
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  "------------------------ get direcotry listing
  CALL FUNCTION 'EPS_GET_DIRECTORY_LISTING'
    EXPORTING
      dir_name               = pa_dir
    TABLES
      dir_list               = dir_list
    EXCEPTIONS
      invalid_eps_subdir     = 1
      sapgparam_failed       = 2
      build_directory_failed = 3
      no_authorization       = 4
      read_directory_failed  = 5
      too_many_read_errors   = 6
      empty_directory_list   = 7
      OTHERS                 = 8.
  IF sy-subrc <> 0.
    MESSAGE 'No such directory' TYPE 'I' DISPLAY LIKE 'E'.
    LEAVE TO SCREEN 0.
  ENDIF.


  "------------------------ get direcotry listing
  LOOP AT dir_list.
    IF pa_full EQ space.
      CHECK dir_list-name CS pa_file.  "consider only files with this name
    ELSE.
      CHECK dir_list-name EQ pa_file.  "check exact name
    ENDIF.


    "get file attributes
    CALL FUNCTION 'EPS_GET_FILE_ATTRIBUTES'
      EXPORTING
        file_name              = dir_list-name
        dir_name               = pa_dir
      IMPORTING
        file_mtime             = file-mtime
      EXCEPTIONS
        read_directory_failed  = 1
        read_attributes_failed = 2
        OTHERS                 = 3.
    IF sy-subrc <> 0.
      CONTINUE.   "skip the file
    ENDIF.


    "get file timestamp (for this change p6 to time from 1970)
    PERFORM p6_to_date_time_tz(rstr0400)
            USING file-mtime
                  file-time
                  file-date.


    "process file generated today
    IF file-date EQ sy-datum.
      CONCATENATE pa_dir '/' dir_list-name INTO full_path.
      APPEND full_path TO it_fdscr.
    ENDIF.
  ENDLOOP.


  "------------------------ process only if any files found
  CHECK it_fdscr[] IS NOT INITIAL.


  "------------------------ set recipients
  LOOP AT so_recip.
    APPEND so_recip-low TO it_recip.
  ENDLOOP.


  "------------------------ set message
  APPEND 'This message was automatically generated in order to supply you with SAP Application Server data file(s).' TO it_mess.
  APPEND 'Check the attachment(s).' TO it_mess.
  APPEND INITIAL LINE TO it_mess.
  APPEND 'Please do not reply to this message.' TO it_mess.
  APPEND INITIAL LINE TO it_mess.
  APPEND '------------------------' TO it_mess.
  APPEND 'With Best Regards' TO it_mess.
  APPEND 'NorthgateArinso team' TO it_mess.


  "------------------------ crate and dispatch message
  CREATE OBJECT gr_email_dispatcher
    EXPORTING
      im_subject   = pa_subj
      im_tab_mess  = it_mess
      im_tab_fdscr = it_fdscr
      im_tab_recip = it_recip.


*&---------------------------------------------------------------------*
*&  Include           ZPLXX_PRO_IN_CS0_EMAIL_INT_C00
*&---------------------------------------------------------------------*


*----------------------------------------------------------------------*
*       CLASS lcl_email_dispatcher DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_email_dispatcher DEFINITION.
  PUBLIC SECTION.
    METHODS: constructor IMPORTING im_subject     TYPE so_obj_des
                                   im_tab_mess    TYPE tt_mess
                                   im_tab_fdscr   TYPE tt_fdscr
                                   im_tab_recip   TYPE tt_recip.


  PRIVATE SECTION.


    "tables
    DATA: it_recipients   TYPE TABLE OF somlreci1,
          it_packing_list TYPE TABLE OF sopcklsti1,
          it_message      TYPE TABLE OF solisti1,
          it_attachments  TYPE TABLE OF solisti1.


    "structures
    DATA: doc_attr        TYPE sodocchgi1.


    METHODS: set_doc_attributes IMPORTING f_subject TYPE so_obj_des, "50 chars
             set_recipients IMPORTING ft_recip TYPE tt_recip,
             set_automatic_message IMPORTING ft_mess TYPE tt_mess,
             initialize_packing_list IMPORTING ft_fdscr TYPE tt_fdscr,
             prepare_data_for_dispatch IMPORTING f_fdscr TYPE rlgrap-filename
                                       CHANGING f_lines TYPE i
                                                fs_packing_list TYPE sopcklsti1,
             get_file_name IMPORTING f_path TYPE rlgrap-filename
                           EXPORTING f_file TYPE so_obj_des,
             dispatch.


ENDCLASS.                    "lcl_email_dispatcher DEFINITION


*----------------------------------------------------------------------*
*       CLASS lcl_email_dispatcher IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_email_dispatcher IMPLEMENTATION.
  METHOD constructor.
    set_doc_attributes( im_subject ).
    set_recipients( im_tab_recip ).
    set_automatic_message( im_tab_mess ).
    initialize_packing_list( im_tab_fdscr ).
    dispatch( ).
  ENDMETHOD.                    "constructor


  METHOD set_doc_attributes.
    "---------------------- Document attributes
    doc_attr-obj_name = 'WAS_FILESEND'.
    doc_attr-obj_descr = f_subject.
    doc_attr-obj_langu = sy-langu.
    doc_attr-sensitivty = 'F'.      "functional message
  ENDMETHOD.                    "set_doc_attributes


  METHOD set_recipients.
    DATA: wa_recip LIKE LINE OF ft_recip,
          wa_recipient  TYPE somlreci1.


    "---------------------- Recipcients
    LOOP AT ft_recip INTO wa_recip.
      wa_recipient-receiver = wa_recip.
      wa_recipient-rec_type = 'U'.               "internet address
      wa_recipient-com_type = 'INT'.             "send via internet
      APPEND wa_recipient TO it_recipients.
    ENDLOOP.
  ENDMETHOD.                    "set_recipients


  METHOD set_automatic_message.
    DATA: wa_mess LIKE LINE OF ft_mess.


    LOOP AT ft_mess INTO wa_mess.
      APPEND wa_mess TO it_message.
    ENDLOOP.
  ENDMETHOD.                    "set_automatic_message


  METHOD initialize_packing_list.
    DATA: wa_fdscr LIKE LINE OF ft_fdscr,
          wa_packing_list TYPE sopcklsti1,
          l_line TYPE i,
          index(3) TYPE n,
          file TYPE so_obj_des.                             "char50


    "--------------------- describe message
    wa_packing_list-transf_bin = space.
    wa_packing_list-body_start = 1.
    DESCRIBE TABLE it_message.
    wa_packing_list-body_num = sy-tfill.
    wa_packing_list-doc_type = 'RAW'.
    APPEND wa_packing_list TO it_packing_list.


    "---------------------- describe attachemnts (one per line)
    l_line = 1.


    LOOP AT ft_fdscr INTO wa_fdscr.


      "------------------ construct attachement name
      get_file_name( EXPORTING f_path = wa_fdscr IMPORTING f_file = file ).


      "------------------ attachment attributes
      CLEAR wa_packing_list.
      wa_packing_list-transf_bin = 'X'.
      wa_packing_list-body_start = l_line.
      index = sy-tabix.
      CONCATENATE 'ATTACH' index INTO wa_packing_list-obj_name.
      wa_packing_list-obj_descr = file.
      wa_packing_list-obj_langu = sy-langu.
      wa_packing_list-doc_type = 'DAT'.          "send as DAT file


      "------------------- get the file form Application server
      CLEAR l_line.
      prepare_data_for_dispatch( EXPORTING f_fdscr = wa_fdscr CHANGING f_lines = l_line
                                                                       fs_packing_list = wa_packing_list ).


      "------------------- return read lines
      wa_packing_list-body_num = l_line.


      "------------------- new attachemnt starts from next line
      l_line = wa_packing_list-body_start + wa_packing_list-body_num.


      APPEND wa_packing_list TO it_packing_list.
    ENDLOOP.
  ENDMETHOD.                    "initialize_packing_list


  METHOD prepare_data_for_dispatch.
    DATA: l_len TYPE i,
          wa_attachment TYPE solisti1.


    OPEN DATASET f_fdscr FOR INPUT IN BINARY MODE.
    IF sy-subrc NE 0.
      "error log here -> can't open file from WAS
    ELSE.
      DO.
        READ DATASET f_fdscr INTO wa_attachment LENGTH l_len.
        IF sy-subrc NE 0.
          EXIT.
        ENDIF.
        APPEND wa_attachment TO it_attachments.
        ADD 1 TO f_lines.
        ADD l_len TO fs_packing_list-doc_size.
      ENDDO.


      "---------------------- all data read in one shot
      IF l_len <> 0.
        APPEND wa_attachment TO it_attachments.
        ADD 1 TO f_lines.
        ADD l_len TO fs_packing_list-doc_size.
      ENDIF.


      CLOSE DATASET  f_fdscr.
    ENDIF.


  ENDMETHOD.                    "prepare_data_for_dispatch


  METHOD get_file_name.
    DATA: off TYPE i,
          len TYPE i,
          file_tmp LIKE f_path.


    WHILE sy-subrc = 0.
      FIND '/' IN SECTION OFFSET off OF f_path
               MATCH OFFSET off
               MATCH LENGTH len.
      IF sy-subrc = 0.
        off = off + len.
      ENDIF.
    ENDWHILE.


    file_tmp = f_path.


    SHIFT file_tmp BY off PLACES LEFT.
    len = STRLEN( file_tmp ).
    SUBTRACT 4 FROM len.
    f_file = file_tmp(len).


  ENDMETHOD.                    "get_file_name


  METHOD dispatch.
    CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
      EXPORTING
        document_data              = doc_attr
        put_in_outbox              = 'X'
        commit_work                = 'X'
      TABLES
        packing_list               = it_packing_list
        contents_bin               = it_attachments
        contents_txt               = it_message
        receivers                  = it_recipients
      EXCEPTIONS
        too_many_receivers         = 1
        document_not_sent          = 2
        document_type_not_exist    = 3
        operation_no_authorization = 4
        parameter_error            = 5
        x_error                    = 6
        enqueue_error              = 7
        OTHERS                     = 8.
    IF sy-subrc = 0.
      WAIT UP TO 2 SECONDS.
      SUBMIT rsconn01 WITH mode = 'INT'
*                        WITH ouput = 'X'
                      AND RETURN.
    ENDIF.
  ENDMETHOD.                    "send_mail


ENDCLASS.                    "lcl_email_sender IMPLEMENTATION

Back to Sending Mails - Home Page

Author: Martin Lang
Submitted: Aug 3rd 2009

Prerequisites: Check for these Notes and apply if required:

Sample Code:

*&---------------------------------------------------------------------*
*& Report  ZAG_CAL_ICAL
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

report  z_appointment_to_outlook.

include <cntn01>.
type-pools: sccon.
data: mail type text40.

* Provide select option to enter multiple attendees
SELECTION-SCREEN: BEGIN OF BLOCK org.
select-options: email for mail no intervals default 'Joe.Doe@test.com'.
SELECTION-SCREEN: END OF BLOCK org.


data lo_appointment type ref to cl_appointment.
data ls_participant type scspart.
data lv_address type swc_object.
data ls_address_container like swcont occurs 0 with header line.
data lt_text type so_txttab.
data ls_text like line of lt_text.
data lv_location like scsappt-room.
data lo_send_request type ref to cl_bcs.
data lv_sent_to_all type os_boolean.

create object lo_appointment.

* Add multiple attendees
loop at email.
clear ls_participant.
swc_create_object lv_address 'ADDRESS' space.
swc_set_element ls_address_container 'AddressString' email-low.
swc_set_element ls_address_container 'TypeId' 'U'.
swc_call_method lv_address 'Create' ls_address_container.
check sy-subrc = 0.

* * get key and type of object
swc_get_object_key lv_address ls_participant-objkey.
check sy-subrc = 0.
swc_get_object_type lv_address ls_participant-objtype.
check sy-subrc = 0.
move sccon_part_sndmail_with_ans to ls_participant-send_mail.
ls_participant-comm_mode = 'INT'.
lo_appointment->add_participant( participant = ls_participant ).

endloop.


* Sample Apppointment for specific date/time
*lo_appointment->set_date( date_from = '20090801'
*                          time_from = '130000'
*                           date_to = '20090801'
*                           time_to = '140000'
*                           ).

* Sample Appointment for All-Day-Event
lo_appointment->set_date( date_from = '20090803'
                          date_to = '20090803'
                          ).

* Make appointment appear "busy"
lo_appointment->set_busy_value( sccon_busy_busy   ).

* Set Location
lo_appointment->set_location_string( 'Location' ).

* Set Organizer
lo_appointment->set_organizer( sy-uname ).

* "Type of Meeting" (value picked from table SCAPPTTYPE)
lo_appointment->set_type( 'ABSENT' ).

* Make this an all day event
lo_appointment->SET_VIEW_ATTRIBUTES( SHOW_ON_TOP  = 'X').

* Set Meeting body text
ls_text = 'This is the Body Text of the Appointment'.
append ls_text to lt_text.
lo_appointment->set_text( lt_text ).

* Set Meeting Subject
lo_appointment->set_title( 'This is the Appointment Subject' ).


* Important to set this one to space. Otherwise SAP will send a not user-friendly e-mail
lo_appointment->save( send_invitation = space ).

* Now that we have the appointment, we can send a good one for outlook by switching to BCS
lo_send_request = lo_appointment->create_send_request( ).

* don't request read/delivery receipts
lo_send_request->set_status_attributes( i_requested_status   = 'N'
                                        i_status_mail        = 'N'
                                         ).

* Send it to the world
lv_sent_to_all = lo_send_request->send( i_with_error_screen = 'X' ).

commit work and wait.

Email with attachements can be sent by using CL_BCS class as below :This code sample can be used as a reference :

The standard class CL_BCS is used to send the notification along with attachment .  CREATE_PERSISTENT is the method which  used to  send request object of the standard class CL_BCS.

Method CREATE_DOCUMENT of CL_DOCUMENT_BCS is used for  creating the text of the email body.Method ADD_ATTACHMENT of  CL_DOCUMENT_BCS is used to creating attachment of the email.Here lt_att_content_hex should contain data

CLASS cl_bcs DEFINITION LOAD.
DATA:  lo_send_request TYPE REF TO cl_bcs
      ,lo_document     TYPE REF TO cl_document_bcs
      ,lo_sender       TYPE REF TO if_sender_bcs
      ,lo_recipient    TYPE REF TO if_recipient_bcs      ,lt_message_body TYPE bcsy_text
      ,lx_document_bcs TYPE REF TO cx_document_bcs
      ,lv_send         TYPE ad_smtpadr VALUE 'xyz@gmail.com'
      ,lv_sent_to_all  TYPE os_boolean     .
"create send request
lo_send_request = cl_bcs=>create_persistent( ).

"create message body and subject
APPEND 'Dear Vendor,' TO lt_message_body.
APPEND INITIAL LINE to lt_message_body.
APPEND 'Please fill the attached .' TO lt_message_body.
APPEND INITIAL LINE to lt_message_body.
APPEND 'Thank You,' TO lt_message_body.

"put your text into the document
lo_document = cl_document_bcs=>create_document(
                 i_type = 'RAW'
                 i_text = lt_message_body
                 i_subject = 'Vendor Payment Form' ).


TRY.
  lo_document->add_attachment(
    EXPORTING
      i_attachment_type = 'PDF'
      i_attachment_subject = 'Form'
      i_att_content_hex = lt_att_content_hex ).

  CATCH cx_document_bcs INTO lx_document_bcs.
ENDTRY.

* Add attachment
* Pass the document to send request
lo_send_request->set_document( lo_document ).


"Create sender
lo_sender = cl_cam_address_bcs=>create_internet_address( l_send ).

"Set sender
lo_send_request->set_sender( lo_sender ).

"Create recipient
lo_recipient = cl_sapuser_bcs=>create( sy-uname ).

*Set recipient
lo_send_request->add_recipient(
     EXPORTING
       i_recipient = lo_recipient i_express = 'X' ).

lo_send_request->add_recipient( lo_recipient ).

* Send email
lo_send_request->send(
  EXPORTING
    i_with_error_screen = 'X'
  RECEIVING
    result = lv_sent_to_all ).

COMMIT WORK.

Author: kalyan Annapareddy
Submitted: 9th june 2008
Related Links:

SAP is a robust system, which gives many facilities in the form of Function Modules (FMs) for connecting to external systems or for use within the system. With a clever use of these FMs we can achieve a lot of things through ABAP code.

This article focuses on ways to send E-mails and SAP Mails using ABAP code.

Firstly SAP Mail

A SAP mail is a mail internal to the SAP system. It is a very good forum to exchange information with other users. Using a SAP mail in ABAP code facilitates exchange of automatic messages at various stages of the business process. It is easy to use and saves many hassles involved in using workflows for exchanging messages.

The ABAP code to send a sap mail is built around the FM SO_OBJECT_SEND which has the following pattern.

CALL FUNCTION 'SO_OBJECT_SEND'
* EXPORTING
*   FOLDER_ID                        = ' '
*   FORWARDER                        = ' '
*   OBJECT_FL_CHANGE                 =
*   OBJECT_HD_CHANGE                 = ' '
*   OBJECT_ID                        = ' '
*   OBJECT_TYPE                      = ' '
*   OUTBOX_FLAG                      = ' '
*   OWNER                            = ' '
*   STORE_FLAG                       = ' '
*   DELETE_FLAG                      = ' '
*   SENDER                           = ' '
*   CHECK_SEND_AUTHORITY             = ' '
*   CHECK_ALREADY_SENT               = ' '
*   GIVE_OBJECT_BACK                 =
*   ORIGINATOR                       = ' '
*   ORIGINATOR_TYPE                  = 'J'
*   LINK_FOLDER_ID                   = ' '
*   SEND_REQUEST_OID                 = ' '
*   IP_ENCRYPT                       = 'U'
*   IP_SIGN                          = 'U'
*   IP_REC_COUNT_ADD                 =
* IMPORTING
*   OBJECT_ID_NEW                    =
*   SENT_TO_ALL                      =
*   ALL_BINDING_DONE                 =
*   OFFICE_OBJECT_KEY                =
*   ORIGINATOR_ID                    =
*   E_SEND_REQUEST_OID               =
* TABLES
*   OBJCONT                          =
*   OBJHEAD                          =
*   OBJPARA                          =
*   OBJPARB                          =
*   RECEIVERS                        =
*   PACKING_LIST                     =
*   ATT_CONT                         =
*   ATT_HEAD                         =
*   NOTE_TEXT                        =
*   LINK_LIST                        =
*   APPLICATION_OBJECT               =
* EXCEPTIONS
*   ACTIVE_USER_NOT_EXIST            = 1
*   COMMUNICATION_FAILURE            = 2
*   COMPONENT_NOT_AVAILABLE          = 3
*   FOLDER_NOT_EXIST                 = 4
*   FOLDER_NO_AUTHORIZATION          = 5
*   FORWARDER_NOT_EXIST              = 6
*   NOTE_NOT_EXIST                   = 7
*   OBJECT_NOT_EXIST                 = 8
*   OBJECT_NOT_SENT                  = 9
*   OBJECT_NO_AUTHORIZATION          = 10
*   OBJECT_TYPE_NOT_EXIST            = 11
*   OPERATION_NO_AUTHORIZATION       = 12
*   OWNER_NOT_EXIST                  = 13
*   PARAMETER_ERROR                  = 14
*   SUBSTITUTE_NOT_ACTIVE            = 15
*   SUBSTITUTE_NOT_DEFINED           = 16
*   SYSTEM_FAILURE                   = 17
*   TOO_MUCH_RECEIVERS               = 18
*   USER_NOT_EXIST                   = 19
*   ORIGINATOR_NOT_EXIST             = 20
*   X_ERROR                          = 21
*   OTHERS                           = 22
          .
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.

 

Author: Saravanan M

Submitted: <06 Sep 2011>
Related Links:

Class CL_BCS: http://help.sap.com/saphelp_sm32/helpdata/en/2d/1c5d3aebba4c38e10000000a114084/content.htm

Class CL_DOCUMENT_BCS: http://help.sap.com/saphelp_NW70EHP1core/helpdata/en/8c/5bf13b68402b69e10000000a11402f/content.htm

Description

This article describes how to convert internal table value into excel and sending excel in email using class CL_BCS and CL_DOCUMENT_BCS.

Selection Screen:

Selection Screen.bmp
 

*&---------------------------------------------------------------------*
*& Report ZSDRR_DAILY_FEED
*&
*&---------------------------------------------------------------------*
*& Description : This is the report program to send email with *
*& list of new contract created daily, weekly and *
*& monthly to specified email ID in the selection *
*& screen. *
*&---------------------------------------------------------------------*
REPORT zsdrr_daily_feed.
TABLES: mara.
*/..Types Declarations
TYPES : BEGIN OF ty_vbak,
vbeln TYPE vbak-vbeln,
erdat TYPE vbak-erdat,
auart TYPE vbak-auart,
augru TYPE vbak-augru,
vkbur TYPE vbak-vkbur,
kunnr TYPE vbak-kunnr,
END OF ty_vbak,
BEGIN OF ty_vbkd,
vbeln TYPE vbkd-vbeln,
posnr TYPE vbkd-posnr,
zzreinstate TYPE vbkd-zzreinstate,
zzexpired TYPE vbkd-zzexpired,
zzlatesale TYPE vbkd-zzlatesale,
zzrenewal TYPE vbkd-zzrenewal,
END OF ty_vbkd,
BEGIN OF ty_veda,
vbeln TYPE veda-vbeln,
vposn TYPE veda-vposn,
vbegdat TYPE veda-vbegdat,
venddat TYPE veda-venddat,
vkuegru TYPE veda-vkuegru,
vbedkue TYPE veda-vbedkue,
END OF ty_veda,
BEGIN OF ty_vbap,
vbeln TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
matnr TYPE vbap-matnr,
zmeng TYPE vbap-zmeng,
kzwi3 TYPE vbap-kzwi3,
kzwi5 TYPE vbap-kzwi5,
maktx TYPE makt-maktx,
mtart TYPE mara-mtart,
END OF ty_vbap,
BEGIN OF ty_vbpa,
vbeln TYPE vbpa-vbeln,
posnr TYPE vbpa-posnr,
parvw TYPE vbpa-parvw,
kunnr TYPE vbpa-kunnr,
pernr TYPE vbpa-pernr,
adrnr TYPE vbpa-adrnr,
END OF ty_vbpa,
BEGIN OF ty_vbpa_s,
sobid TYPE hrp1001-sobid,
kunnr TYPE but000-partner,
END OF ty_vbpa_s,
BEGIN OF ty_adrc,
addrnumber TYPE adrc-addrnumber,
name1 TYPE adrc-name1,
name2 TYPE adrc-name2,
street TYPE adrc-street,
city1 TYPE adrc-city1,
post_code1 TYPE adrc-post_code1,
country TYPE adrc-country,
region TYPE adrc-region,
tel_number TYPE adrc-tel_number,
END OF ty_adrc,
BEGIN OF ty_adr6,
addrnumber TYPE adrc-addrnumber,
smtp_addr TYPE adr6-smtp_addr,
END OF ty_adr6,
BEGIN OF ty_but000,
partner TYPE but000-partner,
bpkind TYPE but000-bpkind,
bu_group TYPE but000-bu_group,
name_last TYPE but000-name_last,
name_first TYPE but000-name_first,
END OF ty_but000,
BEGIN OF ty_hrp1001,
otype TYPE hrp1001-otype,
objid TYPE hrp1001-objid,
plvar TYPE hrp1001-plvar,
relat TYPE hrp1001-relat,
begda TYPE hrp1001-begda,
endda TYPE hrp1001-endda,
sclas TYPE hrp1001-sclas,
sobid TYPE hrp1001-sobid,
END OF ty_hrp1001,
BEGIN OF ty_vbfa,
vbelv TYPE vbfa-vbelv,
posnv TYPE vbfa-posnv,
vbeln TYPE vbfa-vbeln,
posnn TYPE vbfa-posnn,
vbtyp_n TYPE vbfa-vbtyp_n,
vbtyp_v TYPE vbfa-vbtyp_v,
END OF ty_vbfa,
BEGIN OF ty_vbeln,
vbeln TYPE vbak-vbeln,
posnr TYPE vbap-posnr,
END OF ty_vbeln.
TYPES: BEGIN OF ty_kna1,
kunnr TYPE kna1-kunnr,
erdat TYPE kna1-erdat,
END OF ty_kna1.
TYPES: BEGIN OF x_final,
auart TYPE vbak-auart,
erdat TYPE vbak-erdat,
augru TYPE vbak-augru,
vbeln TYPE vbak-vbeln,
posnr TYPE vbap-posnr,
kunnr TYPE vbak-kunnr,
name(60) TYPE c,
telf1 TYPE sza1_d0100-tel_number,
smtp_addr TYPE sza1_d0100-smtp_addr,
street TYPE addr1_data-street,
city1 TYPE addr1_data-city1,
region TYPE addr1_data-region,
post_code1 TYPE addr1_data-post_code1,
country TYPE addr1_data-country,
kunnr_b TYPE vbak-kunnr,
name_b(60) TYPE c,
telf1_b TYPE sza1_d0100-tel_number,
smtp_addr_b TYPE sza1_d0100-smtp_addr,
street_b TYPE addr1_data-street,
city1_b TYPE addr1_data-city1,
region_b TYPE addr1_data-region,
post_code1_b TYPE addr1_data-post_code1,
country_b TYPE addr1_data-country,
matnr TYPE vbap-matnr,
maktx TYPE makt-maktx,
zmeng TYPE vbap-zmeng,
vbegdat TYPE veda-vbegdat,
venddat TYPE veda-venddat,
kzwi3 TYPE vbap-kzwi3,
con_val TYPE vbap-kzwi3,
sales_rep TYPE vbak-kunnr,
vkbur TYPE vbak-vkbur,
END OF x_final,
BEGIN OF x_log,
message TYPE string,
END OF x_log.
*/..Workarea Declarations
DATA: w_vbak TYPE ty_vbak,
w_veda TYPE ty_veda,
w_vbkd TYPE ty_vbkd,
w_vbap TYPE ty_vbap,
w_vbpa TYPE ty_vbpa,
w_adrc TYPE ty_adrc,
w_adr6 TYPE ty_adr6,
w_vbfa TYPE ty_vbfa,
w_vbeln TYPE ty_vbeln,
w_tvarv TYPE tvarv,
w_final TYPE x_final,
w_log TYPE x_log,
w_veda_new TYPE ty_veda,
w_kna1 TYPE ty_kna1.
*/..Data Declarations
DATA : gv_datefrm TYPE sy-datum,
gv_dateto TYPE sy-datum,
gv_order TYPE string.
DATA: t_vbak TYPE STANDARD TABLE OF ty_vbak,
t_vbkd TYPE STANDARD TABLE OF ty_vbkd,
t_veda TYPE STANDARD TABLE OF ty_veda,
t_vbap TYPE STANDARD TABLE OF ty_vbap,
t_vbpa TYPE STANDARD TABLE OF ty_vbpa,
t_vbpa_s TYPE STANDARD TABLE OF ty_vbpa_s,
t_adrc TYPE STANDARD TABLE OF ty_adrc,
t_adr6 TYPE STANDARD TABLE OF ty_adr6,
t_hrp1001 TYPE STANDARD TABLE OF ty_hrp1001,
t_but000 TYPE STANDARD TABLE OF ty_but000,
t_vbfa TYPE STANDARD TABLE OF ty_vbfa,
t_vbeln TYPE STANDARD TABLE OF ty_vbeln,
t_tvarv TYPE STANDARD TABLE OF tvarv,
t_final TYPE STANDARD TABLE OF x_final,
t_log TYPE STANDARD TABLE OF x_log,
t_veda_new TYPE STANDARD TABLE OF ty_veda,
t_kna1 TYPE STANDARD TABLE OF ty_kna1.
DATA: t_cdhdr TYPE TABLE OF cdhdr,
t_cdhdr1 TYPE TABLE OF cdhdr,
t_cdpos TYPE TABLE OF cdpos.
DATA: w_cdpos TYPE cdpos,
w_cdhdr TYPE cdhdr,
w_but000 TYPE ty_but000,
w_hrp1001 TYPE ty_hrp1001,
w_vbpa_s TYPE ty_vbpa_s.
DATA: r_beg_dat TYPE RANGE OF vbak-erdat,
r_canc_dat TYPE RANGE OF veda-vbedkue,
r_parvw TYPE RANGE OF vbpa-parvw,
r_auart TYPE RANGE OF vbak-auart,
rg_auart TYPE RANGE OF vbak-auart,
r_reinst TYPE RANGE OF vbak-erdat,
r_expired TYPE RANGE OF vbak-erdat,
r_contract TYPE RANGE OF vbak-erdat,
r_vkuegru TYPE RANGE OF veda-vkuegru,
r_mtart TYPE RANGE OF mara-mtart,
r_matnr TYPE RANGE OF mara-matnr.
DATA: w_beg_dat LIKE LINE OF r_beg_dat,
w_canc_dat LIKE LINE OF r_canc_dat,
w_parvw LIKE LINE OF r_parvw,
w_auart LIKE LINE OF r_auart,
wg_auart LIKE LINE OF rg_auart,
w_reinst LIKE LINE OF r_reinst,
w_expired LIKE LINE OF r_expired,
w_contract LIKE LINE OF r_contract,
w_vkuegru LIKE LINE OF r_vkuegru,
w_mtart LIKE LINE OF r_mtart.
*/..Selection screen declaration
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS: p_rname TYPE makt-maktx OBLIGATORY,
p_mid TYPE adr6-smtp_addr OBLIGATORY.
SELECT-OPTIONS: s_mat_i FOR mara-matnr,
s_mat_p FOR mara-matnr.
SELECTION-SCREEN END OF BLOCK b1.
* Frequency and Timing
SELECTION-SCREEN BEGIN OF BLOCK b3 WITH FRAME TITLE text-003.
PARAMETERS: p_daily RADIOBUTTON GROUP g1 DEFAULT 'X',
p_weekly RADIOBUTTON GROUP g1,
p_month RADIOBUTTON GROUP g1.
SELECTION-SCREEN END OF BLOCK b3.
*-Initialization-*
INITIALIZATION.
  PERFORM initialization.
*-Start-of-Selection-*
START-OF-SELECTION.
*/..Get the time period for which the report is run.
  PERFORM get_daterange.
*/..Get the Material types based on the selection.
  PERFORM sub_fill_material_types.
  PERFORM sub_consolidate_data.
*&---------------------------------------------------------------------*
*& Form INITIALIZATION
*&---------------------------------------------------------------------*
FORM initialization .
  wg_auart-sign = 'I'.
  wg_auart-option = 'EQ'.
  wg_auart-low = 'ZC01'.
  APPEND wg_auart TO rg_auart.
  CLEAR wg_auart.
  wg_auart-sign = 'I'.
  wg_auart-option = 'EQ'.
  wg_auart-low = 'ZC02'.
  APPEND wg_auart TO rg_auart.
  CLEAR wg_auart.
  wg_auart-sign = 'I'.
  wg_auart-option = 'EQ'.
  wg_auart-low = 'ZC03'.
  APPEND wg_auart TO rg_auart.
  CLEAR wg_auart.
  wg_auart-sign = 'I'.
  wg_auart-option = 'EQ'.
  wg_auart-low = 'ZR01'.
  APPEND wg_auart TO rg_auart.
  CLEAR wg_auart.
  wg_auart-sign = 'I'.
  wg_auart-option = 'EQ'.
  wg_auart-low = 'ZR02'.
  APPEND wg_auart TO rg_auart.
  CLEAR wg_auart.
ENDFORM. " INITIALIZATION
*&---------------------------------------------------------------------*
*& Form GET_DATERANGE
*&---------------------------------------------------------------------*
FORM get_daterange .
  DATA : lv_date TYPE sy-datum.
  CLEAR: lv_date,
  gv_datefrm,
  gv_dateto.
  IF p_daily EQ 'X'.
*/..Set current date
    gv_datefrm = sy-datum.
    gv_dateto = sy-datum.
  ELSEIF p_weekly EQ 'X'.
*/..get a date in previous week.
    CALL FUNCTION 'HR_99S_DATE_MINUS_TIME_UNIT'
      EXPORTING
        i_idate               = sy-datum
        i_time                = 7
        i_timeunit            = 'D'
      IMPORTING
        o_idate               = lv_date
      EXCEPTIONS
        invalid_period        = 1
        invalid_round_up_rule = 2
        internal_error        = 3
        OTHERS                = 4.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
*/..get the previous week's start and end date.
*/..by default monday would be the starting day and Sunday would be
* the ending day.
    CALL FUNCTION 'GET_WEEK_INFO_BASED_ON_DATE'
    EXPORTING
    date = lv_date
    IMPORTING
* WEEK =
    monday = gv_datefrm
    sunday = gv_dateto.
  ELSEIF p_month EQ 'X'.
*/..get a date in previous month.
    CALL FUNCTION 'HR_99S_DATE_MINUS_TIME_UNIT'
      EXPORTING
        i_idate               = sy-datum
        i_time                = 1
        i_timeunit            = 'M'
      IMPORTING
        o_idate               = lv_date
      EXCEPTIONS
        invalid_period        = 1
        invalid_round_up_rule = 2
        internal_error        = 3
        OTHERS                = 4.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
* /..Get the previous month's start and End Date.
    CALL FUNCTION 'OIL_MONTH_GET_FIRST_LAST'
      EXPORTING
        i_date      = lv_date
      IMPORTING
        e_first_day = gv_datefrm
        e_last_day  = gv_dateto
      EXCEPTIONS
        wrong_date  = 1
        OTHERS      = 2.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
  ENDIF.
ENDFORM. " GET_DATERANGE
*&---------------------------------------------------------------------*
*& Form GET_CONTRACT_LIST
*&---------------------------------------------------------------------*
FORM get_contract_list .
*/.. Get the Change history value for the given selection.
*/.. Change history might be Dialy, Weekly or Monthly.
*/..Based onthe checkbox selected pick the matching contract nos.
*/..for new orders.
  REFRESH r_beg_dat.
  w_beg_dat-sign = 'I'.
  w_beg_dat-option = 'BT'.
  w_beg_dat-low = gv_datefrm.
  w_beg_dat-high = gv_dateto.
  APPEND w_beg_dat TO r_beg_dat.
  CLEAR w_beg_dat.
*/..Get the contract header details.
  SELECT vbeln erdat auart augru vkbur kunnr
  FROM vbak
  INTO TABLE t_vbak
  WHERE erdat IN r_beg_dat
  AND auart IN r_auart.
  IF t_vbak[] IS NOT INITIAL.
*/..Get the Sales Document: Business Data details.
    SELECT vbeln posnr zzreinstate zzexpired zzlatesale zzrenewal
    FROM vbkd
    INTO TABLE t_vbkd
    FOR ALL ENTRIES IN t_vbak
    WHERE vbeln = t_vbak-vbeln.
*/.. Get the Contract data details
    SELECT vbeln vposn vbegdat venddat vkuegru vbedkue
    FROM veda
    INTO TABLE t_veda
    FOR ALL ENTRIES IN t_vbak
    WHERE vbeln = t_vbak-vbeln.
* AND vbedkue IN r_canc_dat
* AND vkuegru = gv_canc_reason.
*/..get material and its desc details from VBAP and MAKT table.
    PERFORM sub_get_item_details USING t_vbak.
*/..Get partner detials from VBPA table
* for the above obtained contracts.
*build a range holding only Ship-to,
* sold-to and Bill-to partner functions
    PERFORM sub_get_partner_details USING t_vbak.
*/.. Get the Address details for Sold to & Bill to partners
    PERFORM sub_get_partner_address_det USING t_vbpa.
*/.. Get the E-mail addresses for Sold to & Bill to addresses
    PERFORM sub_get_email_address USING t_vbpa.
*/.. Get Sales Rep Details for all the Contract documents
    PERFORM sub_get_sales_rep_details USING t_vbpa_s.
  ENDIF.
ENDFORM. " GET_CONTRACT_LIST
*&---------------------------------------------------------------------*
*& Form SUB_CONSOLIDATE_DATA_NEW
*&---------------------------------------------------------------------*
FORM sub_consolidate_data_new.
  LOOP AT t_vbak INTO w_vbak WHERE auart IN r_auart.
    w_final-vbeln = w_vbak-vbeln.
    w_final-auart = w_vbak-auart.
    w_final-erdat = w_vbak-erdat.
    w_final-augru = w_vbak-augru.
    w_final-vkbur = w_vbak-vkbur.
*/.. Sold to Party addresses
    CLEAR w_vbpa.
    READ TABLE t_vbpa INTO w_vbpa WITH KEY vbeln = w_vbak-vbeln parvw = 'AG'.
    IF sy-subrc = 0.
      w_final-kunnr = w_vbpa-kunnr.
      READ TABLE t_adrc INTO w_adrc WITH KEY addrnumber = w_vbpa-adrnr.
      IF sy-subrc = 0.
        CONCATENATE w_adrc-name1 w_adrc-name2 INTO w_final-name SEPARATED BY space.
        w_final-telf1 = w_adrc-tel_number.
        w_final-street = w_adrc-street.
        w_final-city1 = w_adrc-city1.
        w_final-region = w_adrc-region.
        w_final-post_code1 = w_adrc-post_code1.
        w_final-country = w_adrc-country.
      ENDIF.
      READ TABLE t_adr6 INTO w_adr6 WITH KEY addrnumber = w_vbpa-adrnr.
      IF sy-subrc = 0.
        w_final-smtp_addr = w_adr6-smtp_addr.
      ENDIF.
    ENDIF.
*/.. Bill to party address
    CLEAR w_vbpa.
    READ TABLE t_vbpa INTO w_vbpa WITH KEY vbeln = w_vbak-vbeln parvw = 'RE'.
    IF sy-subrc = 0.
      w_final-kunnr_b = w_vbpa-kunnr.
      CLEAR w_adrc.
      READ TABLE t_adrc INTO w_adrc WITH KEY addrnumber = w_vbpa-adrnr.
      IF sy-subrc = 0.
        CONCATENATE w_adrc-name1 w_adrc-name2 INTO w_final-name_b SEPARATED BY space.
        w_final-telf1_b = w_adrc-tel_number.
        w_final-street_b = w_adrc-street.
        w_final-city1_b = w_adrc-city1.
        w_final-region_b = w_adrc-region.
        w_final-post_code1_b = w_adrc-post_code1.
        w_final-country_b = w_adrc-country.
      ENDIF.
      CLEAR w_adr6.
      READ TABLE t_adr6 INTO w_adr6 WITH KEY addrnumber = w_vbpa-adrnr.
      IF sy-subrc = 0.
        w_final-smtp_addr_b = w_adr6-smtp_addr.
      ENDIF.
    ENDIF.
* Line Item Details
    LOOP AT t_vbap INTO w_vbap WHERE vbeln = w_vbak-vbeln.
      w_final-posnr = w_vbap-posnr.
      w_final-matnr = w_vbap-matnr.
      w_final-maktx = w_vbap-maktx.
      w_final-zmeng = w_vbap-zmeng.
      w_final-kzwi3 = w_vbap-kzwi3 + w_vbap-kzwi5.
      READ TABLE t_vbpa INTO w_vbpa WITH KEY vbeln = w_vbak-vbeln posnr = w_vbap-posnr parvw = 'Z3'.
      IF sy-subrc = 0.
        CLEAR w_hrp1001.
        READ TABLE t_hrp1001 INTO w_hrp1001 WITH KEY sobid = w_vbpa-kunnr. "#EC *
        IF sy-subrc = 0.
          w_final-sales_rep = w_hrp1001-sobid.
        ENDIF.
      ELSE.
        CLEAR w_vbpa.
        READ TABLE t_vbpa INTO w_vbpa WITH KEY vbeln = w_vbak-vbeln parvw = 'Z3'.
        IF sy-subrc = 0.
          CLEAR w_hrp1001.
          READ TABLE t_hrp1001 INTO w_hrp1001 WITH KEY sobid = w_vbpa-kunnr. "#EC *
          IF sy-subrc = 0.
            w_final-sales_rep = w_hrp1001-sobid.
          ENDIF.
        ENDIF.
      ENDIF.
      CLEAR w_veda.
      READ TABLE t_veda INTO w_veda WITH KEY vbeln = w_vbap-vbeln vposn = w_vbap-posnr.
      IF sy-subrc = 0.
        w_final-vbegdat = w_veda-vbegdat.
        w_final-venddat = w_veda-venddat.
      ELSE.
        READ TABLE t_veda INTO w_veda WITH KEY vbeln = w_vbap-vbeln." vposn = w_vbap-posnr.
        IF sy-subrc = 0.
          w_final-vbegdat = w_veda-vbegdat.
          w_final-venddat = w_veda-venddat.
        ENDIF.
      ENDIF.
      APPEND w_final TO t_final.
    ENDLOOP.
    CLEAR w_final.
    CLEAR w_vbap.
    CLEAR w_vbak.
  ENDLOOP.
  REFRESH: t_vbak,
  t_veda,
  t_vbkd,
  t_vbap,
  t_vbpa,
  t_adr6,
  t_adrc.
ENDFORM. " SUB_CONSOLIDATE_DATA_NEW
*&---------------------------------------------------------------------*
*& Form SUB_SEND_MAIL
*&---------------------------------------------------------------------*
FORM sub_send_mail.
* Data Declaration for Mail Sending Options
* Receiver
  DATA: l_recipent TYPE REF TO if_recipient_bcs,
* Sender
  l_sender TYPE REF TO cl_sapuser_bcs,
  l_attcdoctype TYPE soodk-objtp,
  l_atttitle TYPE sood-objdes,
  l_freq TYPE string,
  l_from TYPE char10,
  l_to TYPE char10.
* Execptions
  DATA : l_bcs_exception TYPE REF TO cx_bcs,               "#EC NEEDED)
  l_document TYPE REF TO cl_document_bcs,
  l_send_request TYPE REF TO cl_bcs.
  DATA: t_mail_text TYPE bcsy_text,
  wa_mail_text_row TYPE soli,
  l_subject2 TYPE so_obj_des,
  l_message TYPE string,
  l_message1 TYPE string.
  DATA: l_num_rows TYPE i,
  l_text_length TYPE so_obj_len,
  l_num_line TYPE i.
  DATA: l_line TYPE string,
  l_zmeng TYPE string,
  l_kzwi3 TYPE string.
  DATA: l_venddat TYPE char10,
  l_vbegdat TYPE char10,
  l_erdat TYPE char10.
  DATA: gt_binary_content TYPE solix_tab,
  gv_size TYPE so_obj_len.
  CONSTANTS: c_tab TYPE c VALUE cl_bcs_convert=>gc_tab,
  c_cr TYPE c VALUE cl_bcs_convert=>gc_crlf,
  c_ext TYPE soodk-objtp VALUE 'XLS',
  c_x TYPE c VALUE 'X'.
  TYPES : BEGIN OF ty_tvakt,
  auart TYPE auart,
  bezei TYPE bezei20,
  END OF ty_tvakt,
  BEGIN OF ty_tvaut,
  augru TYPE augru,
  bezei TYPE bezei40,
  END OF ty_tvaut.
  DATA : lt_tvakt TYPE STANDARD TABLE OF ty_tvakt,
  wa_tvakt TYPE ty_tvakt,
  lt_tvaut TYPE STANDARD TABLE OF ty_tvaut,
  wa_tvaut TYPE ty_tvaut,
  lt_ordesc TYPE STANDARD TABLE OF x_final,
  lv_auart TYPE auart,
  lv_augru TYPE augru,
  lv_auarttxt TYPE bezei40,
  lv_augrutxt TYPE bezei40,
  c_hyp(3) TYPE c VALUE ' - '.
  IF NOT t_final IS INITIAL.
    lt_ordesc = t_final.
    SORT lt_ordesc BY auart augru.
    DELETE ADJACENT DUPLICATES FROM lt_ordesc COMPARING auart augru.
    CLEAR : lt_tvakt,
    lt_tvaut,
    lv_auart,
    lv_augru.
    SELECT auart bezei INTO TABLE lt_tvakt
    FROM tvakt
    FOR ALL ENTRIES IN lt_ordesc
    WHERE auart EQ lt_ordesc-auart
    AND spras EQ sy-langu.
    SORT lt_tvakt BY auart.
    DELETE ADJACENT DUPLICATES FROM lt_tvakt COMPARING ALL FIELDS.
    SELECT augru bezei INTO TABLE lt_tvaut
    FROM tvaut
    FOR ALL ENTRIES IN lt_ordesc
    WHERE augru EQ lt_ordesc-augru
    AND spras EQ sy-langu.
    SORT lt_tvaut BY augru.
    DELETE ADJACENT DUPLICATES FROM lt_tvaut COMPARING ALL FIELDS.
  ENDIF.
* Subject - Header
  l_subject2 = p_rname.
  CONCATENATE gv_datefrm+4(2) '/' gv_datefrm+6(2) '/' gv_datefrm+0(4) INTO l_from.
  CONCATENATE gv_dateto+4(2) '/' gv_dateto+6(2) '/' gv_dateto+0(4) INTO l_to.
  CLEAR l_freq.
  IF p_daily = c_x.
    l_freq = 'Daily'.
  ELSEIF p_weekly = c_x.
    l_freq = 'Weekly'.
  ELSEIF p_month = c_x.
    l_freq = 'Monthly'.
  ENDIF.
  DESCRIBE TABLE t_final LINES l_num_line.
  TRY.
      wa_mail_text_row = 'Data Selection Details:'.
      APPEND wa_mail_text_row TO t_mail_text. CLEAR wa_mail_text_row.
      APPEND wa_mail_text_row TO t_mail_text. CLEAR wa_mail_text_row.
      CONCATENATE 'Contract Type' ':' gv_order INTO wa_mail_text_row SEPARATED BY space.
      APPEND wa_mail_text_row TO t_mail_text.
      CLEAR wa_mail_text_row.
      CONCATENATE 'Frequency' ':' l_freq INTO wa_mail_text_row SEPARATED BY space.
      APPEND wa_mail_text_row TO t_mail_text.
      CLEAR wa_mail_text_row.
      CONCATENATE 'Date' ':' l_from 'to' l_to INTO wa_mail_text_row SEPARATED BY space.
      APPEND wa_mail_text_row TO t_mail_text. CLEAR wa_mail_text_row.
      CLEAR l_message.
      l_message = l_num_line.
      CONCATENATE 'No. of Records' ':' l_message INTO wa_mail_text_row SEPARATED BY space.
      APPEND wa_mail_text_row TO t_mail_text. CLEAR wa_mail_text_row.
      APPEND wa_mail_text_row TO t_mail_text.
      APPEND wa_mail_text_row TO t_mail_text.
      IF t_final[] IS INITIAL.
        wa_mail_text_row = 'No document exists for this selection.'.
        APPEND wa_mail_text_row TO t_mail_text.
        CLEAR wa_mail_text_row.
      ENDIF.
* Define rows and file size
      DESCRIBE TABLE t_mail_text LINES l_num_rows.
      l_num_rows = l_num_rows * 255.
      MOVE l_num_rows TO l_text_length.
      TRY.
          CALL METHOD cl_document_bcs=>create_document
            EXPORTING
              i_type    = 'RAW'
              i_subject = l_subject2
              i_length  = l_text_length
              i_text    = t_mail_text
            RECEIVING
              result    = l_document.
        CATCH cx_document_bcs .                         "#EC NO_HANDLER
      ENDTRY.
* IF t_final[] IS NOT INITIAL.
* Create Attachment
      CONCATENATE c_tab
      text-011 c_tab
      text-012 c_tab
      text-013 c_tab
      text-014 c_tab
      text-015 c_tab
      text-016 c_tab
      text-017 c_tab
      text-018 c_tab
      text-019 c_tab
      text-020 c_tab
      text-021 c_tab
      text-022 c_tab
      text-023 c_tab
      text-024 c_tab
      text-025 c_tab
      text-026 c_tab
      text-027 c_tab
      text-028 c_tab
      text-029 c_tab
      text-030 c_tab
      text-031 c_tab
      text-032 c_tab
      text-033 c_tab
      text-034 c_tab
      text-035 c_tab
      text-036 c_tab
      text-037 c_tab
      text-038 c_tab
      text-039 c_cr INTO l_line.
      CLEAR w_final.
      LOOP AT t_final INTO w_final.
        l_zmeng = w_final-zmeng.
        l_kzwi3 = w_final-kzwi3.
        CLEAR: l_vbegdat,
        l_venddat,
        l_erdat.
        CONCATENATE w_final-vbegdat+4(2) '/'
        w_final-vbegdat+6(2) '/'
        w_final-vbegdat+0(4)
        INTO l_vbegdat.
        CONCATENATE w_final-venddat+4(2) '/'
        w_final-venddat+6(2) '/'
        w_final-venddat+0(4)
        INTO l_venddat.
        CONCATENATE w_final-erdat+4(2) '/'
        w_final-erdat+6(2) '/'
        w_final-erdat+0(4)
        INTO l_erdat.
        IF w_final-auart NE lv_auart.
          READ TABLE lt_tvakt INTO wa_tvakt
          WITH KEY auart = w_final-auart.
          IF sy-subrc EQ 0.
            lv_auarttxt = wa_tvakt-bezei.
            CONCATENATE w_final-auart lv_auarttxt INTO lv_auarttxt SEPARATED BY c_hyp.
          ELSE.
            lv_auarttxt = w_final-auart.
          ENDIF.
          lv_auart = w_final-auart.
        ENDIF.
        IF w_final-augru NE lv_augru.
          READ TABLE lt_tvaut INTO wa_tvaut
          WITH KEY augru = w_final-augru.
          IF sy-subrc EQ 0.
            lv_augrutxt = wa_tvaut-bezei.
            CONCATENATE w_final-augru lv_augrutxt INTO lv_augrutxt SEPARATED BY c_hyp.
          ELSE.
            lv_augrutxt = w_final-augru.
          ENDIF.
          lv_augru = w_final-augru.
        ENDIF.
        CONCATENATE l_line
        lv_auarttxt
        l_erdat
        lv_augrutxt
        w_final-vbeln
        w_final-posnr
        w_final-kunnr
        w_final-name
        w_final-telf1
        w_final-smtp_addr
        w_final-street
        w_final-city1
        w_final-country
        w_final-post_code1
        w_final-region
        w_final-kunnr_b
        w_final-name_b
        w_final-street_b
        w_final-city1_b
        w_final-region_b
        w_final-post_code1_b
        w_final-telf1_b
        w_final-matnr
        w_final-maktx
        l_zmeng
        l_vbegdat
        l_venddat
        l_kzwi3
        w_final-sales_rep
        w_final-vkbur
        INTO l_line SEPARATED BY c_tab.
        CONCATENATE l_line c_cr INTO l_line.
        CLEAR w_final.
      ENDLOOP.
      TRY.
          cl_bcs_convert=>string_to_solix(
          EXPORTING
          iv_string = l_line
          iv_codepage = '4103' "suitable for MS Excel, leave empty
          iv_add_bom = 'X' "for other doc types
          IMPORTING
          et_solix = gt_binary_content
          ev_size = gv_size ).
        CATCH cx_bcs.
          MESSAGE e445(so).
      ENDTRY.
* ENDIF.
* Define File Name
      l_attcdoctype = c_ext.
      l_atttitle = p_rname.
* Create Document
      CALL METHOD l_document->add_attachment(
        i_attachment_type = l_attcdoctype
        i_attachment_subject = l_atttitle
        i_attachment_size = gv_size
        i_att_content_hex = gt_binary_content ).
      l_send_request = cl_bcs=>create_persistent( ).
      l_send_request->set_document( l_document ).
* Define Sender
      l_sender = cl_sapuser_bcs=>create( sy-uname ).
      TRY.
          CALL METHOD l_send_request->set_sender
            EXPORTING
              i_sender = l_sender.
        CATCH cx_send_req_bcs .                         "#EC NO_HANDLER
      ENDTRY.
* Define Recipient
      l_recipent = cl_cam_address_bcs=>create_internet_address( p_mid ).
      l_send_request->add_recipient( EXPORTING i_recipient = l_recipent ).
* Schedule
      l_send_request->set_send_immediately( 'X' ).
      l_send_request->send( ).
      COMMIT WORK AND WAIT.
* Catch Execptions
    CATCH cx_bcs INTO l_bcs_exception.                  "#EC NO_HANDLER
  ENDTRY.
  IF sy-subrc = 0.
    CONCATENATE gv_order '-' l_message INTO l_message1 SEPARATED BY space.
    w_log-message = l_message1.
    APPEND w_log TO t_log.
    CLEAR w_log.
  ENDIF.
  REFRESH t_final.
  CLEAR w_final.
ENDFORM. " SUB_SEND_MAIL
*&---------------------------------------------------------------------*
*& Form SUB_CONSOLIDATE_DATA
*&---------------------------------------------------------------------*
FORM sub_consolidate_data.
*/.. Consolidate and send the New Orders
  CLEAR gv_order.
  gv_order = 'New Contracts'.
*/..Get the list of document types to fetch the contracts.
  PERFORM get_document_types_new.
*/..Based on the selected check boxes, pick the required details.
  PERFORM get_contract_list.
*/.. Consolidate New orders
  PERFORM sub_consolidate_data_new.
*/.. Send New orders
  PERFORM sub_send_mail.
* Display final Log
  PERFORM sub_display_log.
ENDFORM. " SUB_CONSOLIDATE_DATA
*&---------------------------------------------------------------------*
*& Form SUB_GET_ITEM_DETAILS
*&---------------------------------------------------------------------*
FORM sub_get_item_details USING t_vbak LIKE t_vbak.
  REFRESH t_vbap.
*/..get material and its desc details from VBAP and MAKT table.
  IF NOT t_vbak[] IS INITIAL.
    SELECT a~vbeln a~posnr a~matnr a~zmeng a~kzwi3 a~kzwi5
    b~maktx c~mtart
    FROM vbap AS a INNER JOIN
    makt AS b ON a~matnr = b~matnr
    INNER JOIN mara AS c ON c~matnr = b~matnr
    INTO TABLE t_vbap
    FOR ALL ENTRIES IN t_vbak
    WHERE a~vbeln = t_vbak-vbeln
    AND c~matnr IN r_matnr
    AND c~mtart IN r_mtart.
  ENDIF.
ENDFORM. " SUB_GET_ITEM_DETAILS
*&---------------------------------------------------------------------*
*& Form SUB_GET_PARTNER_DETAILS
*&---------------------------------------------------------------------*
FORM sub_get_partner_details USING t_vbak LIKE t_vbak.
  REFRESH: r_parvw,
  t_vbpa,
  t_vbpa_s.
  w_parvw-sign = 'I'.
  w_parvw-option = 'EQ'.
  w_parvw-low = 'AG'.
  APPEND w_parvw TO r_parvw.
  CLEAR w_parvw.
  w_parvw-sign = 'I'.
  w_parvw-option = 'EQ'.
  w_parvw-low = 'RE'.
  APPEND w_parvw TO r_parvw.
  CLEAR w_parvw.
  w_parvw-sign = 'I'.
  w_parvw-option = 'EQ'.
  w_parvw-low = 'SH'.
  APPEND w_parvw TO r_parvw.
  CLEAR w_parvw.
  w_parvw-sign = 'I'.
  w_parvw-option = 'EQ'.
  w_parvw-low = 'Z3'.
  APPEND w_parvw TO r_parvw.
  CLEAR w_parvw.
  SELECT vbeln posnr parvw kunnr pernr adrnr
  FROM vbpa INTO TABLE t_vbpa
  FOR ALL ENTRIES IN t_vbak
  WHERE vbeln = t_vbak-vbeln
  AND parvw IN r_parvw.
  LOOP AT t_vbpa INTO w_vbpa WHERE parvw = 'Z3'.
    w_vbpa_s-sobid = w_vbpa-kunnr.
    w_vbpa_s-kunnr = w_vbpa-kunnr.
    APPEND w_vbpa_s TO t_vbpa_s.
    CLEAR w_vbpa_s.
  ENDLOOP.
ENDFORM. " SUB_GET_PARTNER_DETAILS
*&---------------------------------------------------------------------*
*& Form SUB_GET_PARTNER_ADDRESS_DET
*&---------------------------------------------------------------------*
FORM sub_get_partner_address_det USING t_vbpa LIKE t_vbpa.
  REFRESH t_adrc.
  IF t_vbpa[] IS NOT INITIAL.
    SELECT addrnumber name1 name2 street city1 post_code1 region country tel_number
    FROM adrc
    INTO TABLE t_adrc
    FOR ALL ENTRIES IN t_vbpa
    WHERE addrnumber = t_vbpa-adrnr.
  ENDIF.
ENDFORM. " SUB_GET_PARTNER_ADDRESS_DET
*&---------------------------------------------------------------------*
*& Form SUB_GET_EMAIL_ADDRESS
*&---------------------------------------------------------------------*
FORM sub_get_email_address USING t_vbpa LIKE t_vbpa.
  REFRESH t_adr6.
  IF t_vbpa[] IS NOT INITIAL.
    SELECT addrnumber smtp_addr
    FROM adr6
    INTO TABLE t_adr6
    FOR ALL ENTRIES IN t_vbpa
    WHERE addrnumber = t_vbpa-adrnr.
  ENDIF.
ENDFORM. " SUB_GET_EMAIL_ADDRESS
*&---------------------------------------------------------------------*
*& Form SUB_GET_SALES_REP_DETAILS
*&---------------------------------------------------------------------*
FORM sub_get_sales_rep_details USING t_vbpa_s LIKE t_vbpa_s.
  REFRESH: t_but000,
  t_hrp1001.
  SELECT otype objid plvar relat begda endda sclas sobid
  FROM hrp1001
  INTO TABLE t_hrp1001
  FOR ALL ENTRIES IN t_vbpa_s
  WHERE sobid = t_vbpa_s-sobid
  AND otype = 'S'
  AND plvar = '01'
  AND relat = '008'
  AND sclas = 'BP'
  AND begda < sy-datum
  AND endda >= sy-datum.
  SELECT partner bpkind bu_group name_last name_first
  FROM but000 INTO TABLE t_but000
  FOR ALL ENTRIES IN t_hrp1001
  WHERE partner = t_hrp1001-sobid+0(10)
  AND bpkind = '9002'.
ENDFORM. " SUB_GET_SALES_REP_DETAILS
*&---------------------------------------------------------------------*
*& Form SUB_FILL_MATERIAL_TYPES
*&---------------------------------------------------------------------*
FORM sub_fill_material_types .
  REFRESH r_mtart.
  REFRESH r_matnr.
  IF s_mat_i IS NOT INITIAL.
    APPEND LINES OF s_mat_i TO r_matnr.
  ENDIF.
  IF s_mat_p IS NOT INITIAL.
    APPEND LINES OF s_mat_p TO r_matnr.
  ENDIF.
ENDFORM. " SUB_FILL_MATERIAL_TYPES
*&---------------------------------------------------------------------*
*& Form GET_DOCUMENT_TYPES_NEW
*&---------------------------------------------------------------------*
FORM get_document_types_new .
  REFRESH r_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC01'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC02'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC03'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
ENDFORM. " GET_DOCUMENT_TYPES_NEW
*&---------------------------------------------------------------------*
*& Form GET_DOCUMENT_TYPES_RENEW
*&---------------------------------------------------------------------*
FORM get_document_types_renew .
  REFRESH r_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZR01'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZR02'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
ENDFORM. " GET_DOCUMENT_TYPES_RENEW
*&---------------------------------------------------------------------*
*& Form SUB_DISPLAY_LOG
*&---------------------------------------------------------------------*
FORM sub_display_log .
  DATA: l_mesg TYPE string.
  IF t_log IS NOT INITIAL.
    CONCATENATE 'Email sent to' p_mid 'successfully' INTO l_mesg SEPARATED BY space.
  ELSE.
    CONCATENATE 'Email failed to sent -' p_mid INTO l_mesg SEPARATED BY space.
  ENDIF.
  WRITE / l_mesg.
  LOOP AT t_log INTO w_log.
    WRITE: / w_log-message.
    CLEAR w_log.
  ENDLOOP.
ENDFORM. " SUB_DISPLAY_LOG
*&---------------------------------------------------------------------*
*& Form SUB_VALIDATE_PARTNER_DATA
*&---------------------------------------------------------------------*
FORM sub_validate_partner_data .
  REFRESH t_cdhdr1[].
  SORT t_cdhdr BY objectid.
  t_cdhdr1[] = t_cdhdr[].
  LOOP AT t_cdhdr1 INTO w_cdhdr WHERE change_ind = 'I'.
    READ TABLE t_cdhdr1 TRANSPORTING NO FIELDS WITH KEY objectid = w_cdhdr-objectid
    udate = w_cdhdr-udate
    change_ind = 'U'.
    IF sy-subrc = 0.
      DELETE t_cdhdr WHERE objectid = w_cdhdr-objectid.
    ENDIF.
    CLEAR w_cdhdr.
  ENDLOOP.
ENDFORM. " SUB_VALIDATE_PARTNER_DATA
*&---------------------------------------------------------------------*
*& Form SUB_GET_DOCUMENT_TYPE_ADD
*&---------------------------------------------------------------------*
FORM sub_get_document_type_add .
  REFRESH r_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC01'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC02'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC03'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC04'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC05'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZC06'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZR01'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
  w_auart-sign = 'I'.
  w_auart-option = 'EQ'.
  w_auart-low = 'ZR02'.
  APPEND w_auart TO r_auart.
  CLEAR w_auart.
ENDFORM. " SUB_GET_DOCUMENT_TYPE_ADD
 
REPORT zabap_send_mail.
PARAMETERS: psubject(40) TYPE c DEFAULT 'Hello',
            p_email(40) TYPE c DEFAULT 'write email address' .
DATA: it_packing_list LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
      it_contents LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      it_receivers LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
      it_attachment LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      gd_cnt TYPE i,
      gd_sent_all(1) TYPE c,
      gd_doc_data LIKE sodocchgi1,
      gd_error TYPE sy-subrc.
DATA: it_message TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                  WITH HEADER LINE.
************************************************************************
START-OF-SELECTION.
  PERFORM populate_message_table.
*Send email message, although is not sent from SAP until mail send
*program has been executed(rsconn01)
  PERFORM send_email_message.
*Instructs mail send program for SAPCONNECT to send email(rsconn01)
  PERFORM initiate_mail_execute_program.
*&---------------------------------------------------------------------
*& Form POPULATE_MESSAGE_TABLE
*&---------------------------------------------------------------------
*Adds text to email text table
*----------------------------------------------------------------------
FORM populate_message_table.
  APPEND 'Email line 1' TO it_message.
  APPEND 'Email line 2' TO it_message.
  APPEND 'Email line 3' TO it_message.
  APPEND 'Email line 4' TO it_message.
ENDFORM. " POPULATE_MESSAGE_TABLE
*&---------------------------------------------------------------------
*& Form SEND_EMAIL_MESSAGE
*&---------------------------------------------------------------------
*Send email message
*----------------------------------------------------------------------
FORM send_email_message.
*Fill the document data.
  gd_doc_data-doc_size = 1.

*Populate the subject/generic message attributes
  gd_doc_data-obj_langu = sy-langu.
  gd_doc_data-obj_name = 'SAPRPT'.
  gd_doc_data-obj_descr = psubject.
  gd_doc_data-sensitivty = 'F'.

*Describe the body of the message
  CLEAR it_packing_list.
  REFRESH it_packing_list.
  it_packing_list-transf_bin = space.
  it_packing_list-head_start = 1.
  it_packing_list-head_num = 0.
  it_packing_list-body_start = 1.
  DESCRIBE TABLE it_message LINES it_packing_list-body_num.
  it_packing_list-doc_type = 'RAW'.
  APPEND it_packing_list.

*Add the recipients email address
  CLEAR it_receivers.
  REFRESH it_receivers.
  it_receivers-receiver = p_email.
  it_receivers-rec_type = 'U'.
  it_receivers-com_type = 'INT'.
  it_receivers-notif_del = 'X'.
  it_receivers-notif_ndel = 'X'.
  APPEND it_receivers.

*Call the FM to post the message to SAPMAIL
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = gd_doc_data
      put_in_outbox              = 'X'
    IMPORTING
      sent_to_all                = gd_sent_all
    TABLES
      packing_list               = it_packing_list
      contents_txt               = it_message
      receivers                  = it_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.

*Store function module return code
  gd_error = sy-subrc.

*Get it_receivers return code
  LOOP AT it_receivers.
  ENDLOOP.
ENDFORM. " SEND_EMAIL_MESSAGE
*&---------------------------------------------------------------------
*& Form INITIATE_MAIL_EXECUTE_PROGRAM
*&---------------------------------------------------------------------
*Instructs mail send program for SAPCONNECT to send email.
*----------------------------------------------------------------------
FORM initiate_mail_execute_program.
  WAIT UP TO 2 SECONDS.
  IF gd_error EQ 0.
    SUBMIT rsconn01 WITH mode = 'INT'
    WITH output = 'X'
    AND RETURN.
  ENDIF.
ENDFORM. " INITIATE_MAIL_EXECUTE_PROGRAM
 

SAP mail is a very robust method of interacting with users within SAP system, it is always good to receive email in Microsoft inbox. This also works like an additional notification to users in case they do not check SAP mail regularly.

Sending an email to the Microsoft Inbox is a way of interacting with a non SAP system through ABAP code and hence is very interesting. A fair knowledge of UNIX shell scripting is assumed here.

The ABAP code to send an email to Microsoft inbox revolves around following UNIX script

Echo "From:" "<"$1">" > <unix file path name>

Echo "To:" "<"$2">" >> <unix file path name>

Echo "Subject:" "<"$3">" >> <unix file path name>

Cat $4 >> <unix file path name>

Uuencode $5 $6 >> <unix file path name>

Cat <unix file path name> | /usr/sbin/sendmail -f $fraddr $toaddr

(Note : the commands in the above script can be case sensitive. Check the actual case on the unix installation in question)

Let us understand the various parts of the above script.

$1 = Sender email address

$2 = Recipient email address

$3 = Subject of the email

$4 = Path of unix server file having email body

Form email body as an internal table in ABAP program, download it to a unix server file

$5 = Path of unix server file to be sent as email attachment

$6 = Name to be given to the attachment (like test1.doc, test1.xls). The corresponding Microsoft icon will be shown in the email for the type of file attached ( Word document, excel document etc)

The script builds a temporary file and pipes the file to the sendmail command to achieve the mission.

This script can be invoked from SAP to send the mail to the intended recipient. Store this small script on the unix server. (Assume script name is sndmail )

To do this we should define a link in the SAP system between a customized command and this unix script.

The FM to define a customized command in SAP system has the following pattern.

CALL FUNCTION 'SXPG_CALL_SYSTEM'
  EXPORTING
    commandname                = 
    parameters                 = ' '
  IMPORTING
    status                     = 
  TABLES
    exec_protocol              = 
  EXCEPTIONS
    no_permission              = 1
    command_not_found          = 2
    parameters_too_long        = 3
    security_risk              = 4
    wrong_check_call_interface = 5
    program_start_error        = 6
    program_termination_error  = 7
    x_error                    = 8
    parameter_expected         = 9
    too_many_parameters        = 10
    illegal_command            = 11
    OTHERS                     = 12.
 

The parameters of Function Module are explained below:

Import Parameters Name and Description

Field name

Field function

Commandname
Name of unix shell script or command to be executed by SAP

 

Name of unix shell script to be invoked

Parameters

 

The parameters to be sent to unix shell script ($1, $2 etc). Send parameters as a concatenated string separated by space and length not exceeding 128 characters
For eg in UNIX environment the above shell script would be executed as
Sndmail sender@a.com receiver@b.com Trial /home/test.doc testmail.
We will be simulating this command using the FM from SAP system

Table Parameters Name and Description

Field Name

Field function

Exec_protocol (structure)
Table to get messages from unix server after shell script is executed

Length

Length of the message from external program i.e unix

 

Message

Log message from external program i.e unix

Export Parameters Name and Description

Field Name

Field function

Status
Contains the status of execution of external program

 

Scheduling status of external program i.e unix

 

Once the above FM is invoked with the necessary parameters the unix program sendmail will send a mail to the inbox of the recipient in Microsoft.

The restriction on the parameter string length of 128 characters can be removed to make way for very long email addresses and subjects. Build the parameters into an internal table and download it as a file on the unix server. Instead of passing each parameter individually, pass the unix server path of this file as the parameter to the unix shell script (sndmail mentioned above). Modify the shell script to read every line of this parameter file as variables to be used in the shell script.

REPORT ztsapmail.
DATA: x_object_type LIKE sood-objtp.
DATA: BEGIN OF x_object_hd_change.
        INCLUDE STRUCTURE sood1.
DATA: END OF x_object_hd_change.
DATA: BEGIN OF x_objcont OCCURS 10.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objcont.
DATA: BEGIN OF x_objhead OCCURS 0.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objhead.
DATA: BEGIN OF raw_head.
        INCLUDE STRUCTURE sorh.
DATA: END OF raw_head.
DATA: BEGIN OF x_receivers OCCURS 0.
        INCLUDE STRUCTURE soos1.
DATA: END OF x_receivers.
PARAMETERS: receiver LIKE x_receivers-recnam. " Name
*BUILD MESSAGE HEADER
MOVE 'Sort field goes here' TO x_object_hd_change-objsrt. " Sort field
MOVE 'Name of the object goes here' TO x_object_hd_change-objnam. " Name
MOVE 'Document title goes here' TO x_object_hd_change-objdes. " Title
MOVE 'F' TO x_object_hd_change-objsns. " Functional OBJECT
MOVE 'E' TO x_object_hd_change-objla. " Language
* Object type of the new document
MOVE 'RAW' TO x_object_type.
CLEAR x_objcont.
MOVE 'Contents of mail' TO x_objcont-line.
APPEND x_objcont.
CLEAR x_objcont-line. APPEND x_objcont.
MOVE 'More contents' TO x_objcont-line.
APPEND x_objcont.
MOVE 'Still more contents'
TO x_objcont-line.
APPEND x_objcont.
MOVE ' ' TO x_objcont-line.
APPEND x_objcont.
* Specific header (Dependent on the object type, here RAW)
REFRESH x_objhead.
DESCRIBE TABLE x_objcont LINES raw_head-rawsiz.
MOVE raw_head TO x_objhead.
APPEND x_objhead.
*RECEIVERS table
CLEAR x_receivers.
REFRESH x_receivers.
MOVE receiver TO x_receivers-recnam. " Name
MOVE 'B' TO x_receivers-recesc. " Receiver type
MOVE 'X' TO x_receivers-sndcp. " Send as a copy
MOVE 'X' TO x_receivers-sndex. " EXPRESS DOCUMENT
APPEND x_receivers.
CALL FUNCTION 'SO_OBJECT_SEND'
  EXPORTING
    object_hd_change = x_object_hd_change
    object_type      = x_object_type
    outbox_flag      = 'X'
    owner            = sy-uname
  TABLES
    objcont          = x_objcont
    objhead          = x_objhead
    receivers        = x_receivers.
*
DATA: to_address LIKE sy_lisel,
      from_address LIKE sy-lisel,
      subject LIKE sy-lisel,
      attachment_name LIKE sy_lisel,
      data_file_path LIKE sxpgcolist-parameters,
      body_file_path LIKE sxpgcolist-parameters.
DATA : BEGIN OF int_email_attach OCCURS 0,
txtline(255),
END OF int_email_attach.
DATA : BEGIN OF int_email_body OCCURS 0,
txtline(255),
END OF int_email_body.
CLEAR : int_exec_protocol,int_email_attach,int_email_body.
REFRESH : int_exec_protocol,int_email_attach,int_email_body.
*
int_email_attach-txtline = 'Put all attachment text in this table'.
APPEND int_email_attach. CLEAR int_email_attach.
int_email_body-txtline = 'Put all attachment text in this table'.
APPEND int_email_body. CLEAR int_email_body.
*
CONCATENATE to_address
from_address
subject
body_file_path
data_file_path
attachment_name
INTO v_parameters.
*
IF NOT int_email_attach[] IS INITIAL.
  OPEN DATASET data_file_path FOR OUTPUT IN TEXT MODE.
  LOOP AT int_email_attach.
    TRANSFER int_email_attach-txtline TO data_file_path.
  ENDLOOP.
  CLOSE DATASET data_file_path.
ENDIF.
*
IF NOT int_email_body[] IS INITIAL.
  OPEN DATASET body_file_path FOR OUTPUT IN TEXT MODE.
  LOOP AT int_email_body.
    TRANSFER int_email_body-txtline TO body_file_path.
  ENDLOOP.
  CLOSE DATASET body_file_path.
ENDIF.
*
CALL FUNCTION 'SXPG_CALL_SYSTEM'
  EXPORTING
    commandname                = 'Z_EMAIL' " - Command calling unix script
    PARAMETERS                 = v_parameters
  TABLES
    exec_protocol              = int_exec_protocol
  EXCEPTIONS
    no_permission              = 1
    command_not_found          = 2
    parameters_too_long        = 3
    security_risk              = 4
    wrong_check_call_interface = 5
    program_start_error        = 6
    program_termination_error  = 7
    x_error                    = 8
    parameter_expected         = 9
    too_many_parameters        = 10
    illegal_command            = 11
    OTHERS                     = 12.
 

With the Help of this code u are able to send a mail to the Non SAP system.

 

Author: Gunda Ravi Kumar
Submitted: 22/05/2007

Sending a mail with file attachment  

Description:
I have seen many people asking queries regarding sending mail, and also while attaching the file to a mail. There are standard Function Modules provided by SAP to achieve this task, even then there might be problems while populating the file to be attached or while populating the Function Module parameters. The following code clearly explains the process of sending mail with file attachment.  

**Data Declarations
**Internal Table
DATA : BEGIN OF it_spfli OCCURS 0,
          carrid LIKE spfli-carrid,
          connid LIKE spfli-connid,
       END OF it_spfli.
DATA:   it_packing_list LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
        it_contents     LIKE solisti1 OCCURS 0 WITH HEADER LINE,
** storing receivers       
        it_receivers    LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
**storing file attachment data
        it_attachment   LIKE solisti1 OCCURS 0 WITH HEADER LINE,                    gd_doc_data     LIKE sodocchgi1,
        gd_error        TYPE sy-subrc,
        l_gntxt         LIKE t357g_t-gntxt,
        lv_message(100) TYPE c.
DATA:   it_message TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                WITH HEADER LINE. "storing mail body
DATA : psubject(30) TYPE c VALUE 'Sample Mail'. "subject of the mail
DATA : ld_format TYPE so_obj_tp , "file format
       ld_attfilename TYPE so_obj_des, "file name
       w_cnt TYPE i.
**Selecting the data
SELECT carrid connid INTO TABLE it_spfli FROM spfli WHERE carrid EQ 'AA'.
**Perform for populating mail body
PERFORM populate_message.
**Perform for populating file attachment
PERFORM populate_attachment.
**Perform for populating mail characteristic info
PERFORM populate_pack.
**Perform for populating receivers
PERFORM populate_receivers.
**Perform to send mail
PERFORM send_mail.
*&---------------------------------------------------------------------*
*&      Form  populate_message
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM populate_message .
**Populating the body
  lv_message = 'Sample mail for testing purpose.'.
  APPEND lv_message TO it_message.
ENDFORM.                    " populate_message
*&---------------------------------------------------------------------*
*&      Form  populate_attachment
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM populate_attachment .
**Populating the attachment file with the data from final intenal table
  CONCATENATE 'CARRIER ID'
              'CONNECTION ID'
              INTO it_attachment SEPARATED BY
              cl_abap_char_utilities=>horizontal_tab.
  CONCATENATE cl_abap_char_utilities=>cr_lf it_attachment INTO
  it_attachment.
  APPEND it_attachment.
  LOOP AT it_spfli.
    CONCATENATE it_spfli-carrid it_spfli-connid INTO it_attachment SEPARATED BY
             cl_abap_char_utilities=>horizontal_tab.
    CONCATENATE cl_abap_char_utilities=>cr_lf it_attachment INTO
    it_attachment.
    APPEND it_attachment.
  ENDLOOP.
ENDFORM.                    " populate_attachment
*&---------------------------------------------------------------------*
*&      Form  populate_receivers
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM populate_receivers .
**Populating Mail Recepients
**If there are more than one mail recepient then loop and append them to it_receivers
  it_receivers-receiver = Mail-id of the receiver. (eg : 'abc@xyz.com')
  it_receivers-rec_type = 'U'.
  it_receivers-com_type = 'INT'.
  it_receivers-notif_del = 'X'.
  it_receivers-notif_ndel = 'X'.
  it_receivers-express = 'X'.
  APPEND it_receivers.
ENDFORM.                    " populate_receivers
*&---------------------------------------------------------------------*
*&      Form  populate_pack
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM populate_pack .
**File Type
  ld_format = 'XLS'.
**File Name
  ld_attfilename = 'File1'.
* Fill the document data.
  gd_doc_data-doc_size = 1.
* Populate the subject/generic message attributes
  gd_doc_data-obj_langu = sy-langu.
  gd_doc_data-obj_name = 'SAPRPT'.
  gd_doc_data-obj_descr = psubject .
  gd_doc_data-sensitivty = 'F'.
* Fill the document data and get size of attachment
  CLEAR gd_doc_data.
* Populate the subject/generic message attributes
  gd_doc_data-obj_langu = sy-langu.
  READ TABLE it_attachment INDEX w_cnt.
  gd_doc_data-doc_size = ( w_cnt - 1 ) * 255 + STRLEN( it_attachment ).
  gd_doc_data-obj_name  = 'SAPRPT'.
  gd_doc_data-obj_descr = psubject.
  gd_doc_data-sensitivty = 'F'.
* Describe the body of the message
  CLEAR it_packing_list.
  REFRESH it_packing_list.
  it_packing_list-transf_bin = space.
  it_packing_list-head_start = 1.
  it_packing_list-head_num = 0.
  it_packing_list-body_start = 1.
  DESCRIBE TABLE it_message LINES it_packing_list-body_num.
  it_packing_list-doc_type = 'RAW'.
  APPEND it_packing_list.
**Describe the attachment info
  it_packing_list-transf_bin = 'X'.
  it_packing_list-head_start = 1.
  it_packing_list-head_num = 1.
  it_packing_list-body_start = 1.
  DESCRIBE TABLE it_attachment LINES  it_packing_list-body_num.
  it_packing_list-doc_type = ld_format.
  it_packing_list-obj_name = ld_attfilename.
  it_packing_list-obj_descr = ld_attfilename.
  it_packing_list-doc_size = it_packing_list-body_num * 255.
  APPEND it_packing_list.
ENDFORM.                    " populate_pack
*&---------------------------------------------------------------------*
*&      Form  send_mail
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM send_mail .
**Function Module to send mail
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = gd_doc_data
      put_in_outbox              = 'X'
      commit_work                = 'X'
    TABLES
      packing_list               = it_packing_list
      contents_bin               = it_attachment
      contents_txt               = it_message
      receivers                  = it_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
ENDFORM.                    " send_mail

Back to Sending Mails - Home Page

Author:  Pratik Mallick
Submitted: 3rd April 2009

Introduction

Send notification is becoming important from business point of view. It adds extra reliability to the process and enables business person to react quickly to customer's requirement. If any error occurred to a process some group of people in the top management will get a notification and react based on the details specified in the notification.

Business Requirements

In some situation we had to send a notification to a group people. Some cases we had to only send the text in the mail body and some cases we had to send the detail records as attachments. Suppose one user ran a program to update the material master and the top management wants to get the success records as one attachment and error records as another attachment in the email.   

Methodology

Using the below object oriented technique it can easily obtained. 

Create object

The standard class CL_BCS is used to send the notification along with attachment to a group of people. Method CREATE_PERSISTENT is used to create an send request object of the standard class CL_BCS.

Create body of the email

Method CREATE_DOCUMENT of standard class CL_DOCUMENT_BCS is used to create the text of the email body.

Create attachments of the email

Method ADD_ATTACHMENT of standard class CL_DOCUMENT_BCS is used to create attachment of the email. If we want to create the multiple attachment we have call this method multiple times.
Method SET_DOCUMENT of the standard class CL_BCS is used to add the document (email body and attachments) to be send request object.

Create sender

Method CREATE of the standard class CL_SAPUSER_BCS is used to create the sender address.
Method SET_SENDER of standard class CL_BCS is used add the sender address to the send request object.

Create recipient

Method CREATE_INTERNET_ADDRESS of standard class CL_CAM_ADDRESS_BCS is used to create recipient email address.

Method ADD_RECIPIENT of standard class CL_BCS is used to add the recipient email address to the send request object.

Send email

Method SEND of standard class CL_BCS is used to send the send request object to a group of people added in the recipient list.
Sending is done in a queued way; immediate sending can be triggered for very urgent alerts.

Code

data: l_send_request type ref to cl_bcs,         " Send request
      l_body      type bcsy_text,                " Mail body
      l_success   type bcsy_text,                " Atchmnt for success
      l_error     type bcsy_text,                " Atchmnt for error
      wa_text     type soli,                     " Work area for attach
      l_document  type ref to cl_document_bcs,   " Mail body
      l_sender    type ref to if_sender_bcs,     " Sender address
      l_recipient type ref to if_recipient_bcs,  " Recipient
      l_size      type sood-objlen,              " Size of Attachment
      l_lines     type i,                        " Lines count
      l_email     type ad_smtpadr,               " Email ID
      l_extension type soodk-objtp value 'RAW'.  " TXT format
* Prepare mail bidy
append 'Send multiple file as attachment of a Email.'  to l_body.
append space to l_body.
* Preparing contents of attachment with Change Log
* Header line
wa_text-line+0   = 'First column'.
wa_text-line+20  = 'Second column'.
wa_text-line+40  = 'Third column'.
wa_text-line+60  = 'Fourth column'.
wa_text-line+80  = 'Fifth column'.
wa_text-line+100 = 'Sixth column'.
wa_text-line+120 = 'Seventh column'.
wa_text-line+140 = 'Eighth column'.
append wa_text to l_success.
append wa_text to l_error.
clear : wa_text.
* Populate the data part
wa_text-line+0   = '111111111'.
wa_text-line+20  = '222222222'.
wa_text-line+40  = '333333333'.
wa_text-line+60  = '333333333'.
wa_text-line+80  = '444444444'.
wa_text-line+100 = '555555555'.
wa_text-line+120 = '666666666'.
wa_text-line+140 = '777777777'.
append wa_text to l_success.
clear : wa_text.
wa_text-line+0   = 'aaaaaaaaa'.
wa_text-line+20  = 'bbbbbbbbb'.
wa_text-line+40  = 'ccccccccc'.
wa_text-line+60  = 'ddddddddd'.
wa_text-line+80  = 'eeeeeeeee'.
wa_text-line+100 = 'fffffffff'.
wa_text-line+120 = 'ggggggggg'.
wa_text-line+140 = 'hhhhhhhhh'.
append wa_text to l_error.
clear : wa_text.
* Creates persistent send request
l_send_request = cl_bcs=>create_persistent( ).
* Craete document for mail body
l_document = cl_document_bcs=>create_document(
             i_type    = 'RAW'
             i_text    = l_body  " Mail body
             i_subject = 'Mail send as attachment' ).
* Attachment for success records
l_lines = lines( l_success ).
l_size = l_lines * 255.
* Add attchment
call method l_document->add_attachment
  exporting
    i_attachment_type    = l_extension
    i_attachment_subject = 'Success'
    i_attachment_size    = l_size
    i_att_content_text   = l_success. " Attachment for success record
* Attachment for error records
l_lines = lines( l_error ).
l_size = l_lines * 255.
* Add attchment
call method l_document->add_attachment
  exporting
    i_attachment_type    = l_extension
    i_attachment_subject = 'Error'
    i_attachment_size    = l_size
    i_att_content_text   = l_error. " Attachment for error record
* Add the document to send request
call method l_send_request->set_document( l_document ).
* Sender addess
l_sender = cl_sapuser_bcs=>create( sy-uname ).
call method l_send_request->set_sender
  exporting
    i_sender = l_sender.
* Recipient address
l_email = 'myname@in.ibm.com'.
l_recipient = cl_cam_address_bcs=>create_internet_address( l_email ).
* Add recipient address to send request
call method l_send_request->add_recipient
  exporting
    i_recipient  = l_recipient
    i_express    = 'X'
    i_copy       = ' '
    i_blind_copy = ' '
    i_no_forward = ' '.
l_email = 'myname@gmail.com'.
l_recipient = cl_cam_address_bcs=>create_internet_address( l_email ).
* Add recipient address to send request
call method l_send_request->add_recipient
  exporting
    i_recipient  = l_recipient
    i_express    = 'X'
    i_copy       = ' '
    i_blind_copy = ' '
    i_no_forward = ' '.
* E-Mail is placed into queue for sending. In case of very important alerts
* use the following parameter to initiate an 'immediate sending'; but notice that
* this will trigger a dedicated send process for every single message - which is
* very costly for system performance
* l_send_request->set_send_immediately( 'X' ). "uncomment for immediate sending
* Send mail
call method l_send_request->send( ).
commit work. */

                                                                 
Mail via SAP ABAP Coding.........                                                                     
                      *******************Send mail in SAP ABAP**************************

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
* Data Declarations
DATA: LT_MAILSUBJECT     TYPE SODOCCHGI1.
DATA: LT_MAILRECIPIENTS  TYPE STANDARD TABLE OF SOMLREC90 WITH HEADER LINE.
DATA: LT_MAILTXT         TYPE STANDARD TABLE OF SOLI      WITH HEADER LINE.
* Recipients
LT_MAILRECIPIENTS-REC_TYPE  = 'U'.
LT_MAILRECIPIENTS-RECEIVER = 'sheetal@gmail.com'.
APPEND LT_MAILRECIPIENTS .
CLEAR LT_MAILRECIPIENTS .
* Subject.
LT_MAILSUBJECT-OBJ_NAME = 'TEST'.
LT_MAILSUBJECT-OBJ_LANGU = SY-LANGU.
LT_MAILSUBJECT-OBJ_DESCR = 'Mail Subject'.
* Mail Contents
LT_MAILTXT = 'This is a test mail'.
APPEND LT_MAILTXT. CLEAR LT_MAILTXT.
* Send Mail
CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
  EXPORTING
    DOCUMENT_DATA              = LT_MAILSUBJECT
  TABLES
    OBJECT_CONTENT             = LT_MAILTXT
    RECEIVERS                  = LT_MAILRECIPIENTS
  EXCEPTIONS
    TOO_MANY_RECEIVERS         = 1
    DOCUMENT_NOT_SENT          = 2
    DOCUMENT_TYPE_NOT_EXIST    = 3
    OPERATION_NO_AUTHORIZATION = 4
    PARAMETER_ERROR            = 5
    X_ERROR                    = 6
    ENQUEUE_ERROR              = 7
    OTHERS                     = 8.
IF SY-SUBRC EQ 0.
  COMMIT WORK.
*   Push mail out from SAP outbox
  SUBMIT RSCONN01 WITH MODE = 'INT' AND RETURN.
ENDIF.

 

****************End ************************************************
(thumbs up)  Sheetal Gulati

sap.miniarora@gmail.com

Author: Vinod Reddy Vemuru
Submitted: 25/01/2009
This sample code can be used to send Email with HTML attachment.

REPORT z756942.
PARAMETERS: po_email TYPE ad_smtpadr LOWER CASE.
DATA: li_objcont TYPE STANDARD TABLE OF solisti1,
      li_reclist TYPE STANDARD TABLE OF somlreci1,
      li_objpack TYPE STANDARD TABLE OF sopcklsti1,
      li_objhead TYPE STANDARD TABLE OF solisti1,
      li_content TYPE STANDARD TABLE OF solisti1,
      lwa_objcont TYPE solisti1,
      lwa_reclist TYPE somlreci1,
      lwa_objpack TYPE sopcklsti1,
      lwa_objhead TYPE solisti1,
      lwa_content TYPE solisti1,
      lwa_doc TYPE sodocchgi1,
      l_lines TYPE i.
REFRESH: li_objcont[], li_reclist[],
          li_objpack[], li_objhead[],
          li_content[].
CLEAR: lwa_objcont, lwa_reclist,
        lwa_objpack, lwa_objhead,
        lwa_content, lwa_doc.
MOVE '<body>' TO lwa_objcont.
APPEND lwa_objcont TO li_objcont.
MOVE '<p>' TO lwa_objcont.
APPEND lwa_objcont TO li_objcont.
MOVE 'This is a sample HTML content from test program' TO lwa_objcont.
APPEND lwa_objcont TO li_objcont.
MOVE '</p>' TO lwa_objcont.
APPEND lwa_objcont TO li_objcont.
MOVE '</body>' TO lwa_objcont.
APPEND lwa_objcont TO li_objcont.

lwa_reclist-receiver = po_email.
lwa_reclist-rec_type = 'U'.
APPEND lwa_reclist TO li_reclist.
lwa_objhead = 'test.htm'.
APPEND lwa_objhead TO li_objhead.
lwa_content = 'Please find attached document for more details'.
APPEND lwa_content TO li_content.
CLEAR l_lines.
DESCRIBE TABLE li_content LINES l_lines.
READ TABLE li_content INTO lwa_content INDEX l_lines.
lwa_doc-doc_size = ( l_lines - 1 ) * 255 + STRLEN( lwa_content ).
lwa_doc-obj_langu = 'E'.
lwa_doc-obj_name = 'Test HTML file'.
lwa_doc-obj_descr = 'Test HTML file'.
CLEAR lwa_objpack-transf_bin.
lwa_objpack-head_start = 1.
lwa_objpack-head_num = 0.
lwa_objpack-body_start = 1.
lwa_objpack-body_num = l_lines.
lwa_objpack-doc_type = 'RAW'.
APPEND lwa_objpack TO li_objpack.
CLEAR: lwa_objpack, l_lines.
DESCRIBE TABLE li_objcont LINES l_lines.
READ TABLE li_objcont INTO lwa_objcont INDEX l_lines.
lwa_objpack-doc_size = ( l_lines - 1 ) * 255 + STRLEN( lwa_objcont ).
lwa_objpack-transf_bin = 'X'.
lwa_objpack-head_start = 1.
lwa_objpack-head_num = 0.
lwa_objpack-body_start = 1.
lwa_objpack-body_num = l_lines.
lwa_objpack-doc_type = 'HTM' .
lwa_objpack-obj_name = 'Test HTML file'.
lwa_objpack-obj_descr = 'Test HTML file'.
APPEND lwa_objpack TO li_objpack.
*Sending the mail
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
  EXPORTING
    document_data              = lwa_doc
    put_in_outbox              = 'X'
  TABLES
    packing_list               = li_objpack
    object_header              = li_objhead
    contents_bin               = li_objcont
    contents_txt               = li_content
    receivers                  = li_reclist
  EXCEPTIONS
    too_many_receivers         = 1
    document_not_sent          = 2
    operation_no_authorization = 4
    OTHERS                     = 99.
IF sy-subrc NE 0.
  WRITE:/ 'Document sending failed'.
ELSE.
  WRITE:/ 'Document successfully sent'.
  COMMIT WORK.
ENDIF.
 

In some scenario where we have to send error records or some impotent documents to a group of people as attachments via Email.

REPORT  ztest_subha_mail.

DATA: l_send_request TYPE REF TO cl_bcs,         " Send request
      l_body      TYPE bcsy_text,                " Mail body
      l_attach    TYPE bcsy_text,                " Attachment
      wa_text     TYPE soli,                     " Work area for attach
      l_document  TYPE REF TO cl_document_bcs,   " Mail body
      l_sender    TYPE REF TO if_sender_bcs,     " Sender address
      l_recipient TYPE REF TO if_recipient_bcs,  " Recipient
      l_size      TYPE sood-objlen,              " Size of Attachment
      c_tab       TYPE abap_char1  VALUE
                       cl_abap_char_utilities=>horizontal_tab,
      l_lines     TYPE i,                        " Lines count
      l_email     TYPE ad_smtpadr,               " Email ID
      l_extension TYPE soodk-objtp VALUE 'RAW'.  " TXT format

* Prepare mail bidy
APPEND 'Test Mail by Subhankar' TO l_body.

* Preparing contents of attachment with Change Log
* Header line
wa_text-line+0   = 'First column'.
wa_text-line+20  = 'Second column'.
wa_text-line+40  = 'Third column'.
wa_text-line+60  = 'Fourth column'.
wa_text-line+80  = 'Fifth column'.
wa_text-line+100 = 'Sixth column'.
wa_text-line+120 = 'Seventh column'.
wa_text-line+140 = 'Eighth column'.

APPEND wa_text TO l_attach.
CLEAR : wa_text.
* Populate the data part
wa_text-line+0   = '111111111'.
wa_text-line+20  = '222222222'.
wa_text-line+40  = '333333333'.
wa_text-line+60  = '333333333'.
wa_text-line+80  = '444444444'.
wa_text-line+100 = '555555555'.
wa_text-line+120 = '666666666'.
wa_text-line+140 = '777777777'.
APPEND wa_text TO l_attach.
CLEAR : wa_text.

wa_text-line+0   = 'aaaaaaaaa'.
wa_text-line+20  = 'bbbbbbbbb'.
wa_text-line+40  = 'ccccccccc'.
wa_text-line+60  = 'ddddddddd'.
wa_text-line+80  = 'eeeeeeeee'.
wa_text-line+100 = 'fffffffff'.
wa_text-line+120 = 'ggggggggg'.
wa_text-line+140 = 'hhhhhhhhh'.
APPEND wa_text TO l_attach.
CLEAR : wa_text.
l_lines = LINES( l_attach ).
l_size = l_lines * 255.

* Creates persistent send request
l_send_request = cl_bcs=>create_persistent( ).

* Craete document for mail body
l_document = cl_document_bcs=>create_document(
             i_type    = 'RAW'
             i_text    = l_body
             i_subject = 'Mail send as attachment' ).

* Add attchment
CALL METHOD l_document->add_attachment
  EXPORTING
    i_attachment_type    = l_extension
    i_attachment_subject = 'My attachment'
    i_attachment_size    = l_size
    i_att_content_text   = l_attach.

* Add the document to send request
CALL METHOD l_send_request->set_document( l_document ).

* Sender addess
l_sender = cl_sapuser_bcs=>create( sy-uname ).
CALL METHOD l_send_request->set_sender
  EXPORTING
    i_sender = l_sender.

* Recipient address
l_email = 'sugarani@in.ibm.com'.
l_recipient = cl_cam_address_bcs=>create_internet_address( l_email ).

* Add recipient address to send request
CALL METHOD l_send_request->add_recipient
  EXPORTING
    i_recipient  = l_recipient
    i_express    = 'X'
    i_copy       = ' '
    i_blind_copy = ' '
    i_no_forward = ' '.

* Trigger E-Mail immediately
l_send_request->set_send_immediately( 'X' ).

* Send mail
CALL METHOD l_send_request->send( ).

COMMIT WORK.
 

Author: Suresh Maryala
Submitted: 03/24/2008

Purpose of this document is to capture sending multiple attachments of Spool using SAP E-mail. Spool is converted to HTML format before sent as e-mail. There is no limit on how many attachments can be sent.

This is an example of a code sample:

TABLES: sos04,
        rspotype,
        soli.

PARAMETERS: p_des         LIKE sood1-objdes.
SELECT-OPTIONS: s_spool   FOR rspotype-rqnumber NO INTERVALS,
                s_emails  FOR sos04-l_adr_name NO INTERVALS,
                s_text    FOR soli-line NO INTERVALS.

************************************************************************
* DATA DEFINITION
************************************************************************
*TYPES
TYPES: BEGIN OF ty_tbtcp.
        INCLUDE STRUCTURE tsp01.
TYPES: END OF ty_tbtcp.
TYPES: BEGIN OF ty_objpack,
        rqnumber   TYPE rspotype-rqnumber,
        head_start TYPE sopcklsti1-head_start,
        head_num   TYPE sopcklsti1-head_num,
        body_start TYPE sopcklsti1-body_start,
        body_num   TYPE sopcklsti1-body_num,
        no_lines   TYPE i,
       END OF ty_objpack.
*INTERNAL TABLES
DATA: lt_tbtcp       TYPE STANDARD TABLE OF ty_tbtcp,
      lt_objpack     TYPE STANDARD TABLE OF ty_objpack,
      lt_mess_bod    LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      lt_mess_att    LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      lt_mess_2      LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      lt_spool_list  TYPE STANDARD TABLE OF bapixmspoo WITH HEADER LINE,
      lt_spool_2     TYPE STANDARD TABLE OF bapixmspoo WITH HEADER LINE,
      l_spool_id     LIKE tsp01-rqident.
DATA: ls_tbtcp       TYPE ty_tbtcp,
      ls_objpack     TYPE ty_objpack.
DATA  so_ali LIKE soli OCCURS 0 WITH HEADER LINE.
DATA: it_lines LIKE tline OCCURS 0 WITH HEADER LINE.
DATA: p_template LIKE wwwdataid-objid.
DATA listtab LIKE abaplist OCCURS 1.
DATA p_html LIKE bapihtml OCCURS 10 WITH HEADER LINE.
DATA lt_html LIKE bapihtml OCCURS 10 WITH HEADER LINE.
*STRUCTURES
*VARIABLES
*VARIABLES
DATA: l_spool_nr             LIKE tsp01-rqident,
      l_bytecount            LIKE tst01-dsize,
      l_buffer               TYPE string,
      l_spool_cnt            TYPE i,
      l_cnt                  TYPE i,
      l_line_no              TYPE i,
      l_total_cnt            TYPE i,
      p_cnt(3)               TYPE c,
      p_spool_nr(10)         TYPE c.
DATA: l_subject              LIKE sodocchgi1-obj_descr,
      l_sender_type          LIKE soextreci1-adr_typ,
      l_recsize              TYPE i,
      l_receiver             TYPE sy-subrc.
DATA: ld_sender_address      LIKE soextreci1-receiver,
      ld_sender_address_type LIKE soextreci1-adr_typ,
      ld_error               TYPE sy-subrc.
DATA: t_packing_list         LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
      t_receivers            LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
      t_attachment           LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      w_sent_all(1)          TYPE c,
      w_doc_data             LIKE sodocchgi1.
DATA: tab_lines              LIKE sy-tabix.
************************************************************************
* INITIALIZATION
************************************************************************
INITIALIZATION.
************************************************************************
* START-OF-SELECTION
************************************************************************
START-OF-SELECTION.
* Read Spool Number
  PERFORM f_obtain_spool_id.
* HTML Logic
  PERFORM f_convert_spool_to_htm.
* E-mail need to be sent as HTML
  PERFORM f_process_email.
* End process
  IF sy-subrc <> 0.
    WRITE:/ 'Error Sending Document',
          / 'Return Code:', sy-subrc.
  ELSE.
    WRITE:/ 'Document successfully sent'.
  ENDIF.
************************************************************************
*END-OF-SELECTON
************************************************************************
END-OF-SELECTION.
*&---------------------------------------------------------------------*
*&      Form  f_obtain_spool_id
*&---------------------------------------------------------------------*
FORM f_obtain_spool_id .
* Capture all Spool Numbers into a internal table
  REFRESH lt_tbtcp.
  CLEAR   ls_tbtcp.
  SELECT *
  INTO TABLE lt_tbtcp
  FROM tsp01
  WHERE rqident IN s_spool.
* Sort by Spool Number
  SORT lt_tbtcp BY rqident.
* Capture the number of spool numbers entered
  CLEAR l_total_cnt.
  DESCRIBE TABLE lt_tbtcp LINES l_total_cnt.
ENDFORM.                    " f_obtain_spool_id
*&---------------------------------------------------------------------*
*&      Form  f_process_email
*&---------------------------------------------------------------------*
FORM f_process_email .
* HTML E-mail
  DESCRIBE TABLE lt_html LINES l_recsize.
  CHECK l_recsize > 0.
  PERFORM f_send_email.
ENDFORM.                    " f_process_email
*&---------------------------------------------------------------------*
*&      Form  f_send_email
*&---------------------------------------------------------------------*
FORM f_send_email .
  CHECK NOT ( s_emails-low IS INITIAL ).
  REFRESH lt_mess_bod.
* Default subject matter
  l_subject         = p_des.
  IF NOT s_text-low IS INITIAL.
    LOOP AT s_text.
      MOVE s_text-low TO lt_mess_bod.
      APPEND lt_mess_bod.
      CLEAR  lt_mess_bod.
    ENDLOOP.
  ENDIF.
* HTML Attachment logic
  PERFORM f_send_email_html_attachment.
ENDFORM.                    " f_send_email
*&---------------------------------------------------------------------*
*&      Form  f_convert_spool_to_htm
*&---------------------------------------------------------------------*
FORM f_convert_spool_to_htm .
  LOOP AT lt_tbtcp INTO ls_tbtcp.
    CLEAR p_html.
    REFRESH p_html.
    ADD 1 TO l_cnt.
    l_spool_id = ls_tbtcp-rqident.
    SUBMIT rspolst2 EXPORTING LIST TO MEMORY AND RETURN
    WITH rqident = l_spool_id.
    CALL FUNCTION 'LIST_FROM_MEMORY'
      TABLES
        listobject = listtab
      EXCEPTIONS
        not_found  = 1
        OTHERS     = 2.
    IF sy-subrc <> 0.
*      message e418 raising read_error.
    ENDIF.
    IF p_template IS INITIAL.
      p_template = 'WEBREPORTING_REPORT'.
    ENDIF.
    CALL FUNCTION 'WWW_HTML_FROM_LISTOBJECT'
      EXPORTING
        template_name = p_template
      TABLES
        html          = p_html
        listobject    = listtab
      EXCEPTIONS
        OTHERS        = 1.
    LOOP AT p_html.
      MOVE-CORRESPONDING p_html TO lt_html.
      APPEND lt_html.
    ENDLOOP.
* Building table lt_objpack internal table for creating attachments
    MOVE l_spool_id TO ls_objpack-rqnumber.
    IF l_cnt = 1.
      MOVE 1 TO ls_objpack-head_start.
      MOVE 0 TO ls_objpack-head_num.
      MOVE 1 TO ls_objpack-body_start.
      DESCRIBE TABLE lt_html LINES ls_objpack-no_lines.
      MOVE ls_objpack-no_lines TO ls_objpack-body_num.
      APPEND ls_objpack TO lt_objpack.
    ENDIF.
    IF l_cnt > 1.
      ls_objpack-head_start = ls_objpack-no_lines + 1.
      ls_objpack-head_num = ls_objpack-no_lines + 1.
      ls_objpack-body_start = ls_objpack-no_lines + 1.
      DESCRIBE TABLE p_html LINES ls_objpack-no_lines.
      MOVE ls_objpack-no_lines TO ls_objpack-body_num.
      APPEND ls_objpack TO lt_objpack.
* Overwrite total number of lines
      DESCRIBE TABLE lt_html LINES ls_objpack-no_lines.
    ENDIF.
  ENDLOOP.
ENDFORM.                    " f_convert_spool_to_htm
*&---------------------------------------------------------------------*
*&      Form  f_send_email_html_attachment
*&---------------------------------------------------------------------*
FORM f_send_email_html_attachment .
* Fill the document data.
  w_doc_data-doc_size = 1.
* Fill the document data and get size of attachment
  CLEAR w_doc_data.
  w_doc_data-obj_langu = sy-langu.
  w_doc_data-obj_name  = 'SAPRPT'.
  w_doc_data-obj_descr = p_des .
  w_doc_data-sensitivty = 'F'.
  CLEAR t_attachment.
  REFRESH t_attachment.
  t_attachment[] = lt_html[].
* Describe the body of the message
  CLEAR t_packing_list.
  REFRESH t_packing_list.
  DESCRIBE TABLE lt_mess_bod LINES tab_lines.
  READ TABLE lt_mess_bod INDEX tab_lines.
  w_doc_data-doc_size = ( tab_lines - 1 ) * 255 + strlen( lt_mess_bod ).
  CLEAR t_packing_list-transf_bin.
  t_packing_list-head_start = 1.
  t_packing_list-head_num = 0.
  t_packing_list-body_start = 1.
  t_packing_list-body_num = tab_lines.
  t_packing_list-doc_type = 'RAW'.
  APPEND t_packing_list.
* Create attachment notification
  CLEAR: l_line_no.
  LOOP AT lt_objpack INTO ls_objpack.
    ADD 1 TO l_line_no.
    t_packing_list-transf_bin = 'X'.
    t_packing_list-head_start = ls_objpack-head_start.
    t_packing_list-head_num = ls_objpack-head_num.
    t_packing_list-body_start = ls_objpack-body_start.
    t_packing_list-doc_type = 'HTM'.
    p_cnt = l_line_no.
    CONDENSE p_cnt.
    p_spool_nr = ls_objpack-rqnumber.
    CONCATENATE 'Attachment' p_cnt INTO t_packing_list-obj_name SEPARATED BY space.
* Format Attachment Name.
    PERFORM get_attachment_name USING    p_spool_nr
                                CHANGING t_packing_list-obj_descr.
    t_packing_list-body_num = ls_objpack-body_num.
    t_packing_list-doc_size = t_packing_list-body_num * 255.
    APPEND t_packing_list.
  ENDLOOP.
* Add the recipients email address
  CLEAR t_receivers.
  REFRESH t_receivers.
  LOOP AT s_emails.
    t_receivers-receiver = s_emails-low.
    t_receivers-rec_type = 'U'.
    t_receivers-com_type = 'INT'.
    t_receivers-notif_del = 'X'.
    t_receivers-notif_ndel = 'X'.
* E-mail Delivery is selected
    IF NOT p_del IS INITIAL.
      t_receivers-notif_del = 'X'.
    ELSE.
      CLEAR t_receivers-notif_del.
    ENDIF.
* E-mail Read receipt is checked
    IF NOT p_read IS INITIAL.
      t_receivers-notif_read = 'X'.
    ELSE.
      CLEAR t_receivers-notif_read.
    ENDIF.
    APPEND t_receivers.
  ENDLOOP.
  ld_sender_address = sy-uname.
  ld_sender_address_type = 'B'.
  CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
    EXPORTING
      document_data              = w_doc_data
      put_in_outbox              = 'X'
      sender_address             = ld_sender_address
      sender_address_type        = ld_sender_address_type
      commit_work                = 'X'
    IMPORTING
      sent_to_all                = w_sent_all
    TABLES
      packing_list               = t_packing_list
      contents_bin               = t_attachment
      contents_txt               = lt_mess_att
      receivers                  = t_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
* Populate error return code
  ld_error = sy-subrc.
* Populate zreceiver return code
  LOOP AT t_receivers.
    l_receiver = t_receivers-retrn_code.
  ENDLOOP.
ENDFORM.                    " f_send_email_html_attachment
*&---------------------------------------------------------------------*
*&      Form  GET_ATTACHMENT_NAME
*&---------------------------------------------------------------------*
FORM get_attachment_name  USING    p_spool_nr
                          CHANGING t_packing_list_obj_descr.
  CLEAR ls_tbtcp.
  READ TABLE lt_tbtcp INTO ls_tbtcp
             WITH KEY rqident = p_spool_nr
             BINARY SEARCH.
  IF sy-subrc EQ 0.
    IF ls_tbtcp-rqtitle IS INITIAL.
      ls_tbtcp-rqtitle = ls_tbtcp-rq2name.
    ENDIF.
    CONCATENATE p_spool_nr '-' ls_tbtcp-rqtitle INTO t_packing_list_obj_descr SEPARATED BY space.
  ELSE.
    CONCATENATE p_spool_nr '- Spool'  INTO t_packing_list_obj_descr SEPARATED BY space.
  ENDIF.
  CONDENSE t_packing_list_obj_descr.
ENDFORM.                    " GET_ATTACHMENT_NAME
 

Description: In the Business Process Modeling Group I have seen alot of request regarding how to send mail notifications by using ABAP Code.
I have used the below mentioned code in several cases like
Info Letter to all Vendors, Sending PO Via Email, Reminder mails to the Agents in Workflow and also escalation mails to Process Owners when the task is not performed by the agents in the given time.

Prerequisite : SAP Enterprise Edition and above
SAP Connect needs to be configured
Mail Rely should be available

DATA reciever TYPE TABLE OF adr6-smtp_addr.
DATA subject TYPE so_obj_des.
DATA text TYPE bcsy_text.
DATA line TYPE soli-line.
DATA send_request TYPE REF TO cl_bcs.
DATA document TYPE REF TO cl_document_bcs.
DATA recipient TYPE REF TO if_recipient_bcs.
DATA bcs_exception TYPE REF TO cx_bcs.
DATA sent_to_all TYPE os_boolean.
DATA adresse TYPE adr6-smtp_addr.
DATA mailflag(1) VALUE space.

DATA dat(10).
DATA time(10).
DATA tfree(12).

WRITE sy-datum TO dat.
WRITE sy-uzeit TO time.

subject = 'This is my Subject '.
line = ' I am the body of the message '.

APPEND line TO text.

*mail send mail out to external mail server .

TRY.

*    create the send request
    send_request = cl_bcs=>create_persistent( ).

    document = cl_document_bcs=>create_document(
    i_type = 'RAW'
    i_text = text
    i_subject = betreff ).

*    add document to send request
    send_request->set_document( document ).

*    create recipient and add to send request

    adresse = 'reciever@xyz.com'.

    recipient = cl_cam_address_bcs=>create_internet_address(
    adresse ).
    send_request->add_recipient( i_recipient = recipient ).

*    send mail now
    sent_to_all = send_request->send( i_with_error_screen = 'X' ).

    IF sent_to_all = 'X'.
      MESSAGE s022(so).
    ENDIF.

  CATCH cx_bcs INTO bcs_exception.
    MESSAGE e865(so) WITH bcs_exception->error_type.
ENDTRY.

*Close Transaction.
COMMIT WORK.
 

Many a time our customers ask us if we can send an outlook meeting notice from ABAP. Until now, We did not realize that it was possible, But now we do.

Here is the code snippet of what we had done to achieve this.

The first step was look at a Microsoft outlook meeting invitation as a flat file. For that, we created a meeting notice and downloaded it as a *VCS file. For this please create a dummy invite, invite attendees and save is as a .VCS file. ( File->Save as). Your flat file should look like this.

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN
VERSION:1.0
BEGIN:VEVENT
DTSTART:20070804T183000Z
DTEND:20070804T190000Z
LOCATION;ENCODING=QUOTED-PRINTABLE:Dennys
UID:040000008200E00074C5B7101A82E0080000000070011ADA9FD6C7010000000000000000100
 00000F29C2A2ACE5F284382D1B7CC8BA82B8B
DESCRIPTION;ENCODING=QUOTED-PRINTABLE:=09  =0D=0A
SUMMARY;ENCODING=QUOTED-PRINTABLE:Test Meeting for Code Gallery
PRIORITY:3
END:VEVENT
END:VCALENDAR
 

Now , We all know that the function module  SO_NEW_DOCUMENT_ATT_SEND_API1 can be used send an e-mail with a file as an attachment.  There are tons of messages already on this topic and hence to avoid redundancy, I am skipping that part. for eg please refer

http://www.sapdevelopment.co.uk/reporting/rep_spooltopdf.htm

I am only showing the lines that are used to fill and create the calendar file. Please note this is a sample code and hence hardcoded. Please use text elements for constants and work areas to append to internal tables without directly appending them.

* These are the parameters for the attachment file name and the contents of the attachment itself.
DATA: t_objhead LIKE solisti1 OCCURS 0 WITH HEADER LINE.
DATA: t_objbin LIKE solisti1 OCCURS 20 WITH HEADER LINE.
CONSTANTS:  c_cr(2) VALUE '0D'.
t_objhead = 'testappointment.vcs'.
APPEND t_objhead.
*hence the file will be sent as a vcs file. now for the details.
CONCATENATE 'BEGIN:VCALENDAR' c_cr INTO t_objbin.
APPEND t_objbin.
 

Please add all the other lines in the file in a similar manner.

You can also try to send an e-mail from SBWP to an external address with a VCS attachment and the results would be similar. Please note that the number UID:040000008200E00074C5B7101A82E0080000000070011ADA9FD6C7010000000000000000100
 00000F29C2A2ACE5F284382D1B7CC8BA82B8B might vary for diffewrent versions. Also, they can save it into their calendar and you might get a receipt acknowlegement if you are in the same smtp server as them in case you set the flag in SO_NEW_DOCUMENT_ATT_SEND_API1. Please try using this snippet and let me know any problems you  face or any questions that you may have. Happy reading.

Any comments to improve this snippet are more than welcome.

Thanks

Ganesh.S

"The following code is used to send automatic email.
"define tables
DATA: gt_receivers        TYPE soos1_tab,
      gt_obj_cont         TYPE soli_tab,
      gs_object_hd_change TYPE sood1.
"define structures and work areas
DATA: gs_receivers        TYPE soos1,      gs_obj_cont         TYPE soli,
      gs_object_hd_change TYPE sood1.
"fill two lines of email body
gs_obj_cont-line = 'first line of email body'.
APPEND gs_obj_cont TO  gt_obj_cont.
gs_obj_cont-line = 'second line of email body'.
APPEND gs_obj_cont TO  gt_obj_cont."set receiver
gs_receivers-recextnam  = 'name.last@email.com'.
gs_receivers-recesc     = 'E'.
gs_receivers-sndart     = 'INT'.
gs_receivers-sndpri     = 1.
gs_receivers-mailstatus = 'E'.
gs_receivers-rcdat      = sy-datum.
gs_receivers-rctim      = sy-uzeit .
gs_receivers-deliver    = 'X'.
gs_receivers-mailstatus = 'X'.
gs_receivers-not_deli   = 'X'.
APPEND gs_receivers TO gt_receivers.

gs_object_hd_change-objla  = sy-langu.
gs_object_hd_change-objnam = 'Immediate mail'.

CALL FUNCTION 'SO_OBJECT_SEND'
     EXPORTING
       object_hd_change           = gs_object_hd_change
       object_type                = 'RAW'
       outbox_flag                = 'X'
     TABLES
       objcont                    = gt_obj_cont
       receivers                  = gt_receivers
     EXCEPTIONS
       active_user_not_exist      = 1
       communication_failure      = 2
       component_not_available    = 3
       folder_not_exist           = 4
       folder_no_authorization    = 5
       forwarder_not_exist        = 6
       note_not_exist             = 7
       object_not_exist           = 8
       object_not_sent            = 9
       object_no_authorization    = 10
       object_type_not_exist      = 11
       operation_no_authorization = 12
       owner_not_exist            = 13
       parameter_error            = 14
       substitute_not_active      = 15
       substitute_not_defined     = 16
       system_failure             = 17
       too_much_receivers         = 18
       user_not_exist             = 19
       originator_not_exist       = 20
       x_error                    = 21
       others                     = 22.

 COMMIT WORK.

The following is the sample program for Creating OLE Application and in turn which sends the an email by storing a copy in your presentation server.
You can customize according to your requirement. 

 

*&---------------------------------------------------------------------*
*& Report  YG_ABR20640
*&
*&---------------------------------------------------------------------*
* Program Name        : YGH_ABR20640                                   *
* Program Description : Detail Activity Report                         *
* Developer           : Raghavendra.D.S (LZ1162)                    *
* Business Analyst    : Vivek Pandey
* Transaction code    : YG_ABR20640                                    *
*&---------------------------------------------------------------------*
REPORT ygh_abr20640 MESSAGE-ID ygf_abr20640
                    LINE-COUNT 5000
                    LINE-SIZE 179.
*----------------------------------------------------------------------*
* TABLES DECLERATIONS                                                  *
*----------------------------------------------------------------------*
TABLES:     dpr_project, cgpl_entity, but000.
TYPE-POOLS: slis.
*----------------------------------------------------------------------*
* TYPES DECLERATIONS                                                   *
*----------------------------------------------------------------------*
TYPES : BEGIN OF t_cats_0315,
         pernr  TYPE pernr_d,
         begda  TYPE begda,
         endda  TYPE endda,
         kostl  TYPE skostl,
         lstar  TYPE lstar,
         plsta  TYPE plsta,
         werks  TYPE werks_d,
         lifnr  TYPE elifn,
         ebeln  TYPE sebeln,
         ebelp  TYPE sebelp,
         lstnr  TYPE asnum,
         sprznr TYPE co_prznr,
         accnt  TYPE c,
        END OF t_cats_0315,
        BEGIN OF t_project_id,
         project_id TYPE dpr_tv_project_id,
        END OF t_project_id,
        BEGIN OF t_final,
         participant_guid TYPE dpr_tv_participant_guid,
         bupa_guid        TYPE bu_partner_guid,
         comp_code        TYPE bukrs,
         plant            TYPE werks_d,
         pernr            TYPE personid,
         lifnr            TYPE lifnr,
         name             TYPE name1_gp,
         proj_name        TYPE dpr_tv_name,
         name_first       TYPE bu_namep_f,
         name_last        TYPE bu_namep_l,
         text1            TYPE cgpl_text1,
         role_text        TYPE dpr_tv_participant_role_text,
         staff_action     TYPE dpr_bupa_link-staff_action,
         task_type        TYPE dpr_tv_tsk_type,
         work_effort      TYPE dpr_tv_effort,
         work_unit        TYPE dpr_tv_unit,
         beg_tmstmp_eng   TYPE sy-datum,
         end_tmstmp_eng   TYPE sy-datum,
         location_text    TYPE dpr_tv_location_text,
         task_desc(1000)  TYPE c,                 "tdline,
         task_name        TYPE dpr_tv_name,
         proj_desc(1000)  TYPE c,                 "tdline,
         project_id       TYPE project_id,
         object_key(132)  TYPE c,
         actualstart      TYPE dpr_tv_bapi_ext_date,
         actualfinish     TYPE dpr_tv_bapi_ext_date,
         task_number      TYPE dpr_tv_task_id,
         name_pm(40)      TYPE c,
         bpkind(9)        TYPE c,
         flag             TYPE c,
         days_total       TYPE dpr_tv_effort,
        END OF t_final.
TYPES : BEGIN OF t_taskassignment,
         guid             TYPE dpr_tv_guid,
         created_by       TYPE dpr_tv_created_by,
         created_on       TYPE dpr_tv_timestamp,
         changed_by       TYPE dpr_tv_changed_by,
         changed_on       TYPE dpr_tv_timestamp,
         sort_number      TYPE dpr_tv_sort_number,
         participant_guid TYPE dpr_tv_guid,
         entity_type      TYPE cgpl_object_type,
         entity_guid      TYPE dpr_tv_guid,
         beg_tmstmp       TYPE dpr_tv_timestamp,
         end_tmstmp       TYPE dpr_tv_timestamp,
         work_effort      TYPE dpr_tv_assigned_work,
         work_unit        TYPE dpr_tv_unit,
         responsible      TYPE dpr_tv_responsibility,
         concrete_role    TYPE dpr_tv_concrete_role,
         ea_dummy         TYPE dpr_tv_ea_dummy,
         commentary       TYPE dpr_tv_commentary,
        END OF t_taskassignment,
        BEGIN OF t_taskdetail,
         participant_guid TYPE dpr_tv_participant_guid,
         entity_guid      TYPE dpr_tv_guid,
         task_type        TYPE dpr_tv_tsk_type,
         task_name        TYPE dpr_tv_name,
         task_type_text   TYPE dpr_tv_tsk_type_text,
         task_number      TYPE dpr_tv_task_id,
         task_desc(1000)  TYPE c,                         "tdline,
        END OF t_taskdetail,
        BEGIN OF t_output,
         bpartner    TYPE bu_partner,
         mail(125)   TYPE c,
         status(50)  TYPE c,
        END OF t_output.
TYPES : BEGIN OF t_message.
        INCLUDE STRUCTURE bapiret2.
TYPES : END OF t_message.
TYPES : BEGIN OF t_bdcdata,
         program TYPE bdc_prog,
         dynpro TYPE bdc_dynr,
         dynbegin TYPE bdc_start,
         fnam TYPE char140,
         fval TYPE string,
        END OF t_bdcdata.
*----------------------------------------------------------------------*
* DATA DECLERATIONS                                                    *
*----------------------------------------------------------------------*
DATA: v_guid             TYPE cgpl_guid16,
      v_pernr            TYPE personid,
      v_location         TYPE dpr_tv_location,
      v_begdate          TYPE sy-datum,
      v_beg_tmstmp       TYPE timestamp,
      v_enddate          TYPE sy-datum,
      v_end_tmstmp       TYPE timestamp,
      v_location_text    TYPE dpr_tv_location_text,
      v_task_guid        TYPE dpr_tv_entity_guid,
      v_tsk_type         TYPE dpr_tv_tsk_type,
      v_type_text        TYPE dpr_tv_type_text,
      v_project_guid     TYPE dpr_tt_guids,
      v_staff_action     TYPE prp_action_id,
      v_project_guid_s   TYPE LINE OF dpr_tt_guids,
      v_project_guid_1   TYPE dpr_tv_guid,
      v_text1            TYPE cgpl_text1,
      v_participant_role TYPE dpr_tv_participant_role,
      v_role_text        TYPE dpr_tv_participant_role_text,
      v_ltext(1000)      TYPE c,
      v_name(70)         TYPE c,
      v_save_name(70)    TYPE c,
      v_name_sub(100)    TYPE c,
      v_number           TYPE dpr_tv_number,
      v_role_guid        TYPE dpr_tv_bapi_guid_role,
      v_guid_x16         TYPE sysuuid-x,
      v_guid_c32         TYPE sysuuid-c,
      v_sucess(4)        TYPE c VALUE 0,
      v_failure(4)       TYPE c VALUE 0,
      v_int_order        TYPE project_id,
      v_name_first_pm    TYPE bu_namep_f,
      v_name_last_pm     TYPE bu_namep_l,
      v_name_pm(40)      TYPE c,
      v_skipflag         TYPE c VALUE '0',
      datediff           TYPE tfmatage,
      v_datediff(4)      TYPE n,
      v_bpkind           TYPE bu_bpkind,
      v_bpkind1          TYPE catsvarian,
      v_bpkind2          TYPE catsvarian,
      v_days_total       TYPE dpr_tv_assigned_work.   "i.
DATA : v_vis TYPE i.
*----------------------------------------------------------------------*
* INTERNAL TABLE DECLERATIONS                                          *
*----------------------------------------------------------------------*
DATA:  i_dpr_bupa_link_final  TYPE STANDARD TABLE OF t_final          WITH HEADER LINE,
       i_dpr_bupa_link_final1 TYPE STANDARD TABLE OF t_final          WITH HEADER LINE,
       i_dpr_bupa_link_final2 TYPE STANDARD TABLE OF t_final          WITH HEADER LINE,
       i_dpr_bupa_link_final3 TYPE STANDARD TABLE OF t_final          WITH HEADER LINE,
       i_batchoutput          TYPE STANDARD TABLE OF t_final          WITH HEADER LINE,
       i_tline                TYPE STANDARD TABLE OF tline            WITH HEADER LINE,
       i_project_id           TYPE STANDARD TABLE OF t_project_id     WITH HEADER LINE,
       i_dpr_bupa_link        TYPE STANDARD TABLE OF dpr_bupa_link    WITH HEADER LINE,
       i_proj_guid            TYPE STANDARD TABLE OF dpr_part         WITH HEADER LINE,
       i_objlink              TYPE STANDARD TABLE OF dpr_objlink      WITH HEADER LINE,
       i_taskassignment       TYPE STANDARD TABLE OF dpr_entity_link  WITH HEADER LINE,
       i_taskdetail           TYPE STANDARD TABLE OF t_taskdetail     WITH HEADER LINE,
       i_taskassignment1      TYPE STANDARD TABLE OF t_taskassignment WITH HEADER LINE,
       i_output               TYPE STANDARD TABLE OF t_output         WITH HEADER LINE,
       i_et_description       TYPE STANDARD TABLE OF
                                                  bapi_ts_description WITH HEADER LINE,
       i_bapi_ts_description  TYPE STANDARD TABLE OF
                                                  bapi_ts_description WITH HEADER LINE,
       i_bapi_task_desc       TYPE STANDARD TABLE OF
                                                  bapi_ts_description WITH HEADER LINE,
       i_et_staffing          TYPE STANDARD TABLE OF
                                                  bapi_ts_prp_staffing_det WITH HEADER LINE,
       i_et_subject           TYPE STANDARD TABLE OF
                                                  bapi_ts_subobject WITH HEADER LINE,
       i_months_name          TYPE STANDARD TABLE OF
                                                  t247 WITH HEADER LINE,
       i_bapi_ts_name         TYPE STANDARD TABLE OF
                                                  bapi_ts_name WITH HEADER LINE,
       i_message              TYPE STANDARD TABLE OF t_message WITH HEADER LINE.
*----------------------------------------------------------------------*
* WORKAREA DECLERATIONS                                                *
*----------------------------------------------------------------------*
DATA : wa_0315                       TYPE STANDARD TABLE OF t_cats_0315 WITH HEADER LINE,
       wa_bapi2075_2                 TYPE bapi2075_2,
       wa_participant_guid           TYPE bapi_ts_guid,
       wa_es_projectrole             TYPE bapi_ts_prp_projectrole_det,
       wa_es_projectrole_pm          TYPE bapi_ts_prp_projectrole_det,
       wa_task_guid                  TYPE bapi_ts_guid,
       wa_es_task_detail             TYPE bapi_ts_task_detail,
       wa_generaldetail              TYPE bapivendor_04,
       wa_bapi_ts_guid               TYPE bapi_ts_guid,
       wa_bapi_ts_project_def_detail TYPE bapi_ts_project_def_detail,
       wa_bapi_ts_name               TYPE STANDARD TABLE OF bapi_ts_name WITH HEADER LINE.
*----------------------------------------------------------------------*
* BATCH JOB DECLERATIONS                                               *
*----------------------------------------------------------------------*
*----------------------------------------------------------------------*
* TYPES DECLERATIONS                                                   *
*----------------------------------------------------------------------*
TYPES: t_document_data  TYPE  sodocchgi1,
       t_packing_list   TYPE  sopcklsti1,
       t_attachment     TYPE  solisti1,
       t_body_msg       TYPE  solisti1,
       t_receivers      TYPE  somlreci1.
*----------------------------------------------------------------------*
* INTERNALTABLE DECLERATIONS                                           *
*----------------------------------------------------------------------*
DATA : i_document_data  TYPE STANDARD TABLE OF t_document_data,
       i_packing_list   TYPE STANDARD TABLE OF t_packing_list,
       i_attachment     TYPE STANDARD TABLE OF t_attachment,
       i_body_msg       TYPE STANDARD TABLE OF t_body_msg,
       i_receivers      TYPE STANDARD TABLE OF t_receivers.
*----------------------------------------------------------------------*
* WORK AREA DECLERATIONS                                               *
*----------------------------------------------------------------------*
DATA : w_document_data  TYPE  t_document_data,
       w_packing_list   TYPE  t_packing_list,
       w_attachment     TYPE  t_attachment,
       w_body_msg       TYPE  t_body_msg,
       w_receivers      TYPE  t_receivers.
*----------------------------------------------------------------------*
* DATA DECLERATIONS                                                    *
*----------------------------------------------------------------------*
DATA : v_work_effort(9)      TYPE c,
       v_beg_tmstmp_eng      TYPE sy-datum,
       v_end_tmstmp_eng      TYPE sy-datum,
       v_beg_tmstmp_eng1(11) TYPE c,
       v_end_tmstmp_eng1(11) TYPE c,
       v_date(2)             TYPE c,
       v_month(2)            TYPE c,
       v_year(4)             TYPE c,
       v_start_date          TYPE sy-datum,
       v_end_date            TYPE sy-datum,
       v_email(128)          TYPE c,
       v_recp(128)           TYPE c,
       g_sent_to_all         TYPE sonv-flag,
       g_tab_lines           TYPE i.
*----------------------------------------------------------------------*
* CLASS DECLERATIONS                                                   *
*----------------------------------------------------------------------*
CLASS cl_abap_char_utilities DEFINITION LOAD.
*----------------------------------------------------------------------*
* CONSTANT DECLERATIONS                                                *
*----------------------------------------------------------------------*
CONSTANTS : con_tab  TYPE c VALUE cl_abap_char_utilities=>horizontal_tab,
            con_cret TYPE c VALUE cl_abap_char_utilities=>cr_lf.
CONSTANTS : c_gdd(6) TYPE c VALUE 'GDD590',
            c_gb2(6) TYPE c VALUE 'GB2590',
            c_gp1(6) TYPE c VALUE 'GP1590'.
*----------------------------------------------------------------------*
* RANGES DECLERATION                                                   *
*----------------------------------------------------------------------*
RANGES : r_date  FOR sy-datum,
         r_bpnum FOR but000-partner.
*----------------------------------------------------------------------*
* ALV Data Declerations                                                *
*----------------------------------------------------------------------*
DATA: fieldcatalog  TYPE slis_t_fieldcat_alv WITH HEADER LINE,
      gd_tab_group  TYPE slis_t_sp_group_alv,
      gd_layout     TYPE slis_layout_alv,
      gd_repid      LIKE sy-repid,
      gt_events     TYPE slis_t_event,
      gd_prntparams TYPE slis_print_alv,
      v_dest        LIKE edipoa-logdes,
      v_handle      LIKE sy-tabix,
      v_spool_id    LIKE tsp01-rqident,
      v_rc          TYPE c,
      v_errmessage(100) TYPE c,
      v_text(1000) TYPE c.
*----------------------------------------------------------------------*
* OLE DATA DECLERATION                                                 *
*----------------------------------------------------------------------*
TYPES: BEGIN OF t_catsw,
        mark TYPE catsmark,
        skostl TYPE skostl,
        lstar TYPE lstar,
        sebeln TYPE sebeln,                   "PO
        sebelp TYPE sebelp,                   "ITEM NUMBER
        sprznr TYPE sprznr,
        lstnr TYPE asnum,                     "ACTIVITY NUMBER
        rkostl TYPE ekostl,
        rproj TYPE num8,
        raufnr TYPE eaufnr,
        rnplnr TYPE nw_aufnr,
        raufpl TYPE co_aufpl,
        raplzl TYPE num8,
        rkdauf TYPE ekdau,
        rkdpos TYPE ekdpo,
        rkstr TYPE ekstr,
        rprznr TYPE eprznr,
        paobjnr TYPE rkeobjnr,
        sumdayw TYPE catswsum,
        day1 TYPE catshours,
        day2 TYPE catshours,
        day3 TYPE catshours,
        day4 TYPE catshours,
        day5 TYPE catshours,
        day6 TYPE catshours,
        day7 TYPE catshours,
        day8 TYPE catshours,
        day9 TYPE catshours,
        day10 TYPE catshours,
        day11 TYPE catshours,
        day12 TYPE catshours,
        day13 TYPE catshours,
        day14 TYPE catshours,
        day15 TYPE catshours,
        day16 TYPE catshours,
        day17 TYPE catshours,
        day18 TYPE catshours,
        day19 TYPE catshours,
        day20 TYPE catshours,
        day21 TYPE catshours,
        day22 TYPE catshours,
        day23 TYPE catshours,
        day24 TYPE catshours,
        day25 TYPE catshours,
        day26 TYPE catshours,
        day27 TYPE catshours,
        day28 TYPE catshours,
        day29 TYPE catshours,
        day30 TYPE catshours,
        day31 TYPE catshours,
        vornr TYPE vornr,
        uvorn TYPE uvorn,
        bedid TYPE num12,
        kapar TYPE kapart,
        arbpl TYPE arbpl,
        posid TYPE ps_posid,
        zcpr_guid TYPE char32,
        zcpr_extid TYPE char24,          "TASK NAME
        zcpr_objguid TYPE char32,
        zcpr_objgextid TYPE char24,
        zcpr_objtype TYPE char3,
        zzcpr_guid TYPE char32,
        zzcpr_extid TYPE char24,         "PROJECT ID
        zzcpr_objguid TYPE char32,
        zzcpr_objgextid TYPE char24,     "TASK ID
        zzcpr_objtype TYPE char3,
        participant_role TYPE char15,    "PARTICIPANT ROLE
        arbid TYPE objektid,
        werks TYPE werks_d,
        split TYPE cats_split,
        ltxa1 TYPE ltxa1,
        fstad TYPE dats,
        sstad TYPE dats,
        fendd TYPE dats,
        sendd TYPE dats,
        kbearest TYPE fltp_value,
        vertl TYPE cr_vertn,
        autyp TYPE auftyp,
        kalid TYPE wfcid,
        rproj_ext TYPE ps_posid,
        disptextw1 TYPE text40,
        disptextw2 TYPE text40,
        kper_single TYPE catsmark,
        kper_collect TYPE catsmark,
       END OF t_catsw.
INCLUDE ole2incl.
DATA: gs_excel        TYPE ole2_object,
      gs_wbooklist    TYPE ole2_object,
      gs_application  TYPE ole2_object,
      gs_wbook        TYPE ole2_object,
      gs_activesheet  TYPE ole2_object,
      gs_sheets       TYPE ole2_object,
      gs_newsheet     TYPE ole2_object,
      gs_cell1        TYPE ole2_object,
      gs_cell2        TYPE ole2_object,
      gs_cells        TYPE ole2_object,
      gs_range        TYPE ole2_object,
      gs_font         TYPE ole2_object,
      gs_interior     TYPE ole2_object,
      gs_columns      TYPE ole2_object,
      gs_autofit      TYPE ole2_object,
      gs_table_border TYPE ole2_object,
      gs_table        TYPE ole2_object,
      gs_save         TYPE ole2_object,
      gs_wactbooklist TYPE ole2_object,
      gs_comment      TYPE ole2_object,
      g_workbook      TYPE ole2_object.
DATA: gv_index(2) TYPE c,
      gv_outer_index LIKE sy-index,
      gv_sheet_name(26) TYPE c,
      gv_line_cntr TYPE i,
      gv_line_cntr_1 TYPE i,
      v_flag TYPE c VALUE '0'.
DATA: i_etworklist TYPE STANDARD TABLE OF t_catsw WITH HEADER LINE.
*----------------------------------------------------------------------*
* EMAIL DATA DECLERATION                                               *
*----------------------------------------------------------------------*
DATA : method1 LIKE sy-ucomm,
       g_user LIKE soudnamei1,
       g_user_data LIKE soudatai1,
       g_owner LIKE soud-usrnam,
       g_receipients LIKE soos1 OCCURS 0 WITH HEADER LINE,
       g_document LIKE sood4,
       g_header LIKE sood2,
       g_folmam LIKE sofm2,
       g_objcnt LIKE soli OCCURS 0 WITH HEADER LINE,
       g_objhead LIKE soli OCCURS 0 WITH HEADER LINE,
       g_objpara  LIKE selc OCCURS 0 WITH HEADER LINE,
       g_objparb  LIKE soop1 OCCURS 0 WITH HEADER LINE,
       g_attachments LIKE sood5 OCCURS 0 WITH HEADER LINE,
       g_references LIKE soxrl OCCURS 0 WITH HEADER LINE,
       g_authority LIKE sofa-usracc,
       g_ref_document LIKE sood4,
       g_new_parent LIKE soodk.

DATA: BEGIN OF g_files OCCURS 10,
       text(4096) TYPE c,
      END OF g_files.
DATA : fold_number(12) TYPE c,
       fold_yr(2)      TYPE c,
       fold_type(3)    TYPE c.
DATA : ws_file         TYPE string, "DEFAULT 'C:\Documents and Settings\rd76685\Desktop\test.xls'.
       ws_email(128)   TYPE c,
       ws_pernr        TYPE pernr_d,
       ws_proid        TYPE project_id,
       ws_begdt(10)    TYPE c,
       ws_enddt(10)    TYPE c,
       w_pernr         TYPE pernr_d,
       w_proid         TYPE project_id,
       w_begdt(10)     TYPE c,
       w_enddt(10)     TYPE c,
       v_begday(2)     TYPE c,
       v_begmnt(2)     TYPE c,
       v_begyear(4)    TYPE c,
       v_endday(2)     TYPE c,
       v_endmnt(2)     TYPE c,
       v_endyear(4)    TYPE c,
       v_begday1(2)    TYPE c,
       v_begmnt1(2)    TYPE c,
       v_begyear1(4)   TYPE c,
       v_endday1(2)    TYPE c,
       v_endmnt1(2)    TYPE c,
       v_endyear1(4)   TYPE c,
       v_datebeg(11)   TYPE c,
       v_datebeg1(10)  TYPE c,
       v_dateend(11)   TYPE c,
       v_dateend1(10)  TYPE c,
       v_begindate(11) TYPE c,
       v_enddate1(11)  TYPE c,
       v_month_name    TYPE fcktx,
       v_temp_value    TYPE dpr_tv_effort,
       v_status1       TYPE c VALUE '0',
       v_status2       TYPE c VALUE '0',
       v_tag1(3)       TYPE c VALUE '<(>',
       v_tag2(3)       TYPE c VALUE '<)>',
       v_ldescription(1000) TYPE c,
       v_beg_date1     TYPE sy-datum,
       v_end_date1     TYPE sy-datum.
DATA : v_bpnumlow(8)   TYPE c,
       v_bpnumhigh(8)  TYPE c.
*DATA : bdcdata TYPE STANDARD TABLE OF t_bdcdata WITH HEADER LINE.
DATA : bdcdata TYPE STANDARD TABLE OF bdcdata WITH HEADER LINE.
DATA : wa_bapibus1006_head TYPE bapibus1006_head,
       wa_bapiadsmtp       TYPE STANDARD TABLE OF bapiadsmtp WITH HEADER LINE.
DATA : v_businesspartner   TYPE bu_partner.
*----------------------------------------------------------------------*
* S E L E C T I O N    S C R E E N                                     *
*----------------------------------------------------------------------*
* Selection Parameters/Select Options.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
SELECT-OPTIONS : s_projid FOR dpr_project-project_id OBLIGATORY
                              MATCHCODE OBJECT ygi_abr20663_projectid,
                 s_bpnum  FOR but000-partner.
PARAMETERS:      p_begdt LIKE sy-datum DEFAULT sy-datum,
                 p_enddt LIKE sy-datum.
PARAMETERS :     p_trig TYPE xfeld,
                 p_recp(125) TYPE c.
SELECTION-SCREEN END OF BLOCK b1.
*----------------------------------------------------------------------*
* INITIALAZITION                                                       *
*----------------------------------------------------------------------*
INITIALIZATION.
  PERFORM f_initialaze_rfcdest.
*----------------------------------------------------------------------*
* AT SELECTION SCREEN                                                  *
*----------------------------------------------------------------------*
**Validating Selection Screen File Type
AT SELECTION-SCREEN.
  IF s_projid[] IS INITIAL AND
     p_begdt IS INITIAL AND
     p_enddt IS NOT INITIAL.
    MESSAGE e000.
  ELSEIF s_projid[] IS INITIAL AND
     p_begdt IS NOT INITIAL AND
     p_enddt IS INITIAL.
    MESSAGE e001.
  ELSEIF NOT s_projid[] IS INITIAL AND
     p_begdt IS INITIAL AND
     p_enddt IS INITIAL.
    MESSAGE e003.
  ELSEIF NOT s_projid[] IS INITIAL AND
     p_begdt IS INITIAL AND
     p_enddt IS NOT INITIAL.
    MESSAGE e000.
  ELSEIF NOT s_projid[] IS INITIAL AND
     p_begdt IS NOT INITIAL AND
     p_enddt IS INITIAL.
    MESSAGE e001.
  ELSEIF NOT s_projid[] IS INITIAL AND
     p_enddt < p_begdt.
    MESSAGE e004.
  ELSEIF s_projid[] IS INITIAL AND
     p_enddt < p_begdt.
    MESSAGE e004.
  ELSEIF s_projid[] IS INITIAL AND
     p_begdt IS INITIAL AND
     p_enddt IS INITIAL.
    MESSAGE e003.
  ENDIF.
*----------------------------------------------------------------------*
* S T A R T   O F   S E L E C T I O N                                  *
*----------------------------------------------------------------------*
START-OF-SELECTION.
  IF NOT s_bpnum[] IS INITIAL.
    LOOP AT s_bpnum.
      v_bpnumlow  = s_bpnum-low+2(8).
      v_bpnumhigh = s_bpnum-high+2(8).
      r_bpnum-option  = s_bpnum-option.
      r_bpnum-sign    = s_bpnum-sign.
      r_bpnum-low     = v_bpnumlow.
      r_bpnum-high    = v_bpnumhigh.
      APPEND r_bpnum.
      CLEAR : r_bpnum, v_bpnumlow, v_bpnumhigh.
    ENDLOOP.
  ENDIF.

  r_date-option = 'BT'.
  r_date-sign   = 'I'.
  r_date-low    = p_begdt.
  r_date-high   = p_enddt.
  APPEND r_date.
  CLEAR : r_date.

  CALL FUNCTION 'MONTH_NAMES_GET'
    EXPORTING
      language              = sy-langu
    TABLES
      month_names           = i_months_name
    EXCEPTIONS
      month_names_not_found = 1
      OTHERS                = 2.

  CALL FUNCTION 'FIMA_DAYS_AND_MONTHS_AND_YEARS'
    EXPORTING
      i_date_from = p_begdt
      i_date_to   = p_enddt
    IMPORTING
      e_days      = datediff.

  v_datediff = datediff.
  v_datediff = v_datediff + 1.
  SHIFT v_datediff LEFT DELETING LEADING space.
  IF v_datediff = '0'.
    v_datediff = 1.
    SHIFT v_datediff LEFT DELETING LEADING space.
  ENDIF.
  v_begdate = p_begdt.
  v_enddate = p_enddt.
  v_begyear = p_begdt+0(4).
  v_begmnt  = p_begdt+4(2).
  v_begday  = p_begdt+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_begmnt.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_begday v_month_name v_begyear INTO v_datebeg SEPARATED BY '-'.
  CONCATENATE v_begday v_begmnt v_begyear INTO v_datebeg1 SEPARATED BY '.'.
  v_endyear = p_enddt+0(4).
  v_endmnt  = p_enddt+4(2).
  v_endday  = p_enddt+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_endmnt.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_endday v_month_name v_endyear INTO v_dateend SEPARATED BY '-'.
  CONCATENATE v_endday v_endmnt v_endyear INTO v_dateend1 SEPARATED BY '.'.
  CONVERT DATE       v_begdate INTO
          TIME STAMP v_beg_tmstmp
          TIME ZONE cl_cgpl_scheduling=>m_tzone.
  CONVERT DATE       v_enddate INTO
          TIME STAMP v_end_tmstmp
          TIME ZONE cl_cgpl_scheduling=>m_tzone.

  PERFORM data_retrieval.
  PERFORM fetch_records.
  PERFORM filter_records.
  IF sy-batch NE 'X'.
    IF p_trig NE 'X' AND
       i_dpr_bupa_link_final1[] IS NOT INITIAL.
      PERFORM filter_output_display_alv.
      IF NOT i_dpr_bupa_link_final1[] IS INITIAL.
        PERFORM build_fieldcatalog.
        PERFORM build_layout.
        PERFORM display_alv_report.
      ENDIF.
    ELSEIF p_trig EQ 'X' AND
           p_recp IS INITIAL AND
           i_dpr_bupa_link_final1[] IS NOT INITIAL.
      PERFORM excel_sheet_application.
    ELSEIF p_trig EQ 'X' AND
           p_recp IS NOT INITIAL AND
           i_dpr_bupa_link_final1[] IS NOT INITIAL.
      PERFORM excel_sheet_mail_recipient USING p_recp.
    ENDIF.
  ELSE.
    PERFORM batch_process_email USING p_recp.
  ENDIF.
  CLEAR : v_begday,  v_begmnt,  v_begyear,  v_endday,  v_endmnt,  v_endyear,
          v_datebeg, v_dateend, v_datediff, datediff,  v_month_name, v_datebeg1, v_dateend1,
          v_begday1, v_begmnt1, v_begyear1, v_endday1, v_endmnt1, v_endyear1.
  REFRESH : i_months_name.
  IF i_dpr_bupa_link_final1[] IS INITIAL.
    MESSAGE ID 'YGF_ABR20640' TYPE 'I' NUMBER '005'.
  ENDIF.
*&---------------------------------------------------------------------*
*&      Form  DATA_RETRIEVAL
*&---------------------------------------------------------------------*
FORM data_retrieval .
  IF NOT s_projid[] IS INITIAL.   "AND
*         p_begdt IS INITIAL AND
*         p_enddt IS INITIAL.
    SELECT guid project_id
           FROM dpr_project
           INTO CORRESPONDING FIELDS OF TABLE i_project_id
           WHERE project_id IN s_projid AND
                 version_number EQ space.

    LOOP AT i_project_id.
      CALL FUNCTION 'DPR_GET_GUID_BY_ID_FROM_DB'
        EXPORTING
          iv_number            = i_project_id-project_id
          iv_version_number    = ' '
          iv_object_type       = 'DPO'
        IMPORTING
          et_guid              = v_project_guid
        EXCEPTIONS
          no_rfc_authorization = 1
          not_found            = 2
          invalid_object_type  = 3
          OTHERS               = 4.
      IF sy-subrc = 0.
        READ TABLE v_project_guid INTO v_project_guid_s INDEX 1.
        SELECT *
               FROM cgpl_entity
               INTO CORRESPONDING FIELDS OF TABLE i_proj_guid
               WHERE project_guid EQ v_project_guid_s AND
                     object_type  EQ 'MTG'.
        IF sy-subrc = 0.
          IF NOT i_proj_guid[] IS INITIAL.
            SELECT *
                   APPENDING CORRESPONDING FIELDS OF TABLE i_dpr_bupa_link
                   FROM dpr_bupa_link
                   FOR ALL ENTRIES IN i_proj_guid
                   WHERE participant_guid EQ i_proj_guid-guid AND
                         end_tmstmp >= v_beg_tmstmp AND
                         beg_tmstmp <= v_end_tmstmp.
*                         staff_action = 'CRTD' AND
          ENDIF.
        ENDIF.
      ENDIF.
      CLEAR : v_project_guid, v_project_guid_s, v_guid.
      REFRESH : i_proj_guid.
    ENDLOOP.
  ELSEIF s_projid[] IS INITIAL.    "AND
*         p_begdt IS NOT INITIAL AND
*         p_enddt IS NOT INITIAL.
    SELECT *
           INTO CORRESPONDING FIELDS OF TABLE i_dpr_bupa_link
           FROM dpr_bupa_link
           WHERE end_tmstmp >= v_beg_tmstmp AND
                 beg_tmstmp <= v_end_tmstmp.
*               staff_action = 'CRTD' AND

*  ELSEIF NOT s_projid[] IS INITIAL AND
*         ( p_begdt IS NOT INITIAL OR p_enddt IS NOT INITIAL ).
*    SELECT guid project_id
*           FROM dpr_project
*           INTO CORRESPONDING FIELDS OF TABLE i_project_id
*           WHERE project_id IN s_projid.
*
*    LOOP AT i_project_id.
*      CALL FUNCTION 'DPR_GET_GUID_BY_ID_FROM_DB'
*        EXPORTING
*          iv_number            = i_project_id-project_id
*          iv_version_number    = ' '
*          iv_object_type       = 'DPO'
*        IMPORTING
*          et_guid              = v_project_guid
*        EXCEPTIONS
*          no_rfc_authorization = 1
*          not_found            = 2
*          invalid_object_type  = 3
*          OTHERS               = 4.
*      IF sy-subrc = 0.
*        READ TABLE v_project_guid INTO v_project_guid_s INDEX 1.
*        SELECT *
*               FROM cgpl_entity
*               INTO CORRESPONDING FIELDS OF TABLE i_proj_guid
*               WHERE project_guid EQ v_project_guid_s AND
*                     object_type  EQ 'MTG'.
*        IF sy-subrc = 0.
*          IF NOT i_proj_guid[] IS INITIAL.
*            SELECT *
*                   APPENDING CORRESPONDING FIELDS OF TABLE i_dpr_bupa_link
*                   FROM dpr_bupa_link
*                   FOR ALL ENTRIES IN i_proj_guid
*                   WHERE participant_guid EQ i_proj_guid-guid AND
*                         staff_action = 'CRTD'.
*          ENDIF.
*        ENDIF.
*      ENDIF.
*      CLEAR : v_project_guid, v_project_guid_s, v_guid.
*      REFRESH : i_proj_guid.
*    ENDLOOP.
*  ELSEIF s_projid[] IS INITIAL AND
*        p_begdt IS INITIAL AND
*        p_enddt IS INITIAL.
*    SELECT *
*           INTO CORRESPONDING FIELDS OF TABLE i_dpr_bupa_link
*           FROM dpr_bupa_link
*           WHERE staff_action = 'CRTD'.
  ENDIF.
ENDFORM.                    " DATA_RETRIEVAL
*&---------------------------------------------------------------------*
*&      Form  FETCH_RECORS
*&---------------------------------------------------------------------*
FORM fetch_records .
  DATA : v_length(3) TYPE n.
  LOOP AT i_dpr_bupa_link.
    i_dpr_bupa_link_final-bupa_guid = i_dpr_bupa_link-bupa_guid.
    i_dpr_bupa_link_final-participant_guid = i_dpr_bupa_link-participant_guid.
** to get Personal Number(PERNR) for each BUPA_GUID
    CALL FUNCTION 'BP_CENTRALPERSON_GET'
      EXPORTING
        iv_bu_partner_guid = i_dpr_bupa_link-bupa_guid
      IMPORTING
        ev_person_id       = v_pernr.

    i_dpr_bupa_link_final-pernr = v_pernr.

    DATA : v_name_last  TYPE bu_namep_l,
           v_name_first TYPE bu_namep_f.
    SELECT SINGLE name_last name_first
           FROM but000
           INTO (v_name_last , v_name_first)
           WHERE partner_guid = i_dpr_bupa_link-bupa_guid.

    i_dpr_bupa_link_final-name_first = v_name_first.
    i_dpr_bupa_link_final-name_last  = v_name_last.

**To Get LIFNR
    CALL FUNCTION 'CATS_GET_INFOTYPE_0315' DESTINATION v_dest
      EXPORTING
        pernr           = v_pernr
        date            = sy-datum
      IMPORTING
        i0315           = wa_0315
      EXCEPTIONS
        pernr_not_found = 1
        no_record       = 2
        no_authority    = 3
        OTHERS          = 4.
**For ICDR's only
*    IF sy-subrc NE 0.
*      CONTINUE.
*    ENDIF.
**For ICDR's only
    i_dpr_bupa_link_final-lifnr = wa_0315-lifnr.
    i_dpr_bupa_link_final-pernr = v_pernr.

    CALL FUNCTION 'BAPI_VENDOR_GETDETAIL' DESTINATION v_dest
      EXPORTING
        vendorno      = wa_0315-lifnr
      IMPORTING
        generaldetail = wa_generaldetail.
    i_dpr_bupa_link_final-name = wa_generaldetail-name.

**Project Name
    SELECT SINGLE project_guid
           FROM cgpl_entity
           INTO v_project_guid_1
           WHERE guid = i_dpr_bupa_link-participant_guid AND
                 object_type EQ 'MTG'.

    SELECT SINGLE text1
           FROM cgpl_text
           INTO v_text1
           WHERE guid = v_project_guid_1.

    i_dpr_bupa_link_final-text1 = v_text1.
**Purchase Order Details
    wa_participant_guid-role_guid = i_dpr_bupa_link-participant_guid.
    CALL FUNCTION 'BAPI_BUS2177_GET_DETAIL'
      EXPORTING
        projectrole_guid = wa_participant_guid-role_guid
      IMPORTING
        es_projectrole   = wa_es_projectrole.

**To get PM Name
    CALL FUNCTION 'BAPI_BUS2172_GET_SUBOBJECTS'
      EXPORTING
        project_definition_guid = wa_es_projectrole-project_guid
      TABLES
        et_subobject            = i_et_subject.

    LOOP AT i_et_subject WHERE object_type EQ 'MTG'.
      CALL FUNCTION 'BAPI_BUS2177_GET_DETAIL'
        EXPORTING
          projectrole_guid = i_et_subject-guid
        IMPORTING
          es_projectrole   = wa_es_projectrole_pm
        TABLES
          et_staffing      = i_et_staffing.

      IF wa_es_projectrole_pm-role_type = 'DSRB-PM'.
        READ TABLE i_et_staffing INDEX 1.
        IF sy-subrc = 0.
          SELECT SINGLE name_first name_last
                 FROM but000
                 INTO (v_name_first_pm, v_name_last_pm)
                 WHERE partner_guid = i_et_staffing-partner_guid.
          IF sy-subrc = 0.
            CONCATENATE v_name_first_pm
                        v_name_last_pm
                        INTO v_name_pm SEPARATED BY space.
            i_dpr_bupa_link_final-name_pm = v_name_pm.
            CLEAR : v_name_first_pm, v_name_last_pm, v_name_pm.
          ENDIF.
        ENDIF.
      ENDIF.
      REFRESH : i_et_staffing.
      CLEAR   : wa_es_projectrole_pm.
    ENDLOOP.
    REFRESH : i_et_subject.

    SELECT *
           FROM dpr_objlink
           INTO CORRESPONDING FIELDS OF TABLE i_objlink
           WHERE task_guid = wa_es_projectrole-role_guid AND
                 object_type = '0PURCHORDITEM'.
    IF sy-subrc = 0.
      LOOP AT i_objlink.
        WRITE i_objlink-description TO v_ldescription NO-GAP.
        CONCATENATE v_ltext i_objlink-object_key+0(10) '/' '(' v_ldescription ')' ',' INTO v_ltext.
        CONCATENATE v_ltext '/' INTO v_ltext.
        CLEAR : v_ldescription.
      ENDLOOP.
      TRANSLATE v_ltext USING '/ '.
      SEARCH v_ltext FOR ','.
      IF sy-subrc = 0.
        v_length =  strlen( v_ltext ).
        v_length = v_length - 1.
        v_ltext = v_ltext+0(v_length).
      ENDIF.
*      v_ltext = v_ltext+1(131).
      i_dpr_bupa_link_final-object_key = v_ltext.
      CLEAR : v_ltext, v_ldescription.
    ENDIF.
    CLEAR : wa_participant_guid, wa_es_projectrole, v_length.
**Internal Order Number
    SELECT SINGLE project_guid
              FROM cgpl_entity
              INTO v_project_guid_1
              WHERE guid = i_dpr_bupa_link-participant_guid AND
                    object_type EQ 'MTG'.

    CALL FUNCTION 'DPR_GET_ID_BY_GUID_FROM_DB'
      EXPORTING
        iv_guid              = v_project_guid_1
      IMPORTING
        ev_number            = v_number
      EXCEPTIONS
        no_rfc_authorization = 1
        not_found            = 2
        invalid_object_type  = 3
        OTHERS               = 4.

    i_dpr_bupa_link_final-project_id = v_number.
**Role Type Text / Role Description
    wa_participant_guid-role_guid = i_dpr_bupa_link-participant_guid.
    CALL FUNCTION 'BAPI_BUS2177_GET_DETAIL'
      EXPORTING
        projectrole_guid = wa_participant_guid-role_guid
      IMPORTING
        es_projectrole   = wa_es_projectrole
      TABLES
        et_description   = i_et_description.

    IF sy-subrc = 0.
      CLEAR : v_name.
      LOOP AT i_et_description.
        CONCATENATE v_ltext i_et_description-description_line INTO v_ltext SEPARATED BY ','.
        REPLACE ALL OCCURRENCES OF v_tag1 IN v_ltext WITH ' '.
        REPLACE ALL OCCURRENCES OF v_tag2 IN v_ltext WITH ' '.
      ENDLOOP.
      v_ltext = v_ltext+1(999).
      i_dpr_bupa_link_final-task_desc = v_ltext.
      CLEAR : v_ltext.
      i_dpr_bupa_link_final-role_text = wa_es_projectrole-role_type_text.
    ENDIF.
    CLEAR : wa_participant_guid, wa_es_projectrole.
**Project Dates
    wa_bapi_ts_guid-project_definition_guid = v_project_guid_1.

    CALL FUNCTION 'BAPI_BUS2172_GET_DETAIL'
      EXPORTING
        project_definition_guid      = wa_bapi_ts_guid-project_definition_guid
      IMPORTING
        es_project_definition_detail = wa_bapi_ts_project_def_detail
      TABLES
        et_name                      = i_bapi_ts_name
        et_description               = i_bapi_ts_description.

    IF sy-subrc = 0.
      CLEAR : v_ltext.
      LOOP AT i_bapi_ts_description.
        CONCATENATE v_ltext i_bapi_ts_description-description_line INTO v_ltext SEPARATED BY ','.
        REPLACE ALL OCCURRENCES OF v_tag1 IN v_ltext WITH ' '.
        REPLACE ALL OCCURRENCES OF v_tag2 IN v_ltext WITH ' '.
      ENDLOOP.
      v_ltext = v_ltext+1(999).
      i_dpr_bupa_link_final-proj_desc = v_ltext.
      CLEAR : v_ltext.
    ENDIF.
    LOOP AT i_bapi_ts_name WHERE language = 'EN'.
      i_dpr_bupa_link_final-proj_name = i_bapi_ts_name-name.
    ENDLOOP.
    i_dpr_bupa_link_final-actualstart = wa_bapi_ts_project_def_detail-fixed_start_date.
    i_dpr_bupa_link_final-actualfinish = wa_bapi_ts_project_def_detail-fixed_finish_date.
**Task Type
    SELECT *
            FROM dpr_entity_link
            APPENDING CORRESPONDING FIELDS OF TABLE i_taskassignment
            WHERE participant_guid EQ i_dpr_bupa_link-participant_guid AND
                  entity_type EQ 'TTO' AND
                  responsible NE 'X'.
    APPEND : i_dpr_bupa_link_final.
    CLEAR  : v_pernr, wa_0315, v_project_guid, v_number, wa_bapi2075_2, v_text1,
             v_participant_role,v_guid_x16, v_guid_c32, v_role_text, v_name,
             v_location, v_location_text,  wa_participant_guid, i_dpr_bupa_link_final,
             v_role_guid, wa_es_projectrole, wa_generaldetail, wa_bapi_ts_project_def_detail,
             wa_bapi_ts_guid, v_project_guid_1.
    REFRESH : i_tline, i_objlink, i_et_description, i_bapi_ts_name.
  ENDLOOP.

  LOOP AT i_taskassignment.
    wa_task_guid-task_guid = i_taskassignment-entity_guid.

    i_bapi_task_desc-language = 'EN'.
    APPEND i_bapi_task_desc.

    CALL FUNCTION 'BAPI_BUS2175_GET_DETAIL'
      EXPORTING
        task_guid      = wa_task_guid-task_guid
      IMPORTING
        es_task_detail = wa_es_task_detail
      TABLES
        et_name        = wa_bapi_ts_name
        et_description = i_bapi_task_desc.

    i_taskdetail-participant_guid = i_taskassignment-participant_guid.
    i_taskdetail-entity_guid      = i_taskassignment-entity_guid.
    i_taskdetail-task_type        = wa_es_task_detail-task_type.
    i_taskdetail-task_type_text   = wa_es_task_detail-task_type_text.
    i_taskdetail-task_number      = wa_es_task_detail-task_number.
    READ TABLE wa_bapi_ts_name INDEX 1.
    IF sy-subrc = 0.
      i_taskdetail-task_name      = wa_bapi_ts_name-name.
    ENDIF.
    READ TABLE i_bapi_task_desc INDEX 1.
    IF sy-subrc EQ 0.
      CLEAR : v_ltext.
      v_ltext = i_bapi_task_desc-description_line.
      REPLACE ALL OCCURRENCES OF v_tag1 IN v_ltext WITH ' '.
      REPLACE ALL OCCURRENCES OF v_tag2 IN v_ltext WITH ' '.
      i_taskdetail-task_desc   = v_ltext.             "i_bapi_task_desc-description_line.
    ENDIF.
    APPEND : i_taskdetail.
    CLEAR : i_taskdetail, wa_es_task_detail, wa_task_guid, wa_bapi_ts_name, v_ltext.
  ENDLOOP.
ENDFORM.                    " FETCH_RECORdS
*&---------------------------------------------------------------------*
*&      Form  FILTER_RECORDS
*&---------------------------------------------------------------------*
FORM filter_records .
  DATA : v_beg_date      TYPE sy-datum,
         v_end_date      TYPE sy-datum,
         v_beg_timestamp TYPE timestamp,
         v_end_timestamp TYPE timestamp,
         v_effortvalue(11) TYPE c,
         v_effortvalue1(4) TYPE n,
         v_length(4)       TYPE c.

  LOOP AT i_taskassignment.
    v_beg_timestamp = i_taskassignment-beg_tmstmp.
    v_end_timestamp = i_taskassignment-end_tmstmp.
    READ TABLE i_dpr_bupa_link_final WITH KEY
                 participant_guid = i_taskassignment-participant_guid.
    IF sy-subrc = 0.
      MOVE-CORRESPONDING i_dpr_bupa_link_final TO i_dpr_bupa_link_final1.
      CONVERT TIME STAMP v_beg_timestamp
              TIME ZONE cl_cgpl_scheduling=>m_tzone
              INTO DATE v_beg_date.
      CONVERT TIME STAMP v_end_timestamp
              TIME ZONE cl_cgpl_scheduling=>m_tzone
              INTO DATE v_end_date.
      i_dpr_bupa_link_final1-work_effort    = i_taskassignment-work_effort.
      i_dpr_bupa_link_final1-work_unit      = i_taskassignment-work_unit.
      i_dpr_bupa_link_final1-beg_tmstmp_eng = v_beg_date.   "I_taskassignment-beg_tmstmp.
      i_dpr_bupa_link_final1-end_tmstmp_eng = v_end_date.   "I_taskassignment-end_tmstmp.

**For Checking the work effort days with the
**Task Start/End Dates with Report Start /End Dates
**For Validating the dates by comparing
**Dates selection with Task Start Dates and Task End Dates
      v_temp_value = i_taskassignment-work_effort.
      IF i_dpr_bupa_link_final1-beg_tmstmp_eng > p_begdt.
        IF i_dpr_bupa_link_final1-beg_tmstmp_eng > p_enddt.
          CONTINUE.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng > p_enddt.
          v_days_total = p_enddt - i_dpr_bupa_link_final1-beg_tmstmp_eng.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng < p_enddt.
          v_days_total = i_dpr_bupa_link_final1-end_tmstmp_eng - i_dpr_bupa_link_final1-beg_tmstmp_eng.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng = p_enddt.
          v_days_total = i_dpr_bupa_link_final1-end_tmstmp_eng - i_dpr_bupa_link_final1-beg_tmstmp_eng.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ENDIF.
      ELSEIF i_dpr_bupa_link_final1-beg_tmstmp_eng < p_begdt.
        IF i_dpr_bupa_link_final1-end_tmstmp_eng < p_begdt.
          CONTINUE.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng > p_enddt.
          v_days_total = p_enddt - p_begdt.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng < p_enddt.
          v_days_total = i_dpr_bupa_link_final1-end_tmstmp_eng - p_begdt.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng = p_enddt.
          v_days_total = p_enddt - p_begdt.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ENDIF.
      ELSEIF i_dpr_bupa_link_final1-beg_tmstmp_eng = p_begdt.
        IF i_dpr_bupa_link_final1-end_tmstmp_eng > p_enddt.
          v_days_total = p_enddt - i_dpr_bupa_link_final1-beg_tmstmp_eng.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng < p_enddt.
          v_days_total = i_dpr_bupa_link_final1-end_tmstmp_eng - i_dpr_bupa_link_final1-beg_tmstmp_eng.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ELSEIF i_dpr_bupa_link_final1-end_tmstmp_eng = p_enddt.
          v_days_total = p_enddt - p_begdt.
          v_days_total = v_days_total + 1 .
          IF v_days_total EQ '0.00'.
            v_days_total = '1.00'.
          ENDIF.
          IF v_temp_value LE v_days_total.
            i_dpr_bupa_link_final1-days_total = v_temp_value.
          ELSE.
            i_dpr_bupa_link_final1-days_total = v_days_total.
          ENDIF.
          i_dpr_bupa_link_final1-flag = 'X'.
        ENDIF.
      ENDIF.
      READ TABLE i_taskdetail WITH KEY
                 participant_guid = i_taskassignment-participant_guid
                 entity_guid      = i_taskassignment-entity_guid.
      IF sy-subrc = 0.
        i_dpr_bupa_link_final1-task_type   = i_taskdetail-task_type_text.
        i_dpr_bupa_link_final1-task_name   = i_taskdetail-task_name.
        i_dpr_bupa_link_final1-task_number = i_taskdetail-task_number.
        i_dpr_bupa_link_final1-task_desc   = i_taskdetail-task_desc.
      ENDIF.
      APPEND i_dpr_bupa_link_final1.
      CLEAR : i_dpr_bupa_link_final1.
    ELSE.
      MOVE-CORRESPONDING i_dpr_bupa_link_final TO i_dpr_bupa_link_final1.
      APPEND i_dpr_bupa_link_final1.
      CLEAR : i_dpr_bupa_link_final1, v_beg_date, v_end_date, v_beg_timestamp, v_end_timestamp.
    ENDIF.
    CLEAR : v_beg_date, v_end_date, v_beg_timestamp, v_end_timestamp.
    CLEAR : v_temp_value, v_days_total.
  ENDLOOP.
  CLEAR : i_dpr_bupa_link_final1.
  SORT i_dpr_bupa_link_final1 BY pernr.
  IF NOT r_bpnum[] IS INITIAL.
    LOOP AT i_dpr_bupa_link_final1.
      IF i_dpr_bupa_link_final1-pernr IN r_bpnum.
        CONTINUE.
      ELSE.
        DELETE i_dpr_bupa_link_final1 INDEX sy-tabix.
      ENDIF.
    ENDLOOP.
    CLEAR : i_dpr_bupa_link_final1.
  ENDIF.
ENDFORM.                    " FILTER_RECORDS
*&---------------------------------------------------------------------*
*&      Form  BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
FORM build_fieldcatalog .
  fieldcatalog-fieldname   = 'DUMMY'.
  fieldcatalog-col_pos     = 1.
  fieldcatalog-edit        = 'X'.
  fieldcatalog-no_out      = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'NAME_FIRST'.
  fieldcatalog-seltext_m   = 'First Name'.
  fieldcatalog-col_pos     = 2.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'NAME_LAST'.
  fieldcatalog-seltext_m   = 'Last Name'.
  fieldcatalog-col_pos     = 3.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'LIFNR'.
  fieldcatalog-seltext_m   = 'Vendor Number'.
  fieldcatalog-col_pos     = 4.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'OBJECT_KEY'.
  fieldcatalog-seltext_m   = 'Purchase Order'.
  fieldcatalog-col_pos     = 5.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'TEXT1'.
  fieldcatalog-seltext_m   = 'Project Name'.
  fieldcatalog-col_pos     = 6.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'WORK_EFFORT'.
  fieldcatalog-seltext_m   = 'Task Work Effort'.
  fieldcatalog-col_pos     = 7.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'WORK_UNIT'.
  fieldcatalog-seltext_m   = 'Task Work Unit'.
  fieldcatalog-col_pos     = 8.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'BEG_TMSTMP_ENG'.
  fieldcatalog-seltext_m   = 'Task Begin Date'.
  fieldcatalog-col_pos     = 9.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'END_TMSTMP_ENG'.
  fieldcatalog-seltext_m   = 'Task End Date'.
  fieldcatalog-col_pos     = 10.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'PROJECT_ID'.
  fieldcatalog-seltext_m   = 'Internal Order'.
  fieldcatalog-col_pos     = 11.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'ACTUALSTART'.
  fieldcatalog-seltext_l   = 'Project Actual Start Date'.
  fieldcatalog-col_pos     = 12.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.

  fieldcatalog-fieldname   = 'ACTUALFINISH'.
  fieldcatalog-seltext_l   = 'Project Actual Finish Date'.
  fieldcatalog-col_pos     = 13.
  fieldcatalog-emphasize   = 'X'.
  APPEND fieldcatalog TO fieldcatalog.
  CLEAR  fieldcatalog.
ENDFORM.                    " BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*&      Form  BUILD_LAYOUT
*&---------------------------------------------------------------------*
FORM build_layout .
  gd_layout-no_input          = 'X'.
  gd_layout-colwidth_optimize = 'X'.
  gd_layout-zebra             = 'X'.
  gd_layout-header_text       = 'DETAIL ACTIVITY REPORT'.
ENDFORM.                    " BUILD_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
FORM display_alv_report .
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program = sy-repid
      is_layout          = gd_layout
      it_fieldcat        = fieldcatalog[]
      i_save             = 'X'
    TABLES
      t_outtab           = i_dpr_bupa_link_final1
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    " DISPLAY_ALV_REPORT
*&---------------------------------------------------------------------*
*&      Form  EXCEL_SHEET_APPLICATION
*&---------------------------------------------------------------------*
FORM excel_sheet_application .
  DATA : v_name TYPE char80,
         v_participant_guid TYPE dpr_tv_participant_guid,
         v_index TYPE sy-tabix,
         v_times TYPE i,
         v_effortvalue(11) TYPE c,
         v_effortvalue1(4) TYPE n,
         v_pernr_old       TYPE personid,
         v_pernr_new       TYPE personid,
         v_length(4)  TYPE c.
  DATA : return(255)  TYPE c,
         return1(128) TYPE c,
         type         TYPE i,
         return_file  TYPE string,
         v_email(128) TYPE c.
  DATA : p_file       TYPE localfile.

**TO DETERMINE THE CURRENT USERNAME DESKTOP
**PATH FOR CREATING FOLDER IN HIS SYSTEM.
  LOOP AT i_dpr_bupa_link_final1.
    v_pernr            = i_dpr_bupa_link_final1-pernr.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      i_dpr_bupa_link_final1-bpkind = v_bpkind1.
      MODIFY i_dpr_bupa_link_final1
             INDEX sy-tabix
             TRANSPORTING bpkind.
    ELSE.
      DELETE i_dpr_bupa_link_final1 INDEX sy-tabix.
    ENDIF.
    CLEAR : v_bpkind, v_bpkind1, v_businesspartner, v_pernr.
  ENDLOOP.
  i_dpr_bupa_link_final2[] =  i_dpr_bupa_link_final1[].
  SORT i_dpr_bupa_link_final2 BY participant_guid.
  DELETE ADJACENT DUPLICATES FROM i_dpr_bupa_link_final2 COMPARING participant_guid.
  type = '00000000012'.
  CALL FUNCTION 'GUI_GET_DESKTOP_INFO'
    EXPORTING
      type   = type
    CHANGING
      return = return.

  CONCATENATE return '\DAR_' sy-datum '_' sy-uzeit INTO return.
  return1 = return.
  CALL FUNCTION 'GUI_CREATE_DIRECTORY'
    EXPORTING
      dirname = return1
    EXCEPTIONS
      failed  = 1
      OTHERS  = 2.

  return = return1.

  LOOP AT i_dpr_bupa_link_final2.
    v_skipflag = 0.
    v_index = sy-tabix.
    v_pernr            = i_dpr_bupa_link_final2-pernr.
    v_participant_guid = i_dpr_bupa_link_final2-participant_guid.
    v_int_order        = i_dpr_bupa_link_final2-project_id.
    v_bpkind2          = i_dpr_bupa_link_final2-bpkind.
*--Forming sheet name
    gv_index = sy-index .
    gv_outer_index = sy-index .
    gv_sheet_name = 'Detail Activity Report'.
***For email checking for individual PERNR
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    wa_bapibus1006_head-bpartner = v_businesspartner.
    REFRESH : wa_bapiadsmtp.
    CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
      EXPORTING
        businesspartner = wa_bapibus1006_head-bpartner
        valid_date      = sy-datum
      TABLES
        bapiadsmtp      = wa_bapiadsmtp.
    IF wa_bapiadsmtp[] IS INITIAL.
      v_skipflag = 1.
    ELSE.
      REFRESH : wa_bapiadsmtp.
    ENDIF.

    LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
      IF
*         i_dpr_bupa_link_final1-lifnr      IS INITIAL OR
*         i_dpr_bupa_link_final1-name       IS INITIAL OR
         i_dpr_bupa_link_final1-pernr      IS INITIAL OR
         i_dpr_bupa_link_final1-project_id IS INITIAL OR
         i_dpr_bupa_link_final1-proj_name  IS INITIAL OR
         i_dpr_bupa_link_final1-name_pm    IS INITIAL OR
*         i_dpr_bupa_link_final1-object_key IS INITIAL OR
         i_dpr_bupa_link_final1-proj_desc  IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last INTO v_name SEPARATED BY space.
      IF v_name IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-object_key IS INITIAL AND
         i_dpr_bupa_link_final1-bpkind EQ 'DSR_ICDR'.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-task_name      IS INITIAL OR
         i_dpr_bupa_link_final1-task_desc      IS INITIAL OR
         i_dpr_bupa_link_final1-task_type      IS INITIAL OR
         i_dpr_bupa_link_final1-role_text      IS INITIAL OR
         i_dpr_bupa_link_final1-beg_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-end_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-work_effort    IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CLEAR : v_name.
    ENDLOOP.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
        EXPORTING
          sap_variant = v_bpkind1
          sap_pernr   = v_pernr
          beg_date    = p_begdt
          end_date    = p_enddt
        TABLES
          sap_icatsw  = i_etworklist.
    ENDIF.
    DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
    CLEAR : v_bpkind, v_bpkind1.
    IF i_etworklist[] IS INITIAL.
      v_skipflag = 1.
    ENDIF.

    IF v_skipflag = 0.
*--For the first loop, Excel is initiated and one new sheet is added
      CREATE OBJECT gs_excel 'EXCEL.APPLICATION' .
      GET PROPERTY OF gs_excel 'Visible' = v_vis.
* Set this property to open excel in background
      SET PROPERTY OF gs_excel 'Visible' = 'False' .
      GET PROPERTY OF gs_excel 'Workbooks' = gs_wbooklist .
      GET PROPERTY OF gs_wbooklist 'Application' = gs_application .
      SET PROPERTY OF gs_application 'SheetsInNewWorkbook' = 1 .
      CALL METHOD OF
          gs_wbooklist
          'Add'        = gs_wbook.
      GET PROPERTY OF gs_application 'ActiveSheet' = gs_activesheet .
      GET PROPERTY OF gs_excel 'ActiveWorkbook' = g_workbook.
      SET PROPERTY OF gs_activesheet 'Name' = gv_sheet_name .
      GET PROPERTY OF gs_activesheet 'Cells' = gs_cells.
      GET PROPERTY OF gs_cells 'Font' = gs_font .
      SET PROPERTY OF gs_font 'Name' = 'Arial' .
      SET PROPERTY OF gs_font 'Size' = '10' .
      gv_line_cntr = 1 . "line counter
*--Title
*--Selecting cell area to be merged.
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell1
        EXPORTING
          #1       = 1
          #2       = 1.
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell2
        EXPORTING
          #1       = 1
          #2       = 15.
      CALL METHOD OF
          gs_excel
          'Range'  = gs_cells
        EXPORTING
          #1       = gs_cell1
          #2       = gs_cell2.
      CALL METHOD OF
          gs_cells
          'Select'.
*--Merging
      CALL METHOD OF
          gs_cells
          'Merge'.
*--Setting title data
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell1
        EXPORTING
          #1       = gv_line_cntr
          #2       = 1.
      SET PROPERTY OF gs_cells 'Value' = 'DETAIL ACTIVITY REPORT' .
*--Formatting the title
      GET PROPERTY OF gs_cells 'Font' = gs_font .
      SET PROPERTY OF gs_font 'Name' = 'Arial' .
      SET PROPERTY OF gs_font 'Size' = '12' .
      SET PROPERTY OF gs_font 'Underline' = 2 .
      SET PROPERTY OF gs_font 'Bold' = 1 .
      SET PROPERTY OF gs_cells 'HorizontalAlignment' = -4108 .
      GET PROPERTY OF gs_cells 'Interior' = gs_interior .
      SET PROPERTY OF gs_interior 'Color' = '10092543' .
      CALL METHOD OF
          gs_cells
          'BorderAround'

        EXPORTING
          #1             = 1 "continuous line
          #2             = 2. "thick
      SET PROPERTY OF gs_cells 'Locked' = 1.
      gv_line_cntr = gv_line_cntr + 2 .
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
        ON CHANGE OF i_dpr_bupa_link_final1-participant_guid.
          PERFORM header_data_display.
          PERFORM line_title_display.
          w_proid = i_dpr_bupa_link_final1-project_id.
          v_flag = 1.
        ENDON.
        IF v_flag = 1.
          v_flag = 0.
          CONTINUE.
        ENDIF.
        PERFORM line_item_display.
      ENDLOOP.
**Code Closed by LZ16662
**FOR DISPLAYING CATSWORKLIST DETAILS
**IN EXCEL SHEET
**CONSTANTS VALUE FOR ACTIVITY NUMBER BASED ON SYSTEM
*      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
*      SELECT SINGLE bpkind
*             FROM but000
*             INTO v_bpkind
*             WHERE partner = v_businesspartner.
*      CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
*      IF NOT v_bpkind IS INITIAL.
*        CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
*          EXPORTING
*            sap_variant = v_bpkind1
*            sap_pernr   = v_pernr
*            beg_date    = p_begdt
*            end_date    = p_enddt
*          TABLES
*            sap_icatsw  = i_etworklist.
*      ENDIF.
*      DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
*      CLEAR : v_int_order, v_bpkind.
**Code Closed by LZ16662
      gv_line_cntr = gv_line_cntr_1.
      gv_line_cntr = gv_line_cntr + 2 .

**FOR DISPLAYING COLOMN NAMES FOR CATSWORKLIST
      PERFORM cats_header_data.
**FOR DISPLAYING LINE ITEM DETAILS FOR CATSWORKLIST
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid
                                       AND flag EQ 'X'.
*        v_times = i_dpr_bupa_link_final1-days_total.
        v_temp_value = i_dpr_bupa_link_final1-days_total.          "work_effort.
        v_temp_value = ceil( v_temp_value ).
        v_effortvalue = v_temp_value.
        v_length = strlen( v_effortvalue ).
        v_length = v_length - 3.
        v_effortvalue = v_effortvalue+0(v_length).
        SHIFT v_effortvalue LEFT DELETING LEADING space.
        MOVE v_effortvalue TO v_effortvalue1.
        IF  v_effortvalue1 LE v_datediff.
          v_times = v_effortvalue1.
        ELSEIF v_effortvalue1 GT v_datediff.
          v_times = v_datediff.
        ENDIF.
        READ TABLE i_etworklist WITH KEY zzcpr_objgextid = i_dpr_bupa_link_final1-task_number.
        IF sy-subrc = 0.
          DO v_times TIMES.
            gv_line_cntr = gv_line_cntr + 1.
            PERFORM cats_line_data.
          ENDDO.
        ENDIF.
        CLEAR : v_effortvalue, v_length, v_times, v_effortvalue1, v_temp_value.
      ENDLOOP.
      CLEAR : v_bpkind2.
      PERFORM note_condition.
*      LOOP AT i_etworklist WHERE sebeln NE space.
*        gv_line_cntr = gv_line_cntr + 1.
*        PERFORM cats_line_data.
*      ENDLOOP.
*      SET PROPERTY OF gs_activesheet 'PROTECT' = 1.
      CALL METHOD OF
          gs_activesheet
          'PROTECT'

        EXPORTING
          #1             = 'dsr123##$'.
      CALL METHOD OF
          g_workbook
          'PROTECT'

        EXPORTING
          #1         = 'dsr123##$'.
      REFRESH : i_etworklist.
*    SET PROPERTY OF gs_activesheet 'PROTECT' = 1. "Protect sheet
**TO STORE THE EXCEL FILE FOR DIFFERENT PERSONNEL NUMBER
**TO STORE THE SAME IN CREATED DIRECTORY
*      CONCATENATE i_dpr_bupa_link_final2-name_first i_dpr_bupa_link_final2-name_last INTO v_save_name SEPARATED BY space.
      CONCATENATE i_dpr_bupa_link_final2-role_text '-' INTO v_save_name.
      return_file = return.
      CONCATENATE return '\'  i_dpr_bupa_link_final2-project_id '' v_pernr ''
                  v_save_name  sy-datum '-' sy-uzeit '.xls' INTO return_file.
      CALL METHOD OF
          gs_wbook
          'SaveAs'

        EXPORTING
          #1       = return_file.
*    SET PROPERTY OF gs_excel 'DisplayAlerts' = 0.
      PERFORM free_objects.
      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
      wa_bapibus1006_head-bpartner = v_businesspartner.

      CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
        EXPORTING
          businesspartner = wa_bapibus1006_head-bpartner
          valid_date      = sy-datum
        TABLES
          bapiadsmtp      = wa_bapiadsmtp.
      IF NOT wa_bapiadsmtp[] IS INITIAL.
        READ TABLE wa_bapiadsmtp INDEX 1.

        IF sy-subrc = 0.
          v_email = wa_bapiadsmtp-e_mail.
          w_pernr = v_pernr.
          w_begdt = v_datebeg1.
          w_enddt = v_dateend1.
**EMAILING AN ATTACHMENT TO SAPUSER INBOX
          PERFORM emailing_document USING return_file
                                          v_email
                                          w_pernr
                                          w_proid
                                          w_begdt
                                          w_enddt.
          i_output-bpartner = v_businesspartner.
          i_output-mail     = v_email.
          i_output-status   = 'Sucessfully Mailed the Document'.
          APPEND i_output.
          CLEAR : i_output.
          v_sucess = v_sucess + 1.
        ELSE.
          i_output-bpartner = v_businesspartner.
          i_output-status   = 'Email Address not Maintained'.
          APPEND i_output.
          CLEAR : i_output.
          v_failure = v_failure + 1.
        ENDIF.
      ENDIF.
    ENDIF.
    CLEAR : v_participant_guid, v_pernr, return_file,
            v_businesspartner, wa_bapiadsmtp, wa_bapibus1006_head, v_email, w_proid, w_pernr, w_begdt, w_enddt,
            ws_pernr, ws_proid, ws_begdt, ws_enddt, v_times, v_save_name, return1.
    REFRESH : i_etworklist.
  ENDLOOP.

  LOOP AT i_output WHERE mail NE space.
    v_status1 = 1.
  ENDLOOP.
  LOOP AT i_output WHERE mail EQ space.
    v_status2 = 1.
  ENDLOOP.
  IF v_status1 = 1.
    WRITE : / 'Date   :', sy-datum.
    WRITE : / 'Time   :', sy-uzeit.
    WRITE : / 'Result :', v_sucess , 'Record''s mailed sucessfully'.
    WRITE : / sy-uline.
    WRITE : / sy-vline , AT 2 'BUSINESS PARTNER' CENTERED INTENSIFIED COLOR 4, AT 20 sy-vline,
            AT 30 'EMAIL-ID' CENTERED INTENSIFIED COLOR 4 , AT 125 sy-vline,
            AT 126 'STATUS' CENTERED INTENSIFIED COLOR 4, AT 179 sy-vline.
    WRITE : / sy-uline.
    LOOP AT i_output WHERE mail NE space.
      WRITE : / sy-vline, i_output-bpartner CENTERED INTENSIFIED COLOR 2, AT 20 sy-vline,
                AT 21  i_output-mail LEFT-JUSTIFIED INTENSIFIED COLOR 2, AT 125 sy-vline,
                AT 126 i_output-status LEFT-JUSTIFIED INTENSIFIED COLOR 5, AT 179 sy-vline.
      WRITE : / sy-uline.
    ENDLOOP.
  ENDIF.
  IF v_status2 = 1.

    WRITE : / 'Result :', v_failure , 'Record''s mailed unsucessfully'.
    WRITE : / sy-uline.
    WRITE : / sy-vline , AT 2 'BUSINESS PARTNER' CENTERED INTENSIFIED COLOR 4, sy-vline,
            AT 30 'EMAIL-ID' CENTERED INTENSIFIED COLOR 4 , AT 125 sy-vline,
            AT 126 'STATUS' CENTERED INTENSIFIED COLOR 4, AT 179 sy-vline.
    WRITE : / sy-uline.
    LOOP AT i_output WHERE mail EQ space.
      WRITE : / sy-vline, i_output-bpartner CENTERED INTENSIFIED COLOR 2, AT 20 sy-vline,
                AT 21 i_output-mail LEFT-JUSTIFIED INTENSIFIED COLOR 2, AT 125 sy-vline,
                AT 126 i_output-status LEFT-JUSTIFIED INTENSIFIED COLOR 6, AT 179 sy-vline.
      WRITE : / sy-uline.
    ENDLOOP.
  ENDIF.
*  MESSAGE ID 'YGF_ABR20640' TYPE 'I' NUMBER '002'
*              WITH v_index.
ENDFORM.                    " EXCEL_SHEET_APPLICATION
*&---------------------------------------------------------------------*
*&      Form  HEADER_DATA_DISPLAY
*&---------------------------------------------------------------------*
FORM header_data_display.
**To Fill LIFNR Vendor Title and Number
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
**--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Vendor Number'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
*--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.

  IF NOT i_dpr_bupa_link_final1-lifnr IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-lifnr.
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = 'Not Applicable for FSEs'.
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill NAME Vendor Title and Name
  gv_line_cntr = gv_line_cntr + 1 .     "Header Counter
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Vendor Name'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  IF NOT i_dpr_bupa_link_final1-name IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-name.
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = 'Not Applicable for FSEs'.
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill PERNR Title and Number
  gv_line_cntr = gv_line_cntr + 1 .     "Header Counter
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Personnel Number'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-pernr.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill project_id Title and Number
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Internal Order'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-project_id.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill Project Name
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Project Name'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-proj_name.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill Project Manager Name
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Project Manager'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-name_pm.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**To Fill Firstname and Lastename
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Resource Name'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last INTO v_name SEPARATED BY space.
  SET PROPERTY OF gs_cell1 'Value' = v_name.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CLEAR : v_name.
**To Fill Purchase Order
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Purchase Order'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  IF NOT i_dpr_bupa_link_final1-object_key IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-object_key .
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = 'Not Applicable for FSEs'.
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**Project Description
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Project Description'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-proj_desc .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**Report Start Date
  v_begyear1 = p_begdt+0(4).
  v_begmnt1  = p_begdt+4(2).
  v_begday1  = p_begdt+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_begmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_begday1 v_month_name v_begyear1 INTO v_begindate SEPARATED BY '-'.
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Report Start Date'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_begindate.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
**Report End Date
  v_endyear1 = p_enddt+0(4).
  v_endmnt1  = p_enddt+4(2).
  v_endday1  = p_enddt+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_endmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_endday1 v_month_name v_endyear1 INTO v_enddate1 SEPARATED BY '-'.
  gv_line_cntr = gv_line_cntr + 1 .
*--Writing data
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Report End Date'.
  SET PROPERTY OF gs_cells 'Locked' = 1.
  GET PROPERTY OF gs_cells 'Font' = gs_font .
  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
*  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_enddate1.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  gv_line_cntr = gv_line_cntr + 2.         "Line Item Counter
ENDFORM.                    " HEADER_DATA_DISPLAY
*&---------------------------------------------------------------------*
*&      Form  line_title_DISPLAY
*&---------------------------------------------------------------------*
FORM line_title_display.
*----------------------------------------------------------------------*
*    TASK NAME                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 2.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'TASK NAME' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  gv_line_cntr_1 = gv_line_cntr.
  gv_line_cntr_1 = gv_line_cntr_1 + 1.
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 1.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 2.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_name .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick

*----------------------------------------------------------------------*
*    TASK DESCRIPTION                                                  *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 4.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'TASK DESCRIPTION' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 2.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 4.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_desc .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '30' .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    TASK TYPE                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 3.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 6.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'TASK TYPE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*1ST LINE OF TASK TYPE-SATYAJIT
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 3.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 6.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_type .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ROLE TYPE                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 4.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 8.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ROLE TYPE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 4.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 8.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-role_text .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '15' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ASSIGNMENT START DATE                                             *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 5.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 11.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ASSIGNMENT START DATE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '23' .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CLEAR : v_begyear1, v_begmnt1, v_begday1, v_begindate.
  v_begyear1 = i_dpr_bupa_link_final1-beg_tmstmp_eng+0(4).
  v_begmnt1  = i_dpr_bupa_link_final1-beg_tmstmp_eng+4(2).
  v_begday1  = i_dpr_bupa_link_final1-beg_tmstmp_eng+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_begmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_begday1 v_month_name v_begyear1 INTO v_begindate SEPARATED BY '-'.
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 5.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 11.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_begindate .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '23' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ASSIGNMENT END DATE                                               *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 6.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 13.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ASSIGNMENT END DATE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '23' .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CLEAR : v_endyear1, v_endmnt1, v_endday1, v_enddate1.
  v_endyear1 = i_dpr_bupa_link_final1-end_tmstmp_eng+0(4).
  v_endmnt1  = i_dpr_bupa_link_final1-end_tmstmp_eng+4(2).
  v_endday1  = i_dpr_bupa_link_final1-end_tmstmp_eng+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_endmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_endday1 v_month_name v_endyear1 INTO v_enddate1 SEPARATED BY '-'.
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 6.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 13.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_enddate1 .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '23' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ALLOCATED WORK EFFORTS                                            *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 7.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 16.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ALLOCATED DAYS' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 7.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 16.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-work_effort .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
ENDFORM.                                 "line_title_DISPLAY
*&---------------------------------------------------------------------*
*&      Form  LINE_ITEM_DISPLAY
*&---------------------------------------------------------------------*
FORM line_item_display.
  gv_line_cntr_1 = gv_line_cntr_1 + 1.
*----------------------------------------------------------------------*
*    TASK NAME                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 1.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 2.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_name .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    TASK DESCRIPTION                                                  *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 2.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 4.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_desc .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '30' .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    TASK TYPE                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 3.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 6.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-task_type .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '15' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ROLE TYPE                                                         *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 4.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 8.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-role_text .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '15' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ASSIGNMENT START DATE                                             *
*----------------------------------------------------------------------*
  CLEAR : v_begyear1, v_begmnt1, v_begday1, v_begindate.
  v_begyear1 = i_dpr_bupa_link_final1-beg_tmstmp_eng+0(4).
  v_begmnt1  = i_dpr_bupa_link_final1-beg_tmstmp_eng+4(2).
  v_begday1  = i_dpr_bupa_link_final1-beg_tmstmp_eng+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_begmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_begday1 v_month_name v_begyear1 INTO v_begindate SEPARATED BY '-'.
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 5.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 11.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_begindate .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '19' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ASSIGNMENT END DATE                                               *
*----------------------------------------------------------------------*
  CLEAR : v_endyear1, v_endmnt1, v_endday1, v_enddate1.
  v_endyear1 = i_dpr_bupa_link_final1-end_tmstmp_eng+0(4).
  v_endmnt1  = i_dpr_bupa_link_final1-end_tmstmp_eng+4(2).
  v_endday1  = i_dpr_bupa_link_final1-end_tmstmp_eng+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_endmnt1.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_endday1 v_month_name v_endyear1 INTO v_enddate1 SEPARATED BY '-'.
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 6.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 13.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = v_enddate1 .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '19' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*    ALLOCATED WORK EFFORTS                                            *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr_1
      #2       = 7.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr_1
*    #2 = 16.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final1-work_effort .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
ENDFORM.                         "LINE_ITEM_DISPLAY
*&---------------------------------------------------------------------*
*&      Form  CATS_HEADER_DATA
*&---------------------------------------------------------------------*
FORM cats_header_data .
*----------------------------------------------------------------------*
* TASK ID                                                              *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 2.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'TASK ID' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
* TASK NAME                                                            *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 4.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'TASK NAME' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  WORK DATE                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 3.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 6.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'WORK DATE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  DAYS                                                                *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 4.
  SET PROPERTY OF gs_cell1 'Value' = 'DAYS' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  ROLE TYPE                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 5.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 9.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ROLE TYPE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  UOM                                                                 *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 6.
  SET PROPERTY OF gs_cell1 'Value' = 'UOM' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  DATA ENTRY PROFILE                                                  *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 7.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 13.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'DATA ENTRY PROFILE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '24' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  PERSONNEL NUMBER                                                    *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 8.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 16.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'PERSONNEL NUMBER' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  INTERNAL ORDER                                                      *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 9.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 18.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'INTERNAL ORDER' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  ACTIVITY TYPE                                                       *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 10.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 20.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ACTIVITY TYPE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  SENDER COST CENTER                                                  *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 11.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 23.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'SENDER COST CENTRE' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '29' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  PURCHASE ORDER                                                      *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 12.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 25.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'PURCHASE ORDER' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '20' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  LINE ITEM                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 13.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 27.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'LINE ITEM' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '14' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  PROJECT ID                                                          *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 14.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 29.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'PROJECT ID' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '16' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  ACTIVITY NUMBER (Service Master)                                    *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 15.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 32.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = 'ACTIVITY NUMBER (Service Master)' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 1 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '10092543' .
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '45'.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
ENDFORM.                    " CATS_HEADER_DATA
*&---------------------------------------------------------------------*
*&      Form  CATS_LINE_DATA
*&---------------------------------------------------------------------*
FORM cats_line_data .
  DATA : v_task_id    TYPE char25,
         v_lstnr1(18) TYPE c,
         v_lstnr(19)  TYPE c.
*----------------------------------------------------------------------*
*  TASK ID                                                             *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 2.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  v_task_id = i_etworklist-zzcpr_objgextid.
  CONCATENATE '''' v_task_id INTO v_task_id.
  SET PROPERTY OF gs_cell1 'Value' = v_task_id.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
  SET PROPERTY OF gs_cell1 'ColumnWidth' = '22' .
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CLEAR : v_task_id.
*----------------------------------------------------------------------*
*  TASK NAME                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 2.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 4.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  READ TABLE i_dpr_bupa_link_final1 WITH KEY task_number = i_etworklist-zzcpr_objgextid.
  SET PROPERTY OF gs_cell1 'Value' =  i_dpr_bupa_link_final1-task_name.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  WORK DATE                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 3.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 6.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'NumberFormat' = '[$-409]d-mmm-yyyy;@'.
  SET PROPERTY OF gs_cell1 'Value' = ' ' .
  GET PROPERTY OF gs_cell1 'AddComment' = gs_comment .
  CALL METHOD OF
      gs_comment
      'Text'

    EXPORTING
      #1         = 'Enter Date Format in DD-MMM-YYYY'.
  SET PROPERTY OF gs_cell1 'Locked' = 0 .
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '65280' .
  SET PROPERTY OF gs_cell1 'WrapText' = 1.
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  DAYS                                                                *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 4.
  SET PROPERTY OF gs_cell1 'NumberFormat' = '0.000'.
  SET PROPERTY OF gs_cell1 'Value' = '0.000' .
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  GET PROPERTY OF gs_cell1 'Interior' = gs_interior .
  SET PROPERTY OF gs_interior 'Color' = '65280' .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  SET PROPERTY OF gs_cell1 'Locked' = 0 .
*----------------------------------------------------------------------*
*  ROLE TYPE                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 5.
**--Merging
  SET PROPERTY OF gs_cell1 'Value' = i_dpr_bupa_link_final2-role_text .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  UNIT OF MEASUREMENT                                                 *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 6.
  SET PROPERTY OF gs_cell1 'Value' = 'DA' .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
* DATA ENTRY PROFILE                                                   *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 7.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 13.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  IF v_bpkind2 EQ 'DSR_ICDR'.
    SET PROPERTY OF gs_cell1 'Value' = 'DSR_BICD' .
  ELSEIF v_bpkind2 EQ 'DSR_FSE'.
    SET PROPERTY OF gs_cell1 'Value' = 'DSR_BFSE' .
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
* PERSONNAL NUMBER                                                     *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 8.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 16.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = v_pernr .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  INTERNAL ORDER                                                      *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 9.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 18.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  IF i_etworklist-raufnr IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = ' ' .
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = i_etworklist-raufnr .
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  ACTIVITY TYPE                                                       *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 10.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 20.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  IF i_etworklist-lstar IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = ' ' .
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = i_etworklist-lstar .
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1 .
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  SENDER COST CENTRE                                                  *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 11.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 23.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  IF i_etworklist-skostl IS INITIAL.
    SET PROPERTY OF gs_cell1 'Value' = ' ' .
  ELSE.
    SET PROPERTY OF gs_cell1 'Value' = i_etworklist-skostl .
  ENDIF.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  PURCHASE ORDER                                                      *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 12.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 25.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
*  read table i_dpr_bupa_link_final1 key
  SET PROPERTY OF gs_cell1 'Value' = i_etworklist-sebeln.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  LINE ITEM                                                           *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 13.
* CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 27.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_etworklist-sebelp.
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  PROJECT ID                                                          *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 14.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 29.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  SET PROPERTY OF gs_cell1 'Value' = i_etworklist-zzcpr_extid .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
*----------------------------------------------------------------------*
*  ACTIVITY NUMBER                                                     *
*----------------------------------------------------------------------*
*--Title
*--Selecting cell area to be merged.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 15.
*  CALL METHOD OF gs_excel 'Cells' = gs_cell2
*    EXPORTING
*    #1 = gv_line_cntr
*    #2 = 32.
*  CALL METHOD OF gs_excel 'Range' = gs_cells
*    EXPORTING
*    #1 = gs_cell1
*    #2 = gs_cell2.
*  CALL METHOD OF gs_cells 'Select' .
**--Merging
*  CALL METHOD OF gs_cells 'Merge' .
  v_lstnr1 = i_etworklist-lstnr.
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = v_lstnr1
    IMPORTING
      output = v_lstnr1.
  CONCATENATE '''' v_lstnr1 INTO v_lstnr.
  SET PROPERTY OF gs_cell1 'Value' = v_lstnr .
  SET PROPERTY OF gs_cell1 'Locked' = 1.
**--Formatting the title
  GET PROPERTY OF gs_cell1 'Font' = gs_font .
*  SET PROPERTY OF gs_font 'Name' = 'Arial' .
*  SET PROPERTY OF gs_font 'Size' = '10' .
  SET PROPERTY OF gs_font 'Bold' = 0 .
  SET PROPERTY OF gs_cell1 'HorizontalAlignment' = -4108 .
  CALL METHOD OF
      gs_cell1
      'BorderAround'

    EXPORTING
      #1             = 1 "continuous line
      #2             = 2. "thick
  CLEAR : v_lstnr, v_lstnr1.
ENDFORM.                    " CATS_LINE_DATA
*&---------------------------------------------------------------------*
*&      Form  EMAILING_DOCUMENT
*&---------------------------------------------------------------------*
FORM emailing_document USING return_file
                             v_email
                             w_pernr
                             w_proid
                             w_begdt
                             w_enddt.

  ws_file  = return_file.
  ws_email = v_email.
  ws_pernr = w_pernr.
  ws_proid = w_proid.
  ws_begdt = w_begdt.
  ws_enddt = w_enddt.

  PERFORM bdc_dynpro      USING 'YGS_SEND_EXTERNAL_MAIL' '1000'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'WS_FILE'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=ONLI'.
  PERFORM bdc_field       USING 'WS_FILE'
                                 ws_file.
  PERFORM bdc_field       USING 'WS_EMAIL'
                                 ws_email.
  PERFORM bdc_field       USING 'WS_PERNR'
                                 ws_pernr.
  PERFORM bdc_field       USING 'WS_PROID'
                                 ws_proid.
  PERFORM bdc_field       USING 'WS_BEGDT'
                                 ws_begdt.
  PERFORM bdc_field       USING 'WS_ENDDT'
                                 ws_enddt.
  PERFORM bdc_dynpro      USING 'SAPLSO04' '1000'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=ENTR'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'SOS04-L_ADR_NAME(01)'.
  PERFORM bdc_field       USING 'SOS04-L_ADR_NAME(01)'
                                 v_email.
  PERFORM bdc_dynpro      USING 'SAPLSO04' '1000'.
  PERFORM bdc_field       USING 'BDC_OKCODE'
                                '=SEND'.
  PERFORM bdc_field       USING 'BDC_CURSOR'
                                'SOS04-L_ADR_NAME(01)'.
  CALL TRANSACTION 'YG_EMAIL' USING bdcdata
                              MODE   'N'
                              UPDATE 'S'.
  REFRESH : bdcdata.
ENDFORM.                    " EMAILING_DOCUMENT
*----------------------------------------------------------------------*
*        Start new screen                                              *
*----------------------------------------------------------------------*
FORM bdc_dynpro USING program dynpro.
  CLEAR bdcdata.
  bdcdata-program  = program.
  bdcdata-dynpro   = dynpro.
  bdcdata-dynbegin = 'X'.
  APPEND bdcdata.
ENDFORM.                    "BDC_DYNPRO
*----------------------------------------------------------------------*
*        Insert field                                                  *
*----------------------------------------------------------------------*
FORM bdc_field USING fnam fval.
  CLEAR bdcdata.
  bdcdata-fnam = fnam.
  bdcdata-fval = fval.
  APPEND bdcdata.
ENDFORM.                    "BDC_FIELD
*&---------------------------------------------------------------------*
*&      Form  EXCEL_SHEET_MAIL_RECIPIENT
*&---------------------------------------------------------------------*
FORM excel_sheet_mail_recipient USING p_recp.
  DATA : v_name TYPE char80,
         v_participant_guid TYPE dpr_tv_participant_guid,
         v_index TYPE sy-tabix,
         v_times(4) TYPE c,
         v_effortvalue(11) TYPE c,
         v_effortvalue1(4) TYPE n,
         v_length(4)  TYPE c,
         v_mail(3)    TYPE c VALUE 0.
  DATA : return(255)  TYPE c,
         return1(128) TYPE c,
         type         TYPE i,
         return_file  TYPE string,
         v_email(128) TYPE c,
         v_recp(128)  TYPE c.
  DATA : p_file       TYPE localfile.

**TO DETERMINE THE CURRENT USERNAME DESKTOP
**PATH FOR CREATING FOLDER IN HIS SYSTEM.
  LOOP AT i_dpr_bupa_link_final1.
    v_pernr            = i_dpr_bupa_link_final1-pernr.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      i_dpr_bupa_link_final1-bpkind = v_bpkind1.
      MODIFY i_dpr_bupa_link_final1
             INDEX sy-tabix
             TRANSPORTING bpkind.
    ELSE.
      DELETE i_dpr_bupa_link_final1 INDEX sy-tabix.
    ENDIF.
    CLEAR : v_bpkind, v_bpkind1, v_businesspartner, v_pernr.
  ENDLOOP.
  i_dpr_bupa_link_final2[] =  i_dpr_bupa_link_final1[].
  SORT i_dpr_bupa_link_final2 BY participant_guid.
  DELETE ADJACENT DUPLICATES FROM i_dpr_bupa_link_final2 COMPARING participant_guid.
  type = '00000000012'.
  CALL FUNCTION 'GUI_GET_DESKTOP_INFO'
    EXPORTING
      type   = type
    CHANGING
      return = return.

  CONCATENATE return '\DAR_' sy-datum '_' sy-uzeit INTO return.
  return1 = return.
  CALL FUNCTION 'GUI_CREATE_DIRECTORY'
    EXPORTING
      dirname = return1
    EXCEPTIONS
      failed  = 1
      OTHERS  = 2.
  return = return1.
  LOOP AT i_dpr_bupa_link_final2.
    v_skipflag = 0.
    v_index = sy-tabix.
    v_pernr            = i_dpr_bupa_link_final2-pernr.
    v_participant_guid = i_dpr_bupa_link_final2-participant_guid.
    v_int_order        = i_dpr_bupa_link_final2-project_id.
    v_bpkind2          = i_dpr_bupa_link_final2-bpkind.
*--Forming sheet name
    gv_index = sy-index .
    gv_outer_index = sy-index .
    gv_sheet_name = 'Detail Activity Report'.

***For email checking for individual PERNR
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    wa_bapibus1006_head-bpartner = v_businesspartner.
    REFRESH : wa_bapiadsmtp.
    CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
      EXPORTING
        businesspartner = wa_bapibus1006_head-bpartner
        valid_date      = sy-datum
      TABLES
        bapiadsmtp      = wa_bapiadsmtp.
    IF wa_bapiadsmtp[] IS INITIAL.
      v_skipflag = 1.
    ELSE.
      REFRESH : wa_bapiadsmtp.
    ENDIF.

    LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
      IF
*         i_dpr_bupa_link_final1-lifnr      IS INITIAL OR
*         i_dpr_bupa_link_final1-name       IS INITIAL OR
         i_dpr_bupa_link_final1-pernr      IS INITIAL OR
         i_dpr_bupa_link_final1-project_id IS INITIAL OR
         i_dpr_bupa_link_final1-proj_name  IS INITIAL OR
         i_dpr_bupa_link_final1-name_pm    IS INITIAL OR
*         i_dpr_bupa_link_final1-object_key IS INITIAL OR
         i_dpr_bupa_link_final1-proj_desc  IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last INTO v_name SEPARATED BY space.
      IF v_name IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-object_key IS INITIAL AND
        i_dpr_bupa_link_final1-bpkind EQ 'DSR_ICDR'.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-task_name      IS INITIAL OR
         i_dpr_bupa_link_final1-task_desc      IS INITIAL OR
         i_dpr_bupa_link_final1-task_type      IS INITIAL OR
         i_dpr_bupa_link_final1-role_text      IS INITIAL OR
         i_dpr_bupa_link_final1-beg_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-end_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-work_effort    IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CLEAR : v_name.
    ENDLOOP.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
        EXPORTING
          sap_variant = v_bpkind1
          sap_pernr   = v_pernr
          beg_date    = p_begdt
          end_date    = p_enddt
        TABLES
          sap_icatsw  = i_etworklist.
    ENDIF.
    DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
    CLEAR : v_bpkind, v_bpkind1.
    IF i_etworklist[] IS INITIAL.
      v_skipflag = 1.
    ENDIF.

    IF v_skipflag = 0.
*--For the first loop, Excel is initiated and one new sheet is added
      CREATE OBJECT gs_excel 'EXCEL.APPLICATION' .
      GET PROPERTY OF gs_excel 'Visible' = v_vis.
*set this property to open excel in background
      SET PROPERTY OF gs_excel 'Visible' = 'False' .
      GET PROPERTY OF gs_excel 'Workbooks' = gs_wbooklist .
      GET PROPERTY OF gs_wbooklist 'Application' = gs_application .
      SET PROPERTY OF gs_application 'SheetsInNewWorkbook' = 1 .
      CALL METHOD OF
          gs_wbooklist
          'Add'        = gs_wbook.
      GET PROPERTY OF gs_application 'ActiveSheet' = gs_activesheet .
      GET PROPERTY OF gs_excel 'ActiveWorkbook' = g_workbook.
      SET PROPERTY OF gs_activesheet 'Name' = gv_sheet_name .
      GET PROPERTY OF gs_activesheet 'Cells' = gs_cells.
      GET PROPERTY OF gs_cells 'Font' = gs_font .
      SET PROPERTY OF gs_font 'Name' = 'Arial' .
      SET PROPERTY OF gs_font 'Size' = '10' .
      gv_line_cntr = 1 . "line counter
*--Title
*--Selecting cell area to be merged.
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell1
        EXPORTING
          #1       = 1
          #2       = 1.
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell2
        EXPORTING
          #1       = 1
          #2       = 15.
      CALL METHOD OF
          gs_excel
          'Range'  = gs_cells
        EXPORTING
          #1       = gs_cell1
          #2       = gs_cell2.
      CALL METHOD OF
          gs_cells
          'Select'.
*--Merging
      CALL METHOD OF
          gs_cells
          'Merge'.
*--Setting title data
      CALL METHOD OF
          gs_excel
          'Cells'  = gs_cell1
        EXPORTING
          #1       = gv_line_cntr
          #2       = 1.
      SET PROPERTY OF gs_cells 'Value' = 'DETAIL ACTIVITY REPORT' .
      SET PROPERTY OF gs_cells 'Locked' = 1.
      GET PROPERTY OF gs_cells 'Font' = gs_font .
      SET PROPERTY OF gs_font 'Name' = 'Arial' .
      SET PROPERTY OF gs_font 'Size' = '12' .
      SET PROPERTY OF gs_font 'Underline' = 2 .
      SET PROPERTY OF gs_font 'Bold' = 1 .
      SET PROPERTY OF gs_cells 'HorizontalAlignment' = -4108 .
      GET PROPERTY OF gs_cells 'Interior' = gs_interior .
      SET PROPERTY OF gs_interior 'Color' = '10092543' .
      CALL METHOD OF
          gs_cells
          'BorderAround'

        EXPORTING
          #1             = 1 "continuous line
          #2             = 2. "thick
**--Formatting the title
      gv_line_cntr = gv_line_cntr + 2 .
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
        ON CHANGE OF i_dpr_bupa_link_final1-participant_guid.
          PERFORM header_data_display.
          PERFORM line_title_display.
          w_proid = i_dpr_bupa_link_final1-project_id.
          v_flag = 1.
        ENDON.
        IF v_flag = 1.
          v_flag = 0.
          CONTINUE.
        ENDIF.
        PERFORM line_item_display.
      ENDLOOP.
**Code Closed by LZ16662
**FOR DISPLAYING CATSWORKLIST DETAILS
**IN EXCEL SHEET
**CONSTANTS VALUE FOR ACTIVITY NUMBER BASED ON SYSTEM
*      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
*      SELECT SINGLE bpkind
*             FROM but000
*             INTO v_bpkind
*             WHERE partner = v_businesspartner.
*      CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
*      IF NOT v_bpkind IS INITIAL.
*        CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
*          EXPORTING
*            sap_variant = v_bpkind1
*            sap_pernr   = v_pernr
*            beg_date    = p_begdt
*            end_date    = p_enddt
*          TABLES
*            sap_icatsw  = i_etworklist.
*      ENDIF.
*      DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
*      CLEAR : v_int_order, v_bpkind.
**Code Closed by LZ16662
      gv_line_cntr = gv_line_cntr_1.
      gv_line_cntr = gv_line_cntr + 2 .
**FOR DISPLAYING COLOMN NAMES FOR CATSWORKLIST
      PERFORM cats_header_data.
**FOR DISPLAYING LINE ITEM DETAILS FOR CATSWORKLIST
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid
                                     AND flag EQ 'X'.
*        v_times = i_dpr_bupa_link_final1-days_total.
        v_temp_value = i_dpr_bupa_link_final1-days_total.      "work_effort.
        v_temp_value = ceil( v_temp_value ).
        v_effortvalue = v_temp_value.
        v_length = strlen( v_effortvalue ).
        v_length = v_length - 3.
        v_effortvalue = v_effortvalue+0(v_length).
        SHIFT v_effortvalue LEFT DELETING LEADING space.
        MOVE v_effortvalue TO v_effortvalue1.
        IF  v_effortvalue1 LE v_datediff.
          v_times = v_effortvalue1.
        ELSEIF v_effortvalue1 GT v_datediff.
          v_times = v_datediff.
        ENDIF.
        READ TABLE i_etworklist WITH KEY zzcpr_objgextid = i_dpr_bupa_link_final1-task_number.
        IF sy-subrc = 0.
          DO v_times TIMES.
            gv_line_cntr = gv_line_cntr + 1.
            PERFORM cats_line_data.
          ENDDO.
        ENDIF.
        CLEAR : v_effortvalue, v_length, v_times, v_effortvalue1, v_temp_value.
      ENDLOOP.
      CLEAR : v_bpkind2.
*    LOOP AT i_etworklist WHERE sebeln NE space.
*      gv_line_cntr = gv_line_cntr + 1.
*      PERFORM cats_line_data.
*    ENDLOOP.
      PERFORM note_condition.
*      SET PROPERTY OF gs_activesheet 'PROTECT' = 1.
      CALL METHOD OF
          gs_activesheet
          'PROTECT'

        EXPORTING
          #1             = 'dsr123##$'.
      CALL METHOD OF
          g_workbook
          'PROTECT'

        EXPORTING
          #1         = 'dsr123##$'.
      REFRESH : i_etworklist.
**TO STORE THE EXCEL FILE FOR DIFFERENT PERSONNEL NUMBER
**TO STORE THE SAME IN CREATED DIRECTORY
*      CONCATENATE i_dpr_bupa_link_final2-name_first i_dpr_bupa_link_final1-name_last INTO v_save_name SEPARATED BY space.
      CONCATENATE i_dpr_bupa_link_final2-role_text '-' INTO v_save_name.
      return_file = return.
      CONCATENATE return '\'  i_dpr_bupa_link_final2-project_id '' v_pernr ''
                  v_save_name sy-datum '-' sy-uzeit '.xls' INTO return_file.
      CALL METHOD OF
          gs_wbook
          'SaveAs'

        EXPORTING
          #1       = return_file.
*    SET PROPERTY OF gs_excel 'DisplayAlerts' = 0.
      PERFORM free_objects.

      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
      wa_bapibus1006_head-bpartner = v_businesspartner.

      CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
        EXPORTING
          businesspartner = wa_bapibus1006_head-bpartner
          valid_date      = sy-datum
        TABLES
          bapiadsmtp      = wa_bapiadsmtp.
      IF NOT wa_bapiadsmtp[] IS INITIAL.
        READ TABLE wa_bapiadsmtp INDEX 1.
        IF sy-subrc = 0.
**EMAILING AN ATTACHMENT TO RECIPIENT ADDRESS SPECIFIED
          v_email = wa_bapiadsmtp-e_mail.
          w_pernr = v_pernr.
          w_begdt = v_datebeg1.
          w_enddt = v_dateend1.
          PERFORM emailing_document USING return_file
                                          v_email
                                          w_pernr
                                          w_proid
                                          w_begdt
                                          w_enddt.
          i_output-bpartner = v_businesspartner.
          i_output-mail     = v_email.
          i_output-status   = 'Sucessfully Mailed the Document'.
          APPEND i_output.
          CLEAR : i_output.
          v_sucess = v_sucess + 1.
        ELSE.
          i_output-bpartner = v_businesspartner.
          i_output-status   = 'Email Address not Maintained'.
          APPEND i_output.
          CLEAR : i_output.
          v_failure = v_failure + 1.
        ENDIF.
      ENDIF.
**EMAILING AN ATTACHMENT COPY TO RECIPIENT ADDRESS SPECIFIED
      v_email = p_recp.
      w_pernr = v_pernr.
      w_begdt = v_datebeg1.
      w_enddt = v_dateend1.
      PERFORM emailing_document USING return_file
                                      v_email
                                      w_pernr
                                      w_proid
                                      w_begdt
                                      w_enddt.
      v_mail = v_mail + 1.
    ENDIF.
    CLEAR : v_participant_guid, v_pernr, return_file,
        v_businesspartner, wa_bapiadsmtp, wa_bapibus1006_head, v_email, w_proid, w_pernr, w_begdt, w_enddt,
        ws_pernr, ws_proid, ws_begdt, ws_enddt, v_times, v_save_name, return1.
    REFRESH : i_etworklist.
  ENDLOOP.
  LOOP AT i_output WHERE mail NE space.
    v_status1 = 1.
  ENDLOOP.
  LOOP AT i_output WHERE mail EQ space.
    v_status2 = 1.
  ENDLOOP.

  IF v_status1 = 1.
    WRITE : / 'Date   :', sy-datum.
    WRITE : / 'Time   :', sy-uzeit.
    WRITE : / 'Result :', v_sucess , 'Record''s mailed sucessfully'.
    WRITE : / sy-uline.
    WRITE : / sy-vline , AT 2 'BUSINESS PARTNER' CENTERED INTENSIFIED COLOR 4, AT 20 sy-vline,
            AT 30 'EMAIL-ID' CENTERED INTENSIFIED COLOR 4 , AT 125 sy-vline,
            AT 126 'STATUS' CENTERED INTENSIFIED COLOR 4, AT 179 sy-vline.
    WRITE : / sy-uline.
    LOOP AT i_output WHERE mail NE space.
      WRITE : / sy-vline, i_output-bpartner CENTERED INTENSIFIED COLOR 2, AT 20 sy-vline,
                AT 21  i_output-mail LEFT-JUSTIFIED INTENSIFIED COLOR 2, AT 125 sy-vline,
                AT 126 i_output-status LEFT-JUSTIFIED INTENSIFIED COLOR 5, AT 179 sy-vline.
      WRITE : / sy-uline.
    ENDLOOP.
  ENDIF.
  IF v_status2  = 1.
    WRITE : / 'Result :', v_failure , 'Record''s mailed unsucessfully'.
    WRITE : / sy-uline.
    WRITE : / sy-vline , AT 2 'BUSINESS PARTNER' CENTERED INTENSIFIED COLOR 4, sy-vline,
            AT 30 'EMAIL-ID' CENTERED INTENSIFIED COLOR 4 , AT 125 sy-vline,
            AT 126 'STATUS' CENTERED INTENSIFIED COLOR 4, AT 179 sy-vline.
    WRITE : / sy-uline.
    LOOP AT i_output WHERE mail EQ space.
      WRITE : / sy-vline, i_output-bpartner CENTERED INTENSIFIED COLOR 2, AT 20 sy-vline,
                AT 21 i_output-mail LEFT-JUSTIFIED INTENSIFIED COLOR 2, AT 125 sy-vline,
                AT 126 i_output-status LEFT-JUSTIFIED INTENSIFIED COLOR 6, AT 179 sy-vline.
      WRITE : / sy-uline.
    ENDLOOP.
  ENDIF.
  IF v_mail NE 0.
    WRITE : / 'Result :', 'Record''s mailed sucessfully to -' INTENSIFIED COLOR 5 , p_recp INTENSIFIED COLOR 5.
  ELSE.
    WRITE : / 'Result :', 'Record''s mailed unsucessfully to -' INTENSIFIED COLOR 6 , p_recp INTENSIFIED COLOR 6.
  ENDIF.
ENDFORM.                    " EXCEL_SHEET_MAIL_RECIPIENT
*&---------------------------------------------------------------------*
*&      Form  BATCH_PROCESS_EMAIL
*&---------------------------------------------------------------------*
FORM batch_process_email USING p_recp .
  DATA : v_participant_guid TYPE dpr_tv_participant_guid,
         v_name TYPE char80,
         v_index TYPE sy-tabix,
         v_times(4) TYPE c,
         v_effortvalue(11) TYPE c,
         v_effortvalue1(4) TYPE n,
         v_length(4) TYPE c.

  v_recp = p_recp.
  LOOP AT i_dpr_bupa_link_final1.
    v_pernr            = i_dpr_bupa_link_final1-pernr.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      i_dpr_bupa_link_final1-bpkind = v_bpkind1.
      MODIFY i_dpr_bupa_link_final1
             INDEX sy-tabix
             TRANSPORTING bpkind.
    ELSE.
      DELETE i_dpr_bupa_link_final1 INDEX sy-tabix.
    ENDIF.
    CLEAR : v_bpkind, v_bpkind1, v_businesspartner, v_pernr.
  ENDLOOP.
  i_dpr_bupa_link_final2[] =  i_dpr_bupa_link_final1[].
  SORT i_dpr_bupa_link_final2 BY participant_guid.
  DELETE ADJACENT DUPLICATES FROM i_dpr_bupa_link_final2 COMPARING participant_guid.
  LOOP AT i_dpr_bupa_link_final2.
    v_skipflag = 0.
    v_pernr            = i_dpr_bupa_link_final2-pernr.
    v_participant_guid = i_dpr_bupa_link_final2-participant_guid.
    v_int_order        = i_dpr_bupa_link_final2-project_id.
    v_bpkind2          = i_dpr_bupa_link_final2-bpkind.

    LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
      IF
*         i_dpr_bupa_link_final1-lifnr      IS INITIAL OR
*         i_dpr_bupa_link_final1-name       IS INITIAL OR
       i_dpr_bupa_link_final1-pernr      IS INITIAL OR
       i_dpr_bupa_link_final1-project_id IS INITIAL OR
       i_dpr_bupa_link_final1-proj_name  IS INITIAL OR
       i_dpr_bupa_link_final1-name_pm    IS INITIAL OR
*         i_dpr_bupa_link_final1-object_key IS INITIAL OR
       i_dpr_bupa_link_final1-proj_desc  IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last INTO v_name SEPARATED BY space.
      IF v_name IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-object_key IS INITIAL AND
        i_dpr_bupa_link_final1-bpkind EQ 'DSR_ICDR'.
        v_skipflag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-task_name      IS INITIAL OR
         i_dpr_bupa_link_final1-task_desc      IS INITIAL OR
         i_dpr_bupa_link_final1-task_type      IS INITIAL OR
         i_dpr_bupa_link_final1-role_text      IS INITIAL OR
         i_dpr_bupa_link_final1-beg_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-end_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-work_effort    IS INITIAL.
        v_skipflag = 1.
      ENDIF.
      CLEAR : v_name.
    ENDLOOP.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
        EXPORTING
          sap_variant = v_bpkind1
          sap_pernr   = v_pernr
          beg_date    = p_begdt
          end_date    = p_enddt
        TABLES
          sap_icatsw  = i_etworklist.
    ENDIF.
    DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
    CLEAR : v_bpkind, v_bpkind1.
    IF i_etworklist[] IS INITIAL.
      v_skipflag = 1.
    ENDIF.

    IF v_skipflag = 0.
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
        ON CHANGE OF i_dpr_bupa_link_final1-participant_guid.
          IF NOT i_dpr_bupa_link_final1-lifnr IS INITIAL.
            CONCATENATE 'Vendor Number :'
                               i_dpr_bupa_link_final1-lifnr
                               INTO w_attachment
                               SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ELSE.
            CONCATENATE 'Vendor Number :'
                                 'Not Applicable for FSEs'
                                 INTO w_attachment
                                 SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ENDIF.
          IF NOT i_dpr_bupa_link_final1-name IS INITIAL.
            CONCATENATE 'Vendor Name :'
                        i_dpr_bupa_link_final1-name
                        INTO w_attachment
                        SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ELSE.
            CONCATENATE 'Vendor Name :'
                       'Not Applicable for FSEs'
                       INTO w_attachment
                       SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ENDIF.
          CONCATENATE 'Personnel Number :'
                      i_dpr_bupa_link_final1-pernr
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE 'Internal Order :'
                      i_dpr_bupa_link_final1-project_id
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE 'Project Name :'
                      i_dpr_bupa_link_final1-proj_name
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE 'Project Manager'
                      i_dpr_bupa_link_final1-name_pm
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last  INTO v_name  SEPARATED BY space.
          CONCATENATE v_pernr i_dpr_bupa_link_final1-project_id INTO v_name_sub SEPARATED BY '-'.
          CONCATENATE 'Resource Name :'
                      v_name
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          IF NOT i_dpr_bupa_link_final1-object_key IS INITIAL.
            CONCATENATE 'Purchase Order :'
                        i_dpr_bupa_link_final1-object_key
                        INTO w_attachment
                        SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ELSE.
            CONCATENATE 'Purchase Order :'
                        'Not Applicable for FSEs'
                        INTO w_attachment
                        SEPARATED BY con_tab.
            PERFORM load_data_to_attachment.
          ENDIF.
          CONCATENATE 'Project Description :'
                      i_dpr_bupa_link_final1-proj_desc
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE 'Report Start Date :'
                      v_datebeg
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CONCATENATE 'Report End Date :'
                      v_dateend
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
          CLEAR : v_name.
**Appending Extra Lines for Seperating
          PERFORM load_data_to_attachment.      "Appending Blank Lines
          PERFORM load_data_to_attachment.      "Appending Blank Lines
**2nd Stage
          CONCATENATE 'TASK NAME'
                      'TASK DESCRIPTION'
                      'TASK TYPE'
                      'ROLE TYPE'
                      'ASSIGNMENT START DATE'
                      'ASSIGNMENT END DATE'
                      'ALLOCATED DAYS'
                      '         '
                      '         '
                      '         '
                      '         '
                      '         '
                      INTO w_attachment
                      SEPARATED BY con_tab.
          PERFORM load_data_to_attachment.
**2nd stage 1st line item.
          PERFORM line_item_project_details.
          v_flag = 1.
        ENDON.
        IF v_flag = 1.
          v_flag = 0.
          CONTINUE.
        ENDIF.
        PERFORM line_item_project_details.
      ENDLOOP.
**Code Closed by LZ16662
**FOR DISPLAYING CATSWORKLIST DETAILS
**IN EXCEL SHEET
**CONSTANTS VALUE FOR ACTIVITY NUMBER BASED ON SYSTEM
*      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
*      SELECT SINGLE bpkind
*             FROM but000
*             INTO v_bpkind
*             WHERE partner = v_businesspartner.
*      CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
*      IF NOT v_bpkind IS INITIAL.
*        CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
*          EXPORTING
*            sap_variant   = v_bpkind1
*            sap_pernr     = v_pernr
*            beg_date      = p_begdt
*            end_date      = p_enddt
*          IMPORTING
*            sap_startdate = v_start_date
*            sap_enddate   = v_end_date
*          TABLES
*            sap_icatsw    = i_etworklist.
*      ENDIF.
*      DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
*      CLEAR : v_int_order, v_bpkind.
**Code Closed by LZ16662
**Appending Extra Lines for Seperating
      PERFORM load_data_to_attachment.      "Appending Blank Lines
**FOR DISPLAYING COLOMN NAMES FOR CATSWORKLIST
**3rd Stage
      CONCATENATE 'TASK ID'
                  'TASK NAME'
                  'WORK DATE'
                  'DAYS'
                  'ROLE TYPE'
                  'UOM'
                  'DATA ENTRY PROFILE'
                  'PERSONNEL NUMBER'
                  'INTERNAL ORDER'
                  'ACTIVITY TYPE'
                  'SENDER COST CENTRE'
                  'PURCHASE ORDER'
                  'LINE ITEM'
                  'PROJECT ID'
                  'ACTIVITY NUMBER (Service Master)'
                  '   '
                  INTO w_attachment
                  SEPARATED BY con_tab.
      PERFORM load_data_to_attachment.
**FOR DISPLAYING LINE ITEM DETAILS FOR CATSWORKLIST
      LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
        v_temp_value = i_dpr_bupa_link_final1-work_effort.
        v_temp_value = ceil( v_temp_value ).
        v_effortvalue = v_temp_value.
        v_length = strlen( v_effortvalue ).
        v_length = v_length - 3.
        v_effortvalue = v_effortvalue+0(v_length).
        SHIFT v_effortvalue LEFT DELETING LEADING space.
        MOVE v_effortvalue TO v_effortvalue1.
        IF  v_effortvalue1 LE v_datediff.
          v_times = v_effortvalue1.
        ELSEIF v_effortvalue1 GT v_datediff.
          v_times = v_datediff.
        ENDIF.
        READ TABLE i_etworklist WITH KEY zzcpr_objgextid = i_dpr_bupa_link_final1-task_number.
        IF sy-subrc = 0.
          DO v_times TIMES.
            PERFORM cats_line_data_output.
          ENDDO.
        ENDIF.
        CLEAR : v_effortvalue, v_length, v_times, v_effortvalue1, v_temp_value.
      ENDLOOP.
      CLEAR : v_bpkind2.
      PERFORM load_data_to_attachment.      "Appending Blank Lines
      PERFORM load_data_to_attachment.      "Appending Blank Lines
      CONCATENATE 'Note : Task Name is repeated No.'
                  'of days the task has been allocated'
                  'within the Report Period.'
                  INTO w_attachment.
*                  SEPARATED BY con_tab.
      PERFORM load_data_to_attachment.
*    LOOP AT i_etworklist WHERE sebeln NE space.
*      PERFORM cats_line_data_output.
*    ENDLOOP.
      REFRESH : i_etworklist.
**Determine the Business Partner Address
      CONCATENATE 'E0' v_pernr INTO v_businesspartner.
      wa_bapibus1006_head-bpartner = v_businesspartner.

      CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
        EXPORTING
          businesspartner = wa_bapibus1006_head-bpartner
          valid_date      = sy-datum
        TABLES
          bapiadsmtp      = wa_bapiadsmtp.
      IF NOT wa_bapiadsmtp[] IS INITIAL.
        READ TABLE wa_bapiadsmtp INDEX 1.
        IF sy-subrc = 0.
          v_email = wa_bapiadsmtp-e_mail.
          PERFORM send_mail USING v_email
                                  v_recp
                                  v_name_sub
                                  v_start_date
                                  v_end_date.
        ELSE.
          CLEAR   : w_document_data.
          REFRESH : i_packing_list, i_attachment, i_body_msg, i_receivers.
        ENDIF.
      ENDIF.
    ENDIF.
    REFRESH : i_packing_list, i_attachment, i_body_msg, i_receivers, i_etworklist.
    CLEAR : v_pernr, v_participant_guid, v_businesspartner, wa_bapiadsmtp, wa_bapibus1006_head, v_email,
            v_start_date, v_end_date, v_name_sub.
  ENDLOOP.
ENDFORM.                    " BATCH_PROCESS_EMAIL
*&---------------------------------------------------------------------*
*&      Form  LOAD_DATA_TO_ATTACHMENT
*&---------------------------------------------------------------------*
FORM load_data_to_attachment .
  CONCATENATE con_cret w_attachment
                      INTO w_attachment.
  APPEND w_attachment TO i_attachment.
  CLEAR  w_attachment.
ENDFORM.                    " LOAD_DATA_TO_ATTACHMENT
*&---------------------------------------------------------------------*
*&      Form  LINE_ITEM_PROJECT_DETAILS
*&---------------------------------------------------------------------*
FORM line_item_project_details .
  WRITE i_dpr_bupa_link_final1-beg_tmstmp_eng TO v_beg_tmstmp_eng.
  WRITE i_dpr_bupa_link_final1-end_tmstmp_eng TO v_end_tmstmp_eng.
  CLEAR : v_date, v_month, v_year.
  v_date  = v_beg_tmstmp_eng+0(2).
  v_month = v_beg_tmstmp_eng+2(2).
  v_year  = v_beg_tmstmp_eng+4(4).
  LOOP AT i_months_name WHERE mnr EQ v_month.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_date v_month_name v_year INTO v_beg_tmstmp_eng1 SEPARATED BY '-'.
  CLEAR : v_date, v_month, v_year.
  v_date  = v_end_tmstmp_eng+0(2).
  v_month = v_end_tmstmp_eng+2(2).
  v_year  = v_end_tmstmp_eng+4(4).
  LOOP AT i_months_name WHERE mnr EQ v_month.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_date v_month_name v_year INTO v_end_tmstmp_eng1 SEPARATED BY '-'.
  CLEAR : v_date, v_month, v_year.
  v_work_effort = i_dpr_bupa_link_final1-work_effort.
  CONCATENATE  i_dpr_bupa_link_final1-task_name
               i_dpr_bupa_link_final1-task_desc
               i_dpr_bupa_link_final1-task_type
               i_dpr_bupa_link_final1-role_text
               v_beg_tmstmp_eng1
               v_end_tmstmp_eng1
               v_work_effort
               '      '
               '      '
               '      '
               '      '
               '      '
               INTO w_attachment
               SEPARATED BY con_tab.
  PERFORM load_data_to_attachment.
  CLEAR : v_work_effort, v_beg_tmstmp_eng1, v_end_tmstmp_eng1, v_beg_tmstmp_eng, v_end_tmstmp_eng.
ENDFORM.                    " LINE_ITEM_PROJECT_DETAILS
*&---------------------------------------------------------------------*
*&      Form  CATS_LINE_DATA_OUTPUT
*&---------------------------------------------------------------------*
FORM cats_line_data_output .
  DATA : v_task_id   TYPE char25,
         v_task_name TYPE dpr_tv_name,
         v_lstnr(19) TYPE c,
         v_bpkind3(8) TYPE c.

  READ TABLE i_dpr_bupa_link_final1 WITH KEY task_number = i_etworklist-zzcpr_objgextid.
  IF sy-subrc = 0.
    v_task_name = i_dpr_bupa_link_final1-task_name.
  ENDIF.
  v_task_id = i_etworklist-zzcpr_objgextid.
  CONCATENATE '''' v_task_id INTO v_task_id.
  v_lstnr = i_etworklist-lstnr.
  CONCATENATE '''' v_lstnr INTO v_lstnr.

  IF v_bpkind2 = 'DSR_ICDR'.
    v_bpkind3 = v_bpkind2.
  ELSEIF v_bpkind2 EQ 'DSR_FSE'.
    v_bpkind3 = v_bpkind2.
  ENDIF.

  IF i_etworklist-skostl IS INITIAL AND
     i_etworklist-lstar  IS INITIAL AND
     i_etworklist-raufnr IS INITIAL .
    CONCATENATE v_task_id
                v_task_name
                ' '
                ' '
                i_dpr_bupa_link_final2-role_text
                'DA'
                v_bpkind3
                v_pernr
                ' '
                ' '
                ' '
                i_etworklist-sebeln
                i_etworklist-sebelp
                i_etworklist-zzcpr_extid
                v_lstnr
                '  '
                INTO w_attachment
                SEPARATED BY con_tab.
    PERFORM load_data_to_attachment.
  ELSE.
    CONCATENATE v_task_id
               v_task_name
               ' '
               ' '
               i_dpr_bupa_link_final2-role_text
               'DA'
               v_bpkind3
               v_pernr
               i_etworklist-raufnr
               i_etworklist-lstar
               i_etworklist-skostl
               i_etworklist-sebeln
               i_etworklist-sebelp
               i_etworklist-zzcpr_extid
               v_lstnr
               '  '
               INTO w_attachment
               SEPARATED BY con_tab.
  ENDIF.
  CLEAR : v_task_id, v_task_name, v_bpkind3.
ENDFORM.                    " CATS_LINE_DATA_OUTPUT
*&---------------------------------------------------------------------*
*&      Form  SEND_MAIL
*&---------------------------------------------------------------------*
FORM send_mail USING v_email
                     v_recp
                     v_name_sub
                     v_start_date
                     v_end_date.

  DATA : v_objdescr(70)  TYPE c,
         v_begindate(11) TYPE c,
         v_enddate(11)   TYPE c,
         v_temp(30)      TYPE c,
         v_month_name    TYPE fcktx.
  DATA : i_months_name   TYPE STANDARD TABLE OF
                         t247 WITH HEADER LINE.   "For getting months name in Subject line

  CALL FUNCTION 'MONTH_NAMES_GET'
    EXPORTING
      language              = sy-langu
    TABLES
      month_names           = i_months_name
    EXCEPTIONS
      month_names_not_found = 1
      OTHERS                = 2.

  "Subject of the mail.
  w_document_data-obj_name  = 'MAIL_TO_HEAD'.
  CLEAR : v_objdescr.
  v_year  = v_start_date+0(4).
  v_month = v_start_date+4(2).
  v_date  = v_start_date+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_month.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_date v_month_name v_year INTO v_begindate SEPARATED BY '.'.
  CLEAR : v_year, v_month, v_date, v_month_name.
  v_year  = v_end_date+0(4).
  v_month = v_end_date+4(2).
  v_date  = v_end_date+6(2).
  LOOP AT i_months_name WHERE mnr EQ v_month.
    v_month_name = i_months_name-ktx.
  ENDLOOP.
  CONCATENATE v_date v_month_name v_year INTO v_enddate SEPARATED BY '.'.
  CLEAR : v_year, v_month, v_date, v_month_name.
  CONCATENATE v_begindate '-' v_enddate INTO v_temp SEPARATED BY space.
  CONCATENATE 'DAR' v_name_sub v_temp INTO v_objdescr SEPARATED BY '-'.
  w_document_data-obj_descr = v_objdescr.
  CLEAR : v_objdescr, v_temp, v_begindate, v_enddate.

  "Write Packing List for Body
  DESCRIBE TABLE i_body_msg LINES g_tab_lines.
  w_packing_list-head_start = 1.
  w_packing_list-head_num   = 0.
  w_packing_list-body_start = 1.
  w_packing_list-body_num   = g_tab_lines.
  w_packing_list-doc_type   = 'RAW'.
  APPEND w_packing_list TO i_packing_list.
  CLEAR  w_packing_list.

  "Write Packing List for Attachment
  w_packing_list-transf_bin = 'X'.
  w_packing_list-head_start = 1.
  w_packing_list-head_num   = 1.
  w_packing_list-body_start = 1.
  DESCRIBE TABLE i_attachment LINES w_packing_list-body_num.
  w_packing_list-doc_type   = 'XLS'.
  CONCATENATE v_pernr 'DETAIL ACTIVITY REPORT' INTO v_objdescr SEPARATED BY '-'.
  w_packing_list-obj_descr  = v_objdescr.
  CLEAR : v_objdescr.
  w_packing_list-obj_name   = 'XLS_ATTACHMENT'.
  w_packing_list-doc_size   = w_packing_list-body_num * 255.
  APPEND w_packing_list TO i_packing_list.
  CLEAR  w_packing_list.

  "Fill the document data and get size of attachment
  w_document_data-obj_langu  = sy-langu.
  READ TABLE i_attachment INTO w_attachment INDEX g_tab_lines.
  w_document_data-doc_size = ( g_tab_lines - 1 ) * 255 + strlen( w_attachment ).

  "Receivers List.
  w_receivers-rec_type   = 'U'.  " U Internet address
  w_receivers-receiver   = v_email.  "MAIL ADDRESS
  APPEND w_receivers TO i_receivers .
  CLEAR:w_receivers.
  IF NOT v_recp IS INITIAL.
    w_receivers-rec_type   = 'U'.  " U Internet address
    w_receivers-receiver   = v_recp.  "MAIL ADDRESS
    w_receivers-copy       = 'X'.
    APPEND w_receivers TO i_receivers .
    CLEAR:w_receivers.
  ENDIF.

  "Function module to send mail to Recipients
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = w_document_data
      put_in_outbox              = 'X'
      commit_work                = 'X'
    IMPORTING
      sent_to_all                = g_sent_to_all
    TABLES
      packing_list               = i_packing_list
      contents_bin               = i_attachment
      contents_txt               = i_body_msg
      receivers                  = i_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.

*  IF sy-subrc = 0 .
*    MESSAGE i303(me) WITH 'Mail has been Successfully Sent.'.
*  ELSE.
*    WAIT UP TO 2 SECONDS.
*    "This program starts the SAPconnect send process.
*    SUBMIT rsconn01 WITH mode = 'INT'
*                 WITH output = 'X'
*                 AND RETURN.
*  ENDIF.
  CLEAR : v_email, v_month_name.
  REFRESH : i_months_name.
ENDFORM.                    " SEND_MAIL
*&---------------------------------------------------------------------*
*&      Form  F_INITIALAZE_RFCDEST
*&---------------------------------------------------------------------*
FORM f_initialaze_rfcdest .
  DATA : v_datum TYPE sy-datum.
  CLEAR v_dest.
  CASE sy-sysid.
    WHEN 'NRD'.
      MOVE c_gdd TO v_dest.
    WHEN 'NRB'.
      MOVE c_gb2 TO v_dest.
    WHEN 'NRP'.
      MOVE c_gp1 TO v_dest.
  ENDCASE.
  v_datum = sy-datum + 15.
  p_enddt = v_datum.
  CLEAR : v_datum.
ENDFORM.                    " F_INITIALAZE_RFCDEST
*&---------------------------------------------------------------------*
*&      Form  FREE_OBJECTS
*&---------------------------------------------------------------------*
FORM free_objects .
  CALL METHOD OF
      gs_wbook
      'Close'.
  CALL METHOD OF
      gs_excel
      'Quit'.
  FREE OBJECT gs_cell1.
  FREE OBJECT gs_cell2.
  FREE OBJECT gs_cells.
  FREE OBJECT gs_activesheet.
  FREE OBJECT gs_wbook.
  FREE OBJECT gs_application.
  FREE OBJECT gs_wbooklist.
  FREE OBJECT gs_excel.
ENDFORM.                    " FREE_OBJECTS
*&---------------------------------------------------------------------*
*&      Form  NOTE_CONDITION
*&---------------------------------------------------------------------*
FORM note_condition .
  gv_line_cntr = gv_line_cntr + 2.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell1
    EXPORTING
      #1       = gv_line_cntr
      #2       = 1.
  CALL METHOD OF
      gs_excel
      'Cells'  = gs_cell2
    EXPORTING
      #1       = gv_line_cntr
      #2       = 5.
  CALL METHOD OF
      gs_excel
      'Range'  = gs_cells
    EXPORTING
      #1       = gs_cell1
      #2       = gs_cell2.
  CALL METHOD OF
      gs_cells
      'Select'.
*--Merging
  CALL METHOD OF
      gs_cells
      'Merge'.
  SET PROPERTY OF gs_cells 'Value' = 'Note: Task Name is repeated No. of days the task has been allocated within the Report Period.' .
**--Formatting the title
  GET PROPERTY OF gs_cells 'Font' = gs_font .
  SET PROPERTY OF gs_font  'Name' = 'Arial' .
  SET PROPERTY OF gs_font  'Size' = '10' .
  SET PROPERTY OF gs_font  'Bold' = 1 .
  SET PROPERTY OF gs_font  'Italic' = 1 .
  SET PROPERTY OF gs_cells 'HorizontalAlignment' = -4131 .
  SET PROPERTY OF gs_cells 'Locked' = 1.
ENDFORM.                    " NOTE_CONDITION
*&---------------------------------------------------------------------*
*&      Form  FILTER_OUTPUT_DISPLAY_ALV
*&---------------------------------------------------------------------*
FORM filter_output_display_alv .
  DATA : v_name TYPE char80,
         v_participant_guid TYPE dpr_tv_participant_guid,
         v_index TYPE sy-tabix,
         v_flag  TYPE c VALUE '0'.
**TO DETERMINE THE CURRENT USERNAME DESKTOP
**PATH FOR CREATING FOLDER IN HIS SYSTEM.
  LOOP AT i_dpr_bupa_link_final1.
    v_index = sy-tabix.
    v_pernr            = i_dpr_bupa_link_final1-pernr.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      i_dpr_bupa_link_final1-bpkind = v_bpkind1.
      MODIFY i_dpr_bupa_link_final1
             INDEX sy-tabix
             TRANSPORTING bpkind.
    ELSE.
      DELETE i_dpr_bupa_link_final1 INDEX v_index.
    ENDIF.
    CLEAR : v_bpkind, v_bpkind1, v_businesspartner, v_pernr, v_index.
  ENDLOOP.

  i_dpr_bupa_link_final2[] =  i_dpr_bupa_link_final1[].
  SORT i_dpr_bupa_link_final2 BY participant_guid.
  DELETE ADJACENT DUPLICATES FROM i_dpr_bupa_link_final2 COMPARING participant_guid.

  LOOP AT i_dpr_bupa_link_final2.
    v_skipflag = 0.
    v_index = sy-tabix.
    v_pernr            = i_dpr_bupa_link_final2-pernr.
    v_participant_guid = i_dpr_bupa_link_final2-participant_guid.
    v_int_order        = i_dpr_bupa_link_final2-project_id.
    LOOP AT i_dpr_bupa_link_final1 WHERE participant_guid = v_participant_guid.
      IF
*         i_dpr_bupa_link_final1-lifnr      IS INITIAL OR
*         i_dpr_bupa_link_final1-name       IS INITIAL OR
         i_dpr_bupa_link_final1-pernr      IS INITIAL OR
         i_dpr_bupa_link_final1-project_id IS INITIAL OR
         i_dpr_bupa_link_final1-proj_name  IS INITIAL OR
         i_dpr_bupa_link_final1-name_pm    IS INITIAL OR
*         i_dpr_bupa_link_final1-object_key IS INITIAL OR
         i_dpr_bupa_link_final1-proj_desc  IS INITIAL.
        v_flag = 1.
      ENDIF.
      CONCATENATE i_dpr_bupa_link_final1-name_first i_dpr_bupa_link_final1-name_last INTO v_name SEPARATED BY space.
      IF v_name IS INITIAL.
        v_flag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-object_key IS INITIAL AND
         i_dpr_bupa_link_final1-bpkind EQ 'DSR_ICDR'.
        v_flag = 1.
      ENDIF.
      IF i_dpr_bupa_link_final1-task_name      IS INITIAL OR
         i_dpr_bupa_link_final1-task_desc      IS INITIAL OR
         i_dpr_bupa_link_final1-task_type      IS INITIAL OR
         i_dpr_bupa_link_final1-role_text      IS INITIAL OR
         i_dpr_bupa_link_final1-beg_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-end_tmstmp_eng IS INITIAL OR
         i_dpr_bupa_link_final1-work_effort    IS INITIAL.
        v_flag = 1.
      ENDIF.
      CLEAR : v_name.
      IF v_flag = 1.
        DELETE i_dpr_bupa_link_final1 INDEX sy-tabix.
        v_flag = 0.
      ENDIF.
    ENDLOOP.
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    SELECT SINGLE bpkind
           FROM but000
           INTO v_bpkind
           WHERE partner = v_businesspartner.
    CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.
    IF NOT v_bpkind IS INITIAL.
      CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
        EXPORTING
          sap_variant = v_bpkind1
          sap_pernr   = v_pernr
          beg_date    = p_begdt
          end_date    = p_enddt
        TABLES
          sap_icatsw  = i_etworklist.
    ENDIF.
    DELETE i_etworklist WHERE zzcpr_extid NE v_int_order.
    CLEAR : v_bpkind, v_bpkind1.
    IF i_etworklist[] IS INITIAL.
      DELETE i_dpr_bupa_link_final1 WHERE pernr EQ v_pernr.
    ENDIF.
**To check BP Email Address
    CONCATENATE 'E0' v_pernr INTO v_businesspartner.
    wa_bapibus1006_head-bpartner = v_businesspartner.
    REFRESH : wa_bapiadsmtp.
    CALL FUNCTION 'BAPI_BUPA_ADDRESS_GETDETAIL'
      EXPORTING
        businesspartner = wa_bapibus1006_head-bpartner
        valid_date      = sy-datum
      TABLES
        bapiadsmtp      = wa_bapiadsmtp.
    IF wa_bapiadsmtp[] IS INITIAL.
      DELETE i_dpr_bupa_link_final1 WHERE pernr EQ v_pernr.
    ELSE.
      REFRESH : wa_bapiadsmtp.
    ENDIF.
    CLEAR : v_participant_guid, v_pernr, v_businesspartner, v_int_order, wa_bapiadsmtp, wa_bapibus1006_head.
    REFRESH : i_etworklist.
  ENDLOOP.
ENDFORM.                    " FILTER_OUTPUT_DISPLAY_ALV

*PROGRAM for sending MAIL. transaction code  yg_email
*&---------------------------------------------------------------------*
*& Report  YGS_SEND_EXTERNAL_MAIL
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT  ygs_send_external_mail.
*----------------------------------------------------------------------*
* DATA DECLERATIONS                                                    *
*----------------------------------------------------------------------*
DATA : method1         LIKE sy-ucomm,
       g_user          LIKE soudnamei1,
       g_user_data     LIKE soudatai1,
       g_owner         LIKE soud-usrnam,
       g_document      LIKE sood4 ,
       g_header        LIKE sood2,
       g_folmam        LIKE sofm2,
       g_authority     LIKE sofa-usracc,
       g_ref_document  LIKE sood4,
       g_new_parent    LIKE soodk,
       fold_number(12) TYPE c,
       fold_yr(2)      TYPE c,
       fold_type(3)    TYPE c.
*----------------------------------------------------------------------*
* INTERNAL TABLE DECLERATIONS                                          *
*----------------------------------------------------------------------*
DATA g_objcnt       LIKE soli  OCCURS 0 WITH HEADER LINE.
DATA g_objhead      LIKE soli  OCCURS 0 WITH HEADER LINE.
DATA g_objpara      LIKE selc  OCCURS 0 WITH HEADER LINE.
DATA g_objparb      LIKE soop1 OCCURS 0 WITH HEADER LINE.
DATA g_attachments  LIKE sood5 OCCURS 0 WITH HEADER LINE.
DATA g_references   LIKE soxrl OCCURS 0 WITH HEADER LINE.
DATA g_receipients  LIKE soos1 OCCURS 0 WITH HEADER LINE.
DATA i_months_name  TYPE STANDARD TABLE OF t247 WITH HEADER LINE. "For getting months
"name in Subject line
DATA: BEGIN OF g_files OCCURS 10 ,
       text(4096) TYPE c,
      END OF g_files.
DATA : v_objdescr(50)    TYPE c,
       v_begindate(11)   TYPE c,
       v_enddate(11)     TYPE c,
       v_temp(30)        TYPE c,
       v_dest            LIKE edipoa-logdes,
       v_start_date      TYPE sy-datum,
       v_end_date        TYPE sy-datum,
       v_date(2)         TYPE c,
       v_month(2)        TYPE c,
       v_year(4)         TYPE c,
       v_businesspartner TYPE bu_partner,
       v_bpkind          TYPE bu_bpkind,
       v_bpkind1(8)      TYPE c,
       v_month_name      TYPE fcktx,
       v_name_sub(100)   TYPE c.
*----------------------------------------------------------------------*
* CONSTANT DECLERATIONS                                                *
*----------------------------------------------------------------------*
CONSTANTS : c_gdd(6) TYPE c VALUE 'GDD590',
            c_gb2(6) TYPE c VALUE 'GB2590',
            c_gp1(6) TYPE c VALUE 'GP1590'.
*----------------------------------------------------------------------*
* PARAMETER DECLERATIONS                                               *
*----------------------------------------------------------------------*
PARAMETER : ws_file       TYPE string,
            ws_email(128) TYPE c,
            ws_pernr      TYPE pernr_d,
            ws_proid      TYPE project_id,
            ws_begdt      TYPE sy-datum,
            ws_enddt      TYPE sy-datum.

CLEAR v_dest.
CASE sy-sysid.
  WHEN 'NRD'.
    MOVE c_gdd TO v_dest.
  WHEN 'NRB'.
    MOVE c_gb2 TO v_dest.
  WHEN 'NRP'.
    MOVE c_gp1 TO v_dest.
ENDCASE.

CONCATENATE ws_pernr  ws_proid INTO v_name_sub SEPARATED BY '-'.
CALL FUNCTION 'MONTH_NAMES_GET'
  EXPORTING
    language              = sy-langu
  TABLES
    month_names           = i_months_name
  EXCEPTIONS
    month_names_not_found = 1
    OTHERS                = 2.

* Can me any file fromyour pc ....either xls or word or ppt etc ...
CLEAR : g_user_data, g_document.
g_user-sapname = sy-uname.
ws_file = ws_file.
CALL FUNCTION 'SO_USER_READ_API1'
  EXPORTING
    user      = g_user
  IMPORTING
    user_data = g_user_data.

fold_type = g_user_data-outboxfol+0(3).
fold_yr = g_user_data-outboxfol+3(2).
fold_number =  g_user_data-outboxfol+5(12).
CLEAR g_files.
REFRESH : g_objcnt,  g_objhead,  g_objpara,  g_objparb,  g_receipients,
          g_attachments,  g_references,  g_files.

method1 = 'SAVE'.
g_document-foltp    = fold_type.
g_document-folyr    = fold_yr.
g_document-folno    = fold_number.
g_document-objtp    = g_user_data-object_typ.
g_document-objdes   = 'Detail Activity Report'.
g_document-folrg    = 'O'.
g_document-objlen   = '0'.
g_document-file_ext = 'XLS'.

CONCATENATE 'E0' ws_pernr INTO v_businesspartner.
SELECT SINGLE bpkind
       FROM but000
       INTO v_bpkind
       WHERE partner = v_businesspartner.
CONCATENATE 'DSR_' v_bpkind INTO v_bpkind1.

CALL FUNCTION 'Y_CATS_WORKLIST_DEATILS' DESTINATION v_dest
  EXPORTING
    sap_variant   = v_bpkind1
    sap_pernr     = ws_pernr
    beg_date      = ws_begdt
    end_date      = ws_enddt
  IMPORTING
    sap_startdate = v_start_date
    sap_enddate   = v_end_date.

CLEAR : v_bpkind1, v_bpkind.
v_year  = v_start_date+0(4).
v_month = v_start_date+4(2).
v_date  = v_start_date+6(2).
LOOP AT i_months_name WHERE mnr EQ v_month.
  v_month_name = i_months_name-ktx.
ENDLOOP.
CONCATENATE v_date v_month_name v_year INTO v_begindate SEPARATED BY '.'.
CLEAR : v_date, v_month, v_year, v_month_name.
v_year  = v_end_date+0(4).
v_month = v_end_date+4(2).
v_date  = v_end_date+6(2).
LOOP AT i_months_name WHERE mnr EQ v_month.
  v_month_name = i_months_name-ktx.
ENDLOOP.
CONCATENATE v_date v_month_name v_year INTO v_enddate SEPARATED BY '.'.
CLEAR : v_date, v_month, v_year, v_month_name.
CONCATENATE v_begindate '-' v_enddate INTO v_temp.
CONCATENATE 'DAR' v_name_sub v_temp INTO v_objdescr  SEPARATED BY '-'.
g_header-objdes     = v_objdescr.
CLEAR : v_objdescr, v_temp, v_begindate, v_enddate, v_start_date, v_end_date.

CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = sy-uname
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

* File from the pc to send...
method1 = 'ATTCREATEFROMPC'.

g_files-text = ws_file.
APPEND g_files.
CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = g_owner
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

method1 = 'SEND'.
g_receipients-recextnam = ws_email.
g_receipients-recesc    = 'A'.
g_receipients-sndex     = 'X'.
APPEND  g_receipients.
CALL FUNCTION 'SO_DOCUMENT_REPOSITORY_MANAGER'
  EXPORTING
    method       = method1
    office_user  = g_owner
    ref_document = g_ref_document
    new_parent   = g_new_parent
  IMPORTING
    authority    = g_authority
  TABLES
    objcont      = g_objcnt
    objhead      = g_objhead
    objpara      = g_objpara
    objparb      = g_objparb
    recipients   = g_receipients
    attachments  = g_attachments
    references   = g_references
    files        = g_files
  CHANGING
    document     = g_document
    header_data  = g_header.

* SUBMIT rsconn01 WITH mode = 'INT'
*                 WITH output = 'X'
*                 AND RETURN.
REFRESH : g_objcnt,   g_objhead,   g_objpara,   g_objparb,   g_receipients,
          g_attachments,   g_references,   g_files.
 
REPORT ztsapmail.
DATA: x_object_type LIKE sood-objtp.
DATA: BEGIN OF x_object_hd_change.
        INCLUDE STRUCTURE sood1.
DATA: END OF x_object_hd_change.
DATA: BEGIN OF x_objcont OCCURS 10.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objcont.
DATA: BEGIN OF x_objhead OCCURS 0.
        INCLUDE STRUCTURE soli.
DATA: END OF x_objhead.
DATA: BEGIN OF raw_head.
        INCLUDE STRUCTURE sorh.
DATA: END OF raw_head.
DATA: BEGIN OF x_receivers OCCURS 0.
        INCLUDE STRUCTURE soos1.
DATA: END OF x_receivers.
PARAMETERS: receiver LIKE x_receivers-recnam. " Name
*BUILD MESSAGE HEADER
MOVE 'Sort field goes here' TO x_object_hd_change-objsrt. " Sort field
MOVE 'Name of the object goes here' TO x_object_hd_change-objnam. " Name
MOVE 'Document title goes here' TO x_object_hd_change-objdes. " Title
MOVE 'F' TO x_object_hd_change-objsns. " Functional OBJECT
MOVE 'E' TO x_object_hd_change-objla. " Language
* Object type of the new document
MOVE 'RAW' TO x_object_type.
CLEAR x_objcont.
MOVE 'Contents of mail' TO x_objcont-line.
APPEND x_objcont.
CLEAR x_objcont-line. APPEND x_objcont.
MOVE 'More contents' TO x_objcont-line.
APPEND x_objcont.
MOVE 'Still more contents'
TO x_objcont-line.
APPEND x_objcont.
MOVE ' ' TO x_objcont-line.
APPEND x_objcont.
* Specific header (Dependent on the object type, here RAW)
REFRESH x_objhead.
DESCRIBE TABLE x_objcont LINES raw_head-rawsiz.
MOVE raw_head TO x_objhead.
APPEND x_objhead.
*RECEIVERS table
CLEAR x_receivers.
REFRESH x_receivers.
MOVE receiver TO x_receivers-recnam. " Name
MOVE 'B' TO x_receivers-recesc. " Receiver type
MOVE 'X' TO x_receivers-sndcp. " Send as a copy
MOVE 'X' TO x_receivers-sndex. " EXPRESS DOCUMENT
APPEND x_receivers.
CALL FUNCTION 'SO_OBJECT_SEND'
  EXPORTING
    object_hd_change = x_object_hd_change
    object_type      = x_object_type
    outbox_flag      = 'X'
    owner            = sy-uname
    tablesobjcont    = x_objcont
    objhead          = x_objhead
    receivers        = x_receivers.
 

Author: Jatra Riwayanto
Submitted: 26.09.2007
Related Links:

Description:
My previous snippet is a program that will display Inbox folder content. Now I am adding some code that will display mail content. User can select specific mail and will see the content of this mail.

Report Line-Size
Because length of SOLI-LINE is 255 character, we need to change report line size.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  ZSapInbox NO STANDARD PAGE HEADING
                  LINE-COUNT 65
                  LINE-SIZE 260.

Class Definition
Adding Display_Mail method and several data variable.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
CLASS LCL_MAIN DEFINITION.
  PUBLIC SECTION.
    METHODS: DISPLAY_INBOX,
             DISPLAY_MAIL IMPORTING IM_MAILID TYPE STRING.  " -- added code --
    EVENTS:  MESSAGE EXPORTING VALUE(MSG1) TYPE STRING
                               VALUE(MSG2) TYPE STRING OPTIONAL
                               VALUE(MSG3) TYPE STRING OPTIONAL
                               VALUE(MSG4) TYPE STRING OPTIONAL.
  PRIVATE SECTION.
    METHODS: CLEAR_DATA,
             GET_INBOX_CONTENT.
*---------------------------------
* L.O.C.A.L  D.A.T.A.
*---------------------------------
    DATA: USER      TYPE SOUDNAMEI1,
          UDAT      TYPE SOUDATAI1,
          FDAT      TYPE SOFOLDATI1,
          IT_FDAT   TYPE TABLE OF SOFOLENTI1,
          WA_FDAT   TYPE SOFOLENTI1.

    DATA: MSG1      TYPE STRING,
          MSG2      TYPE STRING,
          MSG3      TYPE STRING,
          MSG4      TYPE STRING.

    DATA: FOLD_ID   TYPE SOODK,
          MAIL_ID   TYPE SOODK.          " -- added code --

    DATA: WA_OBJCONT TYPE SOLI,          " -- added code --
          IT_OBJCONT TYPE TABLE OF SOLI, " -- added code --
          OBJECT_HD_DISPLAY  TYPE SOOD2. " -- added code --

ENDCLASS.                    "lcl_main DEFINITION

Display_Mail Implementation

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
METHOD DISPLAY_MAIL.
    MOVE IM_MAILID TO MAIL_ID.

    CALL FUNCTION 'SO_OBJECT_READ'
         EXPORTING
              folder_id                  = FOLD_ID
              object_id                  = MAIL_ID
              owner                      = P_UNAME
         IMPORTING
              object_hd_display          = object_hd_display
         TABLES
              objcont                    = IT_objcont
         EXCEPTIONS
              active_user_not_exist      = 35
              communication_failure      = 71
              component_not_available    = 01
              folder_not_exist           = 06
              folder_no_authorization    = 05
              object_not_exist           = 14
              object_no_authorization    = 13
              operation_no_authorization = 21
              owner_not_exist            = 22
              parameter_error            = 23
              substitute_not_active      = 31
              substitute_not_defined     = 32
              system_failure             = 72
              x_error                    = 1000.

    IF SY-SUBRC NE 0.
     RAISE EVENT MESSAGE EXPORTING MSG1 = 'Error reading mail content'.
    ELSE.
      FORMAT COLOR COL_HEADING.
      ULINE (259).
      WRITE: / '|',(255) object_hd_display-OBJDES LEFT-JUSTIFIED, '|'.
      ULINE (259).
      FORMAT COLOR OFF.

      LOOP AT IT_OBJCONT INTO WA_OBJCONT.
        WRITE: / '|', WA_OBJCONT-LINE, '|'.
      ENDLOOP.
      ULINE (259).
    ENDIF.

  ENDMETHOD.                    "DISPLAY_MAIL

Hotspot
We need add Hotspot on Object ID column.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
METHOD DISPLAY_INBOX.
    CALL METHOD CLEAR_DATA( ).
    CALL METHOD GET_INBOX_CONTENT( ).
    IF IT_FDAT[] IS INITIAL.
      RAISE EVENT MESSAGE EXPORTING MSG1 = 'No emails in this inbox'.
    ENDIF.

    ULINE AT (114).
    FORMAT COLOR COL_HEADING.
    WRITE: / '|' NO-GAP, (020) 'Object ID'        LEFT-JUSTIFIED,
             '|' NO-GAP, (030) 'Subject'          LEFT-JUSTIFIED,
             '|' NO-GAP, (015) 'Date Recieved'    LEFT-JUSTIFIED,
             '|' NO-GAP, (040) 'Sender '          LEFT-JUSTIFIED,
             '|'.
    ULINE AT /(114).
    FORMAT COLOR OFF.

    LOOP AT IT_FDAT INTO WA_FDAT.
      FORMAT COLOR COL_NORMAL INTENSIFIED ON.
      WRITE: / '|' NO-GAP, (020) WA_FDAT-OBJECT_ID  UNDER 'Email ID'
                   HOTSPOT ON COLOR 5,  " -- added code --
               '|' NO-GAP, (030) WA_FDAT-OBJ_DESCR   LEFT-JUSTIFIED,
               '|' NO-GAP, (015) WA_FDAT-REC_DATE    LEFT-JUSTIFIED,
               '|' NO-GAP, (040) WA_FDAT-SEND_FNAM   LEFT-JUSTIFIED,
               '|'.
    ENDLOOP.
    ULINE AT /(114).
  ENDMETHOD.                    "DISPLAY_INBOX

AT LINE SELECTION
To make user enable display mail we need add AT-LINE-SELECTION code after START-OF-SELECTION.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
START-OF-SELECTION.
  DATA: O_MAIN           TYPE REF TO LCL_MAIN,
        O_HANDLER        TYPE REF TO LCL_HANDLER.

  CREATE OBJECT: O_MAIN, O_HANDLER.
  SET HANDLER O_HANDLER->HANDLE_MESSAGE FOR ALL INSTANCES.

  CALL METHOD O_MAIN->DISPLAY_INBOX.

AT LINE-SELECTION.
  DATA MAIL_ID TYPE STRING.

  MAIL_ID = SY-LISEL+1(17).
  CALL METHOD O_MAIN->DISPLAY_MAIL( MAIL_ID ).

Select Object ID.

Display mail content.

Business Scenarios:

In ETL, many times we have to use the ABAP programs to do processing so that we can implement various business scenarios. Some times users or Support teams need to be notified when something goes wrong in program while dealing with incorrect data. In those cases program goes under infinite loop and program times out. Support team then have to look into dumps and invest lot of time in analyzing the issue to find out where the program went wrong. To avoid all these manual steps we can rite a general program which can be called in different programs to generate the mails with the incorrect values. This automation will help in saving lot of manual effort.

Solution:

The ABAP developer can use the below program to generate the mails to the users and support team.
Step 1. Create a separate program as mentioned.
Go to Transaction SE38 and create program as:

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*&---------------------------------------------------------------------
*& FORM  ZEMAIL_GENERATION
*&---------------------------------------------------------------------
*&  This program receives a table containing Data issue list and
*&  generate mail.
*&---------------------------------------------------------------------
FORM zemail_generation TABLES rc.
  DATA: it_objcont          LIKE solisti1 OCCURS 5 WITH HEADER LINE,
        it_reclist          LIKE somlreci1 OCCURS 5 WITH HEADER LINE,
        itab_objhead        LIKE soli OCCURS 0 WITH HEADER LINE,
        itab_receiver       LIKE soos1 OCCURS 0 WITH HEADER LINE,
        t_email_content     LIKE soli OCCURS 0 WITH HEADER LINE,
        lw_originator       LIKE soos1-recextnam,
        lw_originator_type  LIKE soos1-recesc,
        w_mail_header       LIKE sood1,
        it_document         TYPE hrhap,
        it_doc_chng         LIKE sodocchgi1,
        lin                 LIKE sy-tabix,
        v_content1          LIKE solisti1,
        v_content2          LIKE solisti1,
        v_content3          LIKE solisti1,
        v_content4          LIKE solisti1,
        v_content5          LIKE solisti1,
        header              LIKE sodocchgi1-obj_descr,
        wa_subject          TYPE char100,
        wa_content1         TYPE char100,
        wa_content2         TYPE solisti1-line,
        wa_receiver         TYPE char20,
        wa_event_id         TYPE char50,
        wa_stxh_tdname      TYPE stxh-tdname,
        status              LIKE hrhap-ap_status,
        sub_status          LIKE hrhap-ap_status_sub,
        wa_appraisal_id     LIKE hrhap-appraisal_id,
        plan_version        TYPE hap_plan_version,
        email_address       TYPE comm_id_long,
        designate_add       TYPE comm_id_long,
        l_stxh_tdname       TYPE stxh-tdname,
        lw_sender_name      TYPE soud-usrnam,
        lw_send_request_oid TYPE os_guid,
        sender_pernr        TYPE /bi0/oiemployee,
        sup_pernr           TYPE /bi0/oiemployee,
        appee_pernr         TYPE /bi0/oiemployee.
  DATA  objcont            LIKE soli OCCURS  5 WITH HEADER LINE. "Mail cont
  DATA: rc_tbl_new LIKE solisti1 OCCURS 5 WITH HEADER LINE,
        wa_rc_tbl TYPE solisti1.
  DATA: BEGIN OF w_ws,
          count TYPE i,
          smtp TYPE /bi0/oiemail_addr,
          err_num LIKE sy-msgno,
        END OF w_ws.

***End of declarations.
  CLEAR: wa_receiver, wa_subject , wa_content1, wa_content2, it_document.
  wa_receiver = 'BW-PRODSUPPORT@XYZ.com'.
  wa_subject = header =  'EMPLOYEE Hierarchy Going in Infinite Loop'.
  wa_content1 = 'The Supervisor going in Infinite loop are:'.

*Append Receiverlist table.
  it_reclist-rec_type = 'U'.                       "Internet-adress
  it_reclist-receiver = 'BW-PRODSUPPORT@XYZ.com'.           " 'BW tier 3'.
  it_reclist-express = 'X'.
  APPEND it_reclist.
*Set general email message header/subject information
  w_mail_header-objnam = ''.
  w_mail_header-objsns = 'C'.
  w_mail_header-objla  = sy-langu.
  w_mail_header-objdes = header.
*Set message header to RAW
  itab_objhead-line = 'RAW'.
  APPEND itab_objhead.
*Set receiver information
  itab_receiver-sel        = 'X'.
  itab_receiver-rcdat      = sy-datum.
  itab_receiver-recesc     = 'U'.
  itab_receiver-recnam     = '  '.
  itab_receiver-mailstatus = 'E'.
  itab_receiver-sortclass  = '5'.
  itab_receiver-sndart     = 'INT'.
  itab_receiver-sndpri     = '1'.
  itab_receiver-sndspo     = '0'.
  itab_receiver-deliver    = 'X'.
  itab_receiver-read       = 'X'.
  itab_receiver-recextnam  = w_ws-smtp.
  APPEND itab_receiver.
*Send email
*Process the EMAIL using SO_NEW_DOCUMENT_SEND_API1
*Fill the document header
  it_doc_chng-obj_name   = 'URGENT'.
  it_doc_chng-obj_descr  = header.
  IF sy-sysid = 'HRP'.
    it_doc_chng-sensitivty = 'P'.
  ELSE.
    it_doc_chng-sensitivty = 'O'.
  ENDIF.
  it_doc_chng-obj_langu  = sy-langu.
* fill the text of the mail
  it_objcont = wa_content1.
  APPEND it_objcont.
*** Append the RCs to the Text of the mail.
*RC is an internal table containing incorrect data having issues.
  APPEND LINES OF rc TO it_objcont.
* Read table and get the document size.
  DESCRIBE TABLE it_objcont LINES lin.
  READ TABLE it_objcont INDEX lin.
  it_doc_chng-doc_size = ( lin - 1 ) * 255 + strlen( it_objcont ).
  IF it_doc_chng-doc_size LT 0.
    it_doc_chng-doc_size = 0.
  ENDIF.
* Send the email
  CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
    EXPORTING
      document_data     = it_doc_chng
      document_type     = 'RAW'
      put_in_outbox     = 'X'
      commit_work       = 'X'
    TABLES
      object_content    = it_objcont
      receivers         = it_reclist
    EXCEPTIONS
      document_not_sent = 2.

ENDFORM.                    "ZEMAIL_GENERATION

Step 2. In your main program where you are doing functional processing, create an internal table and keep on filling the same with the values having data issue.
"RC" is an internal table with the values having data issues.
Call program to generate mail by using the below mention code snippet in your main program.
Table "RC" is populated with list of Corrupted RCs.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
rc[] = corr_rc_table[].
DESCRIBE TABLE rc LINES lin.
IF lin <> 0.
*** Call PERFORM to send Email for Corrupted values from RCs.
  PERFORM zemail_generation TABLES  rc .
ENDIF.
  • Step 3: For testing the functionality of the program:
     Got to Transaction SCOT and goto Utilities as shown in screen shot:"

In the "OVERVIEW OF SEND ORDERS", you will see screen as shown below:

"
Select any request to check the body of the mail. Do execute to release the mail from outbox.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT  zemail_attach                   .
TABLES: ekko.

PARAMETERS: p_email   TYPE somlreci1-receiver
                                  DEFAULT 'test@sapdev.co.uk'.

TYPES: BEGIN OF t_ekpo,
  ebeln TYPE ekpo-ebeln,
  ebelp TYPE ekpo-ebelp,
  aedat TYPE ekpo-aedat,
  matnr TYPE ekpo-matnr,
 END OF t_ekpo.
DATA: it_ekpo TYPE STANDARD TABLE OF t_ekpo INITIAL SIZE 0,
      wa_ekpo TYPE t_ekpo.

TYPES: BEGIN OF t_charekpo,
  ebeln(10) TYPE c,
  ebelp(5)  TYPE c,
  aedat(8)  TYPE c,
  matnr(18) TYPE c,
 END OF t_charekpo.
DATA: wa_charekpo TYPE t_charekpo.

DATA:   it_message TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                WITH HEADER LINE.
DATA:   it_attach TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                WITH HEADER LINE.

DATA:   t_packing_list LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
        t_contents LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        t_receivers LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
        t_attachment LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        t_object_header LIKE solisti1 OCCURS 0 WITH HEADER LINE,
        w_cnt TYPE i,
        w_sent_all(1) TYPE c,
        w_doc_data LIKE sodocchgi1,
        gd_error    TYPE sy-subrc,
        gd_reciever TYPE sy-subrc.

************************************************************************
*START_OF_SELECTION
START-OF-SELECTION.
*   Retrieve sample data from table ekpo
  PERFORM data_retrieval.

*   Populate table with details to be entered into .xls file
  PERFORM build_xls_data_table.

************************************************************************
*END-OF-SELECTION
END-OF-SELECTION.
* Populate message body text
  PERFORM populate_email_message_body.

* Send file by email as .xls speadsheet
  PERFORM send_file_as_email_attachment
                               TABLES it_message
                                      it_attach
                                USING p_email
                                      'Example .xls document attachment'
                                      'XLS'
                                      'filename'
                                      ' '
                                      ' '
                                      ' '
                             CHANGING gd_error
                                      gd_reciever.

*   Instructs mail send program for SAPCONNECT to send email(rsconn01)
  PERFORM initiate_mail_execute_program.

*&---------------------------------------------------------------------*
*&      Form  DATA_RETRIEVAL
*&---------------------------------------------------------------------*
*       Retrieve data form EKPO table and populate itab it_ekko
*----------------------------------------------------------------------*
FORM data_retrieval.
  SELECT ebeln ebelp aedat matnr
   UP TO 10 ROWS
    FROM ekpo
    INTO TABLE it_ekpo.
ENDFORM.                    " DATA_RETRIEVAL

*&---------------------------------------------------------------------*
*&      Form  BUILD_XLS_DATA_TABLE
*&---------------------------------------------------------------------*
*       Build data table for .xls document
*----------------------------------------------------------------------*
FORM build_xls_data_table.
  CONSTANTS: con_cret TYPE x VALUE '0D',  "OK for non Unicode
             con_tab TYPE x VALUE '09'.   "OK for non Unicode

*If you have Unicode check active in program attributes then you will
*need to declare constants as follows
*class cl_abap_char_utilities definition load.
*constants:
*    con_tab  type c value cl_abap_char_utilities=>HORIZONTAL_TAB,
*    con_cret type c value cl_abap_char_utilities=>CR_LF.

  CONCATENATE 'EBELN' 'EBELP' 'AEDAT' 'MATNR'
         INTO it_attach SEPARATED BY con_tab.
  CONCATENATE con_cret it_attach  INTO it_attach.
  APPEND  it_attach.

  LOOP AT it_ekpo INTO wa_charekpo.
    CONCATENATE wa_charekpo-ebeln wa_charekpo-ebelp
                wa_charekpo-aedat wa_charekpo-matnr
           INTO it_attach SEPARATED BY con_tab.
    CONCATENATE con_cret it_attach  INTO it_attach.
    APPEND  it_attach.
  ENDLOOP.
ENDFORM.                    " BUILD_XLS_DATA_TABLE

*&---------------------------------------------------------------------*
*&      Form  SEND_FILE_AS_EMAIL_ATTACHMENT
*&---------------------------------------------------------------------*
*       Send email
*----------------------------------------------------------------------*
FORM send_file_as_email_attachment TABLES pit_message
                                          pit_attach
                                    USING p_email
                                          p_mtitle
                                          p_format
                                          p_filename
                                          p_attdescription
                                          p_sender_address
                                          p_sender_addres_type
                                 CHANGING p_error
                                          p_reciever.

  DATA: ld_error    TYPE sy-subrc,
        ld_reciever TYPE sy-subrc,
        ld_mtitle LIKE sodocchgi1-obj_descr,
        ld_email LIKE  somlreci1-receiver,
        ld_format TYPE  so_obj_tp ,
        ld_attdescription TYPE  so_obj_nam ,
        ld_attfilename TYPE  so_obj_des ,
        ld_sender_address LIKE  soextreci1-receiver,
        ld_sender_address_type LIKE  soextreci1-adr_typ,
        ld_receiver LIKE  sy-subrc.

  ld_email   = p_email.
  ld_mtitle = p_mtitle.
  ld_format              = p_format.
  ld_attdescription      = p_attdescription.
  ld_attfilename         = p_filename.
  ld_sender_address      = p_sender_address.
  ld_sender_address_type = p_sender_addres_type.

* Fill the document data.
  w_doc_data-doc_size = 1.

* Populate the subject/generic message attributes
  w_doc_data-obj_langu = sy-langu.
  w_doc_data-obj_name  = 'SAPRPT'.
  w_doc_data-obj_descr = ld_mtitle .
  w_doc_data-sensitivty = 'F'.

* Fill the document data and get size of attachment
  CLEAR w_doc_data.
  READ TABLE it_attach INDEX w_cnt.
  w_doc_data-doc_size =
     ( w_cnt - 1 ) * 255 + strlen( it_attach ).
  w_doc_data-obj_langu  = sy-langu.
  w_doc_data-obj_name   = 'SAPRPT'.
  w_doc_data-obj_descr  = ld_mtitle.
  w_doc_data-sensitivty = 'F'.
  CLEAR t_attachment.
  REFRESH t_attachment.
  t_attachment[] = pit_attach[].

* Describe the body of the message
  CLEAR t_packing_list.
  REFRESH t_packing_list.
  t_packing_list-transf_bin = space.
  t_packing_list-head_start = 1.
  t_packing_list-head_num = 0.
  t_packing_list-body_start = 1.
  DESCRIBE TABLE it_message LINES t_packing_list-body_num.
  t_packing_list-doc_type = 'RAW'.
  APPEND t_packing_list.

* Create attachment notification
  t_packing_list-transf_bin = 'X'.
  t_packing_list-head_start = 1.
  t_packing_list-head_num   = 1.
  t_packing_list-body_start = 1.

  DESCRIBE TABLE t_attachment LINES t_packing_list-body_num.
  t_packing_list-doc_type   =  ld_format.
  t_packing_list-obj_descr  =  ld_attdescription.
  t_packing_list-obj_name   =  ld_attfilename.
  t_packing_list-doc_size   =  t_packing_list-body_num * 255.
  APPEND t_packing_list.

* Add the recipients email address
  CLEAR t_receivers.
  REFRESH t_receivers.
  t_receivers-receiver = ld_email.
  t_receivers-rec_type = 'U'.
  t_receivers-com_type = 'INT'.
  t_receivers-notif_del = 'X'.
  t_receivers-notif_ndel = 'X'.
  APPEND t_receivers.

  CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
    EXPORTING
      document_data              = w_doc_data
      put_in_outbox              = 'X'
      sender_address             = ld_sender_address
      sender_address_type        = ld_sender_address_type
      commit_work                = 'X'
    IMPORTING
      sent_to_all                = w_sent_all
    TABLES
      packing_list               = t_packing_list
      contents_bin               = t_attachment
      contents_txt               = it_message
      receivers                  = t_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.

* Populate zerror return code
  ld_error = sy-subrc.

* Populate zreceiver return code
  LOOP AT t_receivers.
    ld_receiver = t_receivers-retrn_code.
  ENDLOOP.
ENDFORM.                    "send_file_as_email_attachment

*&---------------------------------------------------------------------*
*&      Form  INITIATE_MAIL_EXECUTE_PROGRAM
*&---------------------------------------------------------------------*
*       Instructs mail send program for SAPCONNECT to send email.
*----------------------------------------------------------------------*
FORM initiate_mail_execute_program.
  WAIT UP TO 2 SECONDS.
  SUBMIT rsconn01 WITH mode = 'INT'
                WITH output = 'X'
                AND RETURN.
ENDFORM.                    " INITIATE_MAIL_EXECUTE_PROGRAM

*&---------------------------------------------------------------------*
*&      Form  POPULATE_EMAIL_MESSAGE_BODY
*&---------------------------------------------------------------------*
*        Populate message body text
*----------------------------------------------------------------------*
FORM populate_email_message_body.
  REFRESH it_message.
  it_message = 'Please find attached a list test ekpo records'.
  APPEND it_message.
ENDFORM.                    " POPULATE_EMAIL_MESSAGE_BODY

Sending Mails - Home Page

Hi,

https://forums.sdn.sap.com/thread.jspa?messageID=3065528&#30655283065528

https://forums.sdn.sap.com/thread.jspa?messageID=2959234&#29592342959234

https://forums.sdn.sap.com/thread.jspa?messageID=2571717&#25717172571717

https://forums.sdn.sap.com/thread.jspa?messageID=2989716&#29897162989716

https://forums.sdn.sap.com/thread.jspa?messageID=2933362&#29333622933362

 There are many threads like this to send external and internal emails from SAP. I thought to consolidate them. So, here is the code to send email from SAP with and with out attachments.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT zemail.

DATA: itcpo LIKE itcpo,
      tab_lines LIKE sy-tabix.

* Variables for EMAIL functionality
DATA: maildata   LIKE sodocchgi1.
DATA: mailpack   LIKE sopcklsti1 OCCURS 2 WITH HEADER LINE.
DATA: mailhead   LIKE solisti1 OCCURS 1 WITH HEADER LINE.
DATA: mailbin    LIKE solisti1 OCCURS 10 WITH HEADER LINE.
DATA: mailtxt    LIKE solisti1 OCCURS 10 WITH HEADER LINE.
DATA: mailrec    LIKE somlrec90 OCCURS 0  WITH HEADER LINE.
DATA: solisti1   LIKE solisti1 OCCURS 0 WITH HEADER LINE.


PERFORM send_form_via_email.


************************************************************************
*       FORM  SEND_FORM_VIA_EMAIL                                      *
************************************************************************
FORM  send_form_via_email.

  CLEAR:    maildata, mailtxt, mailbin, mailpack, mailhead, mailrec.
  REFRESH:  mailtxt, mailbin, mailpack, mailhead, mailrec.

* Creation of the document to be sent File Name
  maildata-obj_name = 'TEST'.
* Mail Subject
  maildata-obj_descr = 'Subject'.

* Mail Contents
  mailtxt-line = 'Here is your file'.
  APPEND mailtxt.

* Prepare Packing List
  PERFORM prepare_packing_list.

* Set recipient - email address here!!!
  mailrec-receiver = 'you@yourcompany.com'.
  mailrec-rec_type  = 'U'.
  APPEND mailrec.

* Sending the document
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = maildata
      put_in_outbox              = ' '
    TABLES
      packing_list               = mailpack
      object_header              = mailhead
      contents_bin               = mailbin
      contents_txt               = mailtxt
      receivers                  = mailrec
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      operation_no_authorization = 4
      OTHERS                     = 99.

  IF sy-subrc = 0.
    SUBMIT rsconn01 WITH mode = 'INT' AND RETURN.
  ENDIF.

ENDFORM.                    "send_form_via_email

************************************************************************
*      Form  PREPARE_PACKING_LIST
************************************************************************
FORM prepare_packing_list.

  CLEAR:    mailpack, mailbin, mailhead.
  REFRESH:  mailpack, mailbin, mailhead.

  DESCRIBE TABLE mailtxt LINES tab_lines.
  READ TABLE mailtxt INDEX tab_lines.
  maildata-doc_size = ( tab_lines - 1 ) * 255 + strlen( mailtxt ).

* Creation of the entry for the compressed document
  CLEAR mailpack-transf_bin.
  mailpack-head_start = 1.
  mailpack-head_num = 0.
  mailpack-body_start = 1.
  mailpack-body_num = tab_lines.
  mailpack-doc_type = 'RAW'.
  APPEND mailpack.

  mailhead = 'TEST.TXT'.
  APPEND mailhead.



* File 1
  mailbin = 'This is file 1'.
  APPEND mailbin.

  DESCRIBE TABLE mailbin LINES tab_lines.

  mailpack-transf_bin = 'X'.
  mailpack-head_start = 1.
  mailpack-head_num = 1.
  mailpack-body_start = 1.
  mailpack-body_num = tab_lines.
  mailpack-doc_type = 'TXT'.
  mailpack-obj_name = 'TEST1'.
  mailpack-obj_descr = 'Subject'.
  mailpack-doc_size = tab_lines * 255.
  APPEND mailpack.



*File 2
  mailbin = 'This is file 2'.
  APPEND mailbin.

  DATA: start TYPE i.
  DATA: end TYPE i.

  start = tab_lines + 1.

  DESCRIBE TABLE mailbin LINES end.

  mailpack-transf_bin = 'X'.
  mailpack-head_start = 1.
  mailpack-head_num = 1.
  mailpack-body_start = start.
  mailpack-body_num = end.
  mailpack-doc_type = 'TXT'.
  mailpack-obj_name = 'TEST2'.
  mailpack-obj_descr = 'Subject'.
  mailpack-doc_size = tab_lines * 255.
  APPEND mailpack.


ENDFORM.                    "prepare_packing_list

*With PDF Attachment:*
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
  EXPORTING
    formname = 'Z_TEST'
  IMPORTING
    fm_name  = v_fname.

CALL FUNCTION v_fname
  EXPORTING
    control_parameters = x_ctrl_p
  IMPORTING
    job_output_info    = x_output_data.

CALL FUNCTION 'CONVERT_OTF'
  EXPORTING
    format                = 'PDF'
    max_linewidth         = 134
  IMPORTING
    bin_filesize          = v_size
  TABLES
    otf                   = x_output_data-otfdata
    lines                 = it_lines
  EXCEPTIONS
    err_max_linewidth     = 1
    err_format            = 2
    err_conv_not_possible = 3
    OTHERS                = 4.

CALL FUNCTION 'SX_TABLE_LINE_WIDTH_CHANGE'
  EXPORTING
    line_width_dst              = 255
  TABLES
    content_in                  = it_lines
    content_out                 = it_soli
  EXCEPTIONS
    err_line_width_src_too_long = 1
    err_line_width_dst_too_long = 2
    err_conv_failed             = 3
    OTHERS                      = 4.

CALL FUNCTION 'FUNC_CONVERT_DATA_ODC01'
  EXPORTING
    iv_byte_mode = 'X'
  TABLES
    it_data      = it_lines
    et_data      = it_table.

*-----To caluculate total number of lines of internal table
DESCRIBE TABLE it_table LINES v_lines.

*-----Create Message Body and Title and Description
it_mess = 'successfully converted smartform from otf format to pdf' .
APPEND it_mess.

wa_doc_data-obj_name = 'smartform'.
wa_doc_data-expiry_dat = sy-datum + 10.
wa_doc_data-obj_descr = 'smartform'.
wa_doc_data-sensitivty = 'F'.
wa_doc_data-doc_size = v_lines * 255.
APPEND it_pcklist.

*-----PDF Attachment
it_pcklist-transf_bin = 'X'.
it_pcklist-head_start = 1.
it_pcklist-head_num = 0.
it_pcklist-body_start = 1.
it_pcklist-doc_size = v_lines_bin * 255 .
it_pcklist-body_num = v_lines.
it_pcklist-doc_type = 'PDF'.
it_pcklist-obj_name = 'smartform'.
it_pcklist-obj_descr = 'smart_desc'.
it_pcklist-obj_langu = 'E'.
it_pcklist-doc_size = v_lines * 255.
APPEND it_pcklist.

*-----Giving the receiver email-id
CLEAR it_receivers.
it_receivers-receiver = 'abcd@yahoo.com'.
it_receivers-rec_type = 'U'.
APPEND it_receivers.

*-----Calling the function module to sending email
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
  EXPORTING
    document_data              = wa_doc_data
    put_in_outbox              = 'X'
    commit_work                = 'X'
  TABLES
    packing_list               = it_pcklist
    contents_txt               = it_mess
    contents_hex               = it_table
    receivers                  = it_receivers
  EXCEPTIONS
    too_many_receivers         = 1
    document_not_sent          = 2
    document_type_not_exist    = 3
    operation_no_authorization = 4
    parameter_error            = 5
    x_error                    = 6
    enqueue_error              = 7
    OTHERS                     = 8.

Here is the sample code for Emailing reports in HTML format

Code listing for: ZEMAIL
Description: Email Reports in HTML Format

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
REPORT zemail.

DATA: send_request TYPE REF TO cl_bcs.
DATA: text TYPE bcsy_text.
DATA: document TYPE REF TO cl_document_bcs.
DATA: sender_id TYPE REF TO if_sender_bcs.
DATA: recipient TYPE REF TO if_recipient_bcs.
DATA: bcs_exception TYPE REF TO cx_bcs.
DATA: sent_to_all TYPE os_boolean.
DATA: conlength TYPE i ,
      conlengths TYPE so_obj_len ,
      result_content TYPE string .
DATA: content_length TYPE w3param-cont_len ,
      content_type TYPE w3param-cont_type,
      return_code TYPE w3param-ret_code .
DATA: listobject TYPE TABLE OF abaplist.
DATA: html_wa TYPE w3html.
DATA: html TYPE STANDARD TABLE OF w3html .
DATA: wa_rec TYPE ad_smtpadr .
DATA: bcs_message TYPE string .
DATA: tmp_str TYPE string .
DATA: prog TYPE programm ,
      var TYPE raldb_vari .

DATA: recepients TYPE bcsy_smtpa WITH HEADER LINE,
      return TYPE table_of_strings.
DATA : v_rec(40).


SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
PARAMETERS: report TYPE program,
            variant TYPE raldb_vari,
            sender TYPE ad_smtpadr,
            subject TYPE so_obj_des.
SELECT-OPTIONS: s_rec FOR v_rec NO INTERVALS LOWER CASE.
SELECTION-SCREEN END OF BLOCK b1.

LOOP AT s_rec.
  TRANSLATE s_rec-low TO LOWER CASE.
  recepients = s_rec-low.

  APPEND recepients.
  CLEAR recepients .
ENDLOOP.
*recepients = 'seckharmc@gmail.com'.
*append recepients.

IF NOT recepients[] IS INITIAL .
  CLEAR: var, prog .
  MOVE: report TO prog ,
        variant TO var .
  TRANSLATE prog TO UPPER CASE .
  TRANSLATE var TO UPPER CASE .

  SUBMIT (prog) USING SELECTION-SET var EXPORTING LIST TO MEMORY AND RETURN.
  CLEAR: listobject , html .
  REFRESH : listobject, html .
  CALL FUNCTION 'LIST_FROM_MEMORY'
    TABLES
      listobject = listobject.
  CALL FUNCTION 'WWW_HTML_FROM_LISTOBJECT'
    EXPORTING
      report_name = prog
    TABLES
      html        = html
      listobject  = listobject.
  CLEAR tmp_str .
  CLEAR : html_wa .

  LOOP AT html INTO html_wa .
    CONCATENATE tmp_str html_wa INTO tmp_str.
  ENDLOOP .
  CLEAR: conlength,conlengths .
  conlength = strlen( tmp_str ) .
  conlengths = conlength .
  TRY.
      CLEAR send_request .
      send_request = cl_bcs=>create_persistent( ).
      CLEAR document .
      document = cl_document_bcs=>create_document(
                    i_type = 'HTM'
                    i_text = html
                    i_length = conlengths
                    i_subject = subject ).

* add document to send request
      CALL METHOD send_request->set_document( document ).
      CLEAR sender_id .
      sender_id = cl_cam_address_bcs=>create_internet_address( sender ).
      CALL METHOD send_request->set_sender
        EXPORTING
          i_sender = sender_id.
      CLEAR wa_rec .
      LOOP AT recepients INTO wa_rec .
        CLEAR recipient .
        recipient = cl_cam_address_bcs=>create_internet_address( wa_rec ).
* add recipient with its respective attributes to send request
        CALL METHOD send_request->add_recipient
          EXPORTING
            i_recipient = recipient
            i_express   = 'X'.

      ENDLOOP .
      CALL METHOD send_request->set_status_attributes
        EXPORTING
          i_requested_status = 'E'
          i_status_mail      = 'E'.
      CALL METHOD send_request->set_send_immediately( 'X' ).

* ---------- send document ---------------------------------------
      CALL METHOD send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = sent_to_all ).
      IF sent_to_all = 'X'.
        APPEND 'Mail sent successfully ' TO return .
        WRITE:/ 'Mail sent successfully '.
      ENDIF.
      COMMIT WORK.
    CATCH cx_bcs INTO bcs_exception.
      bcs_message = bcs_exception->get_text( ).
      APPEND bcs_message TO return .
      EXIT.
  ENDTRY.
ELSE .
  APPEND 'Specify email address for sending' TO return .
ENDIF .

*Selection texts
*--------------------------------------------------------------------*
* REPORT Program Name
* SENDER Sender's E-Mail ID
* SUBJECT D .
* S_REC Receiver Email IDs
* VARIANT D .
*--------------------------------------------------------------------*
REPORT z_demo_mail.

*&---------------------------------------------------------------------*
*& Global data declaration
*&---------------------------------------------------------------------*

DATA:
w_document_data LIKE sodocchgi1.

DATA:
i_object_header TYPE STANDARD TABLE OF solisti1,
w_object_header TYPE solisti1,

i_object_content TYPE STANDARD TABLE OF solisti1,
w_object_content TYPE solisti1,

i_contents_hex TYPE STANDARD TABLE OF solix,
w_contents_hex TYPE solix,

i_object_para TYPE STANDARD TABLE OF soparai1,
w_object_para TYPE soparai1,

i_object_parb TYPE STANDARD TABLE OF soparbi1,
w_object_parb TYPE soparbi1,

i_receivers TYPE STANDARD TABLE OF somlreci1,
w_receivers TYPE somlreci1.

*&---------------------------------------------------------------------*
*& Selection screen
*&---------------------------------------------------------------------*
PARAMETER : uname TYPE syuname DEFAULT sy-uname.

*&---------------------------------------------------------------------*
*& Start-of-selection event
*&---------------------------------------------------------------------*
START-OF-SELECTION.

* Populate receiver info
  CLEAR: w_receivers.
  w_receivers-receiver = uname.
  w_receivers-rec_type = 'B'.
  APPEND w_receivers TO i_receivers.

* Populate header data
  w_document_data-obj_name = 'Your action required'.
  w_document_data-obj_descr = 'Pl. press execute button'.
  w_document_data-sensitivty = 'O'.
  w_document_data-proc_type = 'R'.
  w_document_data-proc_name = 'RSINCL00'.


* Populate mail content
  CLEAR: w_object_content.
  CONCATENATE 'Please execute report: '
  w_document_data-proc_name
  INTO w_object_content-line SEPARATED BY space.
  APPEND w_object_content TO i_object_content.


  CALL FUNCTION 'SO_NEW_DOCUMENT_SEND_API1'
    EXPORTING
      document_data              = w_document_data
      document_type              = 'RAW'
    TABLES
      object_content             = i_object_content
      object_para                = i_object_para
      receivers                  = i_receivers
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
  IF sy-subrc = 0.
    MESSAGE s000(z_zzz_ca_messages)
    WITH 'Mail send successfully'(001).
  ENDIF.
 

 

 

Author: Himanshu Kanekar
Submitted: 14-Oct-2010
Related Links:


A very common requirement by the user is to export data to a Formatted Microsoft Excel Spreadsheet and send it to an Email or post it on a FTP Server.  If the report is a simple ALV grid then the ALV control can do it automatically, but it would be a simple Excel Spreadsheet without any formatting. In order to create a Formatted Excel Sheet we can either use the OLE (Object Linking & Enabling) Concept or the XML method.

The OLE method involves opening an instance of Microsoft Excel and then preparing the sheet. The major disadvantage of this method is that it can be executed in Foreground only.

An ABAP Program can create an XML file and it can be opened directly into Excel.  The advantages and possibilities are endless:

  • An xml file is plain text so can be created on the Presentation Server or Application Server;
  • It can be sent as an Attachment to an Email;
  • Colours, Fonts, Number Formats and so on can be specified;
  • Formatting can be applied to Rows, Columns or Single Cells;
  • Column Heights and Widths can be specified, or Auto-Formatted;
  • Multiple Worksheets can be created;
  • Formulas can be entered in cells;

This is a Sample Code for fetching the User Login Details and sending it as an XLS attachment to an Email using the XML method -

REPORT  sy-repid.

TYPE-POOLS: ixml.

*------------------------------------------------------------------------*
*                           Data Declarations                            *
*------------------------------------------------------------------------*

* Structure for Final Internal Table
TYPES: BEGIN OF ty_final,
        srno(3) TYPE n,
        user_id TYPE usr02-bname,
        full_name TYPE bapiaddr3-fullname,
        dept TYPE bapiaddr3-department,
        login(3) TYPE c,
       END OF ty_final.

* Structure for USR02
TYPES: BEGIN OF ty_usr02,
        bname TYPE usr02-bname,
        trdat TYPE usr02-trdat,
       END OF ty_usr02.

* Internal Table & Work Area for Final Internal Table
DATA: it_final TYPE TABLE OF ty_final,
      wa_final TYPE ty_final.

* Internal Table & Work Area for USR02 Internal Table
DATA: it_usr02 TYPE TABLE OF ty_usr02,
      wa_usr02 TYPE ty_usr02.

* Work Area for ADD3_DATA Structre
DATA: wa_addr TYPE bapiaddr3.
DATA: it_return TYPE TABLE OF bapiret2.

DATA: lv_date TYPE d.
DATA: lv_filename TYPE string.

TYPES: BEGIN OF xml_line,
        data(255) TYPE x,
       END OF xml_line.

DATA: l_ixml            TYPE REF TO if_ixml,
      l_streamfactory   TYPE REF TO if_ixml_stream_factory,
      l_ostream         TYPE REF TO if_ixml_ostream,
      l_renderer        TYPE REF TO if_ixml_renderer,
      l_document        TYPE REF TO if_ixml_document.

DATA: l_element_root        TYPE REF TO if_ixml_element,
      ns_attribute          TYPE REF TO if_ixml_attribute,
      r_element_properties  TYPE REF TO if_ixml_element,
      r_element             TYPE REF TO if_ixml_element,
      r_worksheet           TYPE REF TO if_ixml_element,
      r_table               TYPE REF TO if_ixml_element,
      r_column              TYPE REF TO if_ixml_element,
      r_row                 TYPE REF TO if_ixml_element,
      r_cell                TYPE REF TO if_ixml_element,
      r_data                TYPE REF TO if_ixml_element,
      l_value               TYPE string,
      l_type                TYPE string,
      l_text(100)           TYPE c,
      r_styles              TYPE REF TO if_ixml_element,
      r_style               TYPE REF TO if_ixml_element,
      r_style1              TYPE REF TO if_ixml_element,
      r_format              TYPE REF TO if_ixml_element,
      r_border              TYPE REF TO if_ixml_element,
      num_rows              TYPE i.

DATA: l_xml_table       TYPE TABLE OF xml_line,
      wa_xml            TYPE xml_line,
      l_xml_size        TYPE i,
      l_rc              TYPE i.


*------------------------------------------------------------------------*
*                             Initialization                             *
*------------------------------------------------------------------------*

INITIALIZATION.
  lv_date = sy-datum - 1.


*------------------------------------------------------------------------*
*                           Start of Selection                           *
*------------------------------------------------------------------------*

START-OF-SELECTION.

  PERFORM get_user_data.
  PERFORM process_xml_data.
  PERFORM send_mail.


*&---------------------------------------------------------------------*
*&      Form  get_user_data
*&---------------------------------------------------------------------*
*       Fetch User details from USR02
*----------------------------------------------------------------------*

FORM get_user_data.

  REFRESH it_final.
  SELECT DISTINCT bname trdat FROM usr02 INTO TABLE it_usr02.
  SORT it_usr02 BY bname.

  IF NOT it_usr02[] IS INITIAL.

    LOOP AT it_usr02 INTO wa_usr02.

      CLEAR wa_final.
      wa_final-srno = sy-tabix.                   " Serial No.
      wa_final-user_id = wa_usr02-bname.          " User ID

      CALL FUNCTION 'BAPI_USER_GET_DETAIL'
        EXPORTING
          username = wa_usr02-bname
        IMPORTING
          address  = wa_addr
        TABLES
          return   = it_return.

      IF sy-subrc EQ 0.
        wa_final-full_name = wa_addr-fullname.    " Full Name
        wa_final-dept = wa_addr-department.       " Department
      ENDIF.

      IF wa_usr02-trdat EQ lv_date.
        wa_final-login = 'YES'.                   " Login on Previous Day
      ELSE.
        wa_final-login = 'NO'.
      ENDIF.

      APPEND wa_final TO it_final.

    ENDLOOP.

  ENDIF.

ENDFORM.                    " get_user_data


*&---------------------------------------------------------------------*
*&      Form  SEND_MAIL
*&---------------------------------------------------------------------*
*       Send Email
*----------------------------------------------------------------------*

FORM send_mail.

  DATA: objpack   LIKE sopcklsti1 OCCURS 2 WITH HEADER LINE.
  DATA: objhead   LIKE solisti1 OCCURS 1 WITH HEADER LINE.
  DATA: objbin    LIKE solix OCCURS 10 WITH HEADER LINE.
  DATA: objtxt    LIKE solisti1 OCCURS 10 WITH HEADER LINE.
  DATA: reclist   LIKE somlreci1 OCCURS 5 WITH HEADER LINE.
  DATA: doc_chng  LIKE sodocchgi1.
  DATA: tab_lines LIKE sy-tabix.
  DATA: l_num(3).
  DATA: subj_date(10) TYPE c.

* Mail Subject
  CONCATENATE lv_date+6(2) '-' lv_date+4(2) '-' lv_date+0(4) INTO subj_date.
  CONCATENATE 'SAP Application Usage Report ' subj_date INTO doc_chng-obj_descr SEPARATED BY space.

* Mail Contents
  objtxt = 'Dear User,'.
  APPEND objtxt.

  CLEAR objtxt.
  APPEND objtxt.

  CONCATENATE 'Please find the attached SAP Application Usage Report for ' subj_date INTO objtxt SEPARATED BY space.              " Mail Contents
  APPEND objtxt.

  CLEAR objtxt.
  APPEND objtxt.

  objtxt = 'Thanks & Regards,'.
  APPEND objtxt.

  objtxt = 'Himanshu Kanekar'.
  APPEND objtxt.

  DESCRIBE TABLE objtxt LINES tab_lines.
  READ TABLE objtxt INDEX tab_lines.
  doc_chng-doc_size = ( tab_lines - 1 ) * 255 + STRLEN( objtxt ).

* Packing List For the E-mail Body
  objpack-head_start = 1.
  objpack-head_num   = 0.
  objpack-body_start = 1.
  objpack-body_num   = tab_lines.
  objpack-doc_type   = 'RAW'.
  APPEND objpack.

* Creation of the Document Attachment
  LOOP AT l_xml_table INTO wa_xml.
    CLEAR objbin.
    objbin-line = wa_xml-data.
    APPEND objbin.
  ENDLOOP.

  DESCRIBE TABLE objbin LINES tab_lines.
  objhead = 'SAP Login Details'.
  APPEND objhead.

* Packing List For the E-mail Attachment
  objpack-transf_bin = 'X'.
  objpack-head_start = 1.
  objpack-head_num   = 0.
  objpack-body_start = 1.
  objpack-body_num = tab_lines.
  CONCATENATE 'SAP_Login_Details' subj_date INTO objpack-obj_descr SEPARATED BY space.
  objpack-doc_type = 'XLS'.
  objpack-doc_size = tab_lines * 255.
  APPEND objpack.

* Target Recipent
  CLEAR reclist.
  reclist-receiver = 'user@company.com'.
  reclist-rec_type = 'U'.
  APPEND reclist.

* Sending the document
  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = doc_chng
      put_in_outbox              = 'X'
    TABLES
      packing_list               = objpack
      object_header              = objhead
      contents_txt               = objtxt
      contents_hex               = objbin
      receivers                  = reclist
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      operation_no_authorization = 4
      OTHERS                     = 99.

ENDFORM.                    " SEND_MAIL



*&---------------------------------------------------------------------*
*&      Form  process_xml_data
*&---------------------------------------------------------------------*
*       Process XML Data
*----------------------------------------------------------------------*

FORM process_xml_data .

* Creating a ixml Factory
  l_ixml = cl_ixml=>create( ).

* Creating the DOM Object Model
  l_document = l_ixml->create_document( ).

* Create Root Node 'Workbook'
  l_element_root  = l_document->create_simple_element( name = 'Workbook'  parent = l_document ).
  l_element_root->set_attribute( name = 'xmlns'  value = 'urn:schemas-microsoft-com:office:spreadsheet' ).

  ns_attribute = l_document->create_namespace_decl( name = 'ss'  prefix = 'xmlns'  uri = 'urn:schemas-microsoft-com:office:spreadsheet' ).
  l_element_root->set_attribute_node( ns_attribute ).

  ns_attribute = l_document->create_namespace_decl( name = 'x'  prefix = 'xmlns'  uri = 'urn:schemas-microsoft-com:office:excel' ).
  l_element_root->set_attribute_node( ns_attribute ).

* Create node for document properties.
  r_element_properties = l_document->create_simple_element( name = 'TEST_REPORT'  parent = l_element_root ).
  l_value = sy-uname.
  l_document->create_simple_element( name = 'Author'  value = l_value  parent = r_element_properties  ).

* Styles
  r_styles = l_document->create_simple_element( name = 'Styles'  parent = l_element_root  ).

* Style for Header
  r_style  = l_document->create_simple_element( name = 'Style'   parent = r_styles  ).
  r_style->set_attribute_ns( name = 'ID'  prefix = 'ss'  value = 'Header' ).

  r_format  = l_document->create_simple_element( name = 'Font'  parent = r_style  ).
  r_format->set_attribute_ns( name = 'Bold'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Interior' parent = r_style  ).
  r_format->set_attribute_ns( name = 'Color'   prefix = 'ss'  value = '#92D050' ).
  r_format->set_attribute_ns( name = 'Pattern' prefix = 'ss'  value = 'Solid' ).

  r_format  = l_document->create_simple_element( name = 'Alignment'  parent = r_style  ).
  r_format->set_attribute_ns( name = 'Vertical'  prefix = 'ss'  value = 'Center' ).
  r_format->set_attribute_ns( name = 'WrapText'  prefix = 'ss'  value = '1' ).

  r_border  = l_document->create_simple_element( name = 'Borders'  parent = r_style ).
  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Bottom' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Left' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Top' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Right' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

* Style for Data
  r_style1  = l_document->create_simple_element( name = 'Style'   parent = r_styles  ).
  r_style1->set_attribute_ns( name = 'ID'  prefix = 'ss'  value = 'Data' ).

  r_border  = l_document->create_simple_element( name = 'Borders'  parent = r_style1 ).
  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Bottom' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Left' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Top' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).

  r_format  = l_document->create_simple_element( name = 'Border'   parent = r_border  ).
  r_format->set_attribute_ns( name = 'Position'  prefix = 'ss'  value = 'Right' ).
  r_format->set_attribute_ns( name = 'LineStyle'  prefix = 'ss'  value = 'Continuous' ).
  r_format->set_attribute_ns( name = 'Weight'  prefix = 'ss'  value = '1' ).


* Worksheet
  r_worksheet = l_document->create_simple_element( name = 'Worksheet'  parent = l_element_root ).
  r_worksheet->set_attribute_ns( name = 'Name'  prefix = 'ss'  value = 'Sheet1' ).

* Table
  r_table = l_document->create_simple_element( name = 'Table'  parent = r_worksheet ).
  r_table->set_attribute_ns( name = 'FullColumns'  prefix = 'x'  value = '1' ).
  r_table->set_attribute_ns( name = 'FullRows'     prefix = 'x'  value = '1' ).

* Column Formatting
  r_column = l_document->create_simple_element( name = 'Column'  parent = r_table ).
  r_column->set_attribute_ns( name = 'Width'  prefix = 'ss'  value = '40' ).

  r_column = l_document->create_simple_element( name = 'Column'  parent = r_table ).
  r_column->set_attribute_ns( name = 'Width'  prefix = 'ss'  value = '90' ).

  r_column = l_document->create_simple_element( name = 'Column'  parent = r_table ).
  r_column->set_attribute_ns( name = 'Width'  prefix = 'ss'  value = '140' ).

  r_column = l_document->create_simple_element( name = 'Column'  parent = r_table ).
  r_column->set_attribute_ns( name = 'Width'  prefix = 'ss'  value = '150' ).

  r_column = l_document->create_simple_element( name = 'Column'  parent = r_table ).
  r_column->set_attribute_ns( name = 'Width'  prefix = 'ss'  value = '90' ).

* Blank Row
  r_row = l_document->create_simple_element( name = 'Row'  parent = r_table ).

* Column Headers Row
  r_row = l_document->create_simple_element( name = 'Row'  parent = r_table ).
  r_row->set_attribute_ns( name = 'AutoFitHeight'  prefix = 'ss'  value = '1' ).

* Sr. No.
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Header' ).
  r_data = l_document->create_simple_element( name = 'Data'  value = 'Sr. No.'  parent = r_cell ).
  r_data->set_attribute_ns( name = 'Type'  prefix = 'ss' value = 'String' ).

* User Name
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Header' ).
  r_data = l_document->create_simple_element( name = 'Data'  value = 'User Name'  parent = r_cell ).
  r_data->set_attribute_ns( name = 'Type'  prefix = 'ss' value = 'String' ).

* Full Name
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Header' ).
  r_data = l_document->create_simple_element( name = 'Data'  value = 'Full Name'  parent = r_cell ).
  r_data->set_attribute_ns( name = 'Type'  prefix = 'ss' value = 'String' ).

* Department
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Header' ).
  r_data = l_document->create_simple_element( name = 'Data'  value = 'Department'  parent = r_cell ).
  r_data->set_attribute_ns( name = 'Type'  prefix = 'ss' value = 'String' ).

* Login
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Header' ).
  CONCATENATE 'Login - ' lv_date+6(2) '/' lv_date+4(2) '/' lv_date+0(4) INTO l_value.
  r_data = l_document->create_simple_element( name = 'Data'  value = l_value  parent = r_cell ).
  r_data->set_attribute_ns( name = 'Type'  prefix = 'ss' value = 'String' ).

* Blank Row after Column Headers
  r_row = l_document->create_simple_element( name = 'Row'  parent = r_table ).
  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).

  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).

  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).

  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).

  r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
  r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).

* Data Table
  LOOP AT it_final INTO wa_final.

    r_row = l_document->create_simple_element( name = 'Row'  parent = r_table ).

* Sr. No.
    r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
    r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).
    l_value = sy-tabix.
    CONDENSE l_value NO-GAPS.
    r_data = l_document->create_simple_element( name = 'Data'  value = l_value   parent = r_cell ).           " Data
    r_data->set_attribute_ns( name = 'Type'  prefix = 'ss'  value = 'Number' ).                               " Cell format

* User Name
    r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
    r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).
    l_value = wa_final-user_id.
    r_data = l_document->create_simple_element( name = 'Data'  value = l_value   parent = r_cell ).           " Data
    r_data->set_attribute_ns( name = 'Type'  prefix = 'ss'  value = 'String' ).                               " Cell format

* Full Name
    r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
    r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).
    l_value = wa_final-full_name.
    r_data = l_document->create_simple_element( name = 'Data'  value = l_value   parent = r_cell ).           " Data
    r_data->set_attribute_ns( name = 'Type'  prefix = 'ss'  value = 'String' ).                               " Cell format

* Department
    r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
    r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).
    l_value = wa_final-dept.
    r_data = l_document->create_simple_element( name = 'Data'  value = l_value   parent = r_cell ).           " Data
    r_data->set_attribute_ns( name = 'Type'  prefix = 'ss'  value = 'String' ).                               " Cell format

* Login
    r_cell = l_document->create_simple_element( name = 'Cell'  parent = r_row ).
    r_cell->set_attribute_ns( name = 'StyleID'  prefix = 'ss'  value = 'Data' ).
    l_value = wa_final-login.
    r_data = l_document->create_simple_element( name = 'Data'  value = l_value   parent = r_cell ).          " Data
    r_data->set_attribute_ns( name = 'Type'  prefix = 'ss'  value = 'String' ).                              " Cell format

  ENDLOOP.

* Creating a Stream Factory
  l_streamfactory = l_ixml->create_stream_factory( ).

* Connect Internal XML Table to Stream Factory
  l_ostream = l_streamfactory->create_ostream_itable( table = l_xml_table ).

* Rendering the Document
  l_renderer = l_ixml->create_renderer( ostream  = l_ostream  document = l_document ).
  l_rc = l_renderer->render( ).

* Saving the XML Document
  l_xml_size = l_ostream->get_num_written_raw( ).

ENDFORM.                    " process_xml_data

The output of the Report is a Formatted Excel Sheet as an email attachment.

END-OF-SELECTION.
  IF getfile EQ 'X'.
    IF NOT t_app_letr[] IS INITIAL.
      PERFORM mail_merge_data_to_ms_word.
    ELSE.
      WRITE: / 'NO DATA AVAILABLE FOR THIS SELECTION!'.
    ENDIF.
  ENDIF.

*&---------------------------------------------------------------------*
*&      Form  MAIL_MERGE_DATA_TO_MS_WORD
*&---------------------------------------------------------------------*
* Enclosing the other sub modules for the easy maintenance
*----------------------------------------------------------------------*
* No Parameters for this subroutine
*----------------------------------------------------------------------*
FORM mail_merge_data_to_ms_word .
  PERFORM clear_existing_data_file.
  PERFORM download_employee_data_to_pc.
  PERFORM start_ms_word.
  PERFORM fill_ms_word_with_data.
ENDFORM.                    " MAIL_MERGE_DATA_TO_MS_WORD
*&---------------------------------------------------------------------*
*&      FORM  CLEAR_EXISTING_DATA_FILE
*&---------------------------------------------------------------------*
*  Clearing the existing DATA file used for Merge
*----------------------------------------------------------------------*
* No Parameters for this subroutine
*----------------------------------------------------------------------*
FORM clear_existing_data_file .
  DATA: file_name TYPE string.
  DATA: result TYPE abap_bool.
  DATA: rc TYPE i.
  file_name = twrkfile.

  CALL METHOD cl_gui_frontend_services=>file_exist
    EXPORTING
      file            = file_name
    RECEIVING
      result          = result
    EXCEPTIONS
      cntl_error      = 1
      error_no_gui    = 2
      wrong_parameter = 3
      OTHERS          = 4.

  CALL METHOD cl_gui_cfw=>flush.
  IF result EQ abap_true.
    CALL METHOD cl_gui_frontend_services=>file_delete
      EXPORTING
        filename = file_name
      CHANGING
        rc       = rc
      EXCEPTIONS
        OTHERS   = 0.

* FLUSH TO EXECUTE THE DELETION
    CALL METHOD cl_gui_cfw=>flush.
  ENDIF.

ENDFORM.                    " CLEAR_EXISTING_DATA_FILE
*&---------------------------------------------------------------------*
*&      FORM  DOWNLAOD_EMPLOYEE_DATA_TO_PC
*&---------------------------------------------------------------------*
*  Download here for e.g. employee data to PC (Data File)
*----------------------------------------------------------------------*
* No Parameters passed to this subroutine
*----------------------------------------------------------------------*
FORM download_employee_data_to_pc.
  DATA: file_name TYPE string.
  DATA: cnt TYPE i.
  DATA: lt_download TYPE STANDARD TABLE OF string,
        lv_download TYPE string,
        lv_hstr(1024) TYPE c.

  CLASS cl_abap_char_utilities DEFINITION LOAD.
  CONSTANTS: lc_tab TYPE string
                    VALUE cl_abap_char_utilities=>horizontal_tab.

  FIELD-SYMBOLS: <field> TYPE any,
                 <data_tab_wa> TYPE any.

  PERFORM get_all_field_names.

  CLEAR lv_download.
  LOOP AT fieldnames.
    WRITE fieldnames TO lv_hstr LEFT-JUSTIFIED.
    IF sy-tabix > 1.
      CONCATENATE lv_download lc_tab lv_hstr
                  INTO lv_download.
    ELSE.
      CONCATENATE lv_download lv_hstr
                  INTO lv_download.
    ENDIF.
  ENDLOOP.
  APPEND lv_download TO lt_download.

* THEN THE DATA TABLE
  LOOP AT t_app_letr
       ASSIGNING <data_tab_wa>.
    cnt = 0.
    CLEAR lv_download.
    sy-subrc = 0.
    WHILE sy-subrc = 0.
      cnt = cnt + 1.
      ASSIGN COMPONENT cnt OF STRUCTURE <data_tab_wa> TO <field>.
      CHECK sy-subrc = 0.
      WRITE <field> TO lv_hstr LEFT-JUSTIFIED.
      IF cnt > 1.
        CONCATENATE lv_download lc_tab lv_hstr
                    INTO lv_download.
      ELSE.
        CONCATENATE lv_download lv_hstr
                    INTO lv_download.
      ENDIF.
    ENDWHILE.
    APPEND lv_download TO lt_download.
  ENDLOOP.

  file_name = twrkfile.
  CALL FUNCTION 'GUI_DOWNLOAD'
    EXPORTING
      filename                = file_name
      write_field_separator   = 'X'
      trunc_trailing_blanks   = 'X'
    TABLES
      data_tab                = lt_download
    EXCEPTIONS
      file_write_error        = 1
      no_batch                = 2
      gui_refuse_filetransfer = 3
      invalid_type            = 4
      no_authority            = 5
      unknown_error           = 6
      header_not_allowed      = 7
      separator_not_allowed   = 8
      filesize_not_allowed    = 9
      header_too_long         = 10
      dp_error_create         = 11
      dp_error_send           = 12
      dp_error_write          = 13
      unknown_dp_error        = 14
      access_denied           = 15
      dp_out_of_memory        = 16
      disk_full               = 17
      dp_timeout              = 18
      file_not_found          = 19
      dataprovider_exception  = 20
      control_flush_error     = 21
      OTHERS                  = 22.
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        RAISE file_write_error.
      WHEN 2.
        RAISE no_batch.
      WHEN 3.
        RAISE gui_refuse_filetransfer.
      WHEN 4.
        RAISE invalid_type .
      WHEN 5.
        RAISE no_authority.
      WHEN 6.
        RAISE unknown_error.
      WHEN 7.
        RAISE header_not_allowed.
      WHEN 8.
        RAISE separator_not_allowed.
      WHEN 9.
        RAISE filesize_not_allowed.
      WHEN 10.
        RAISE header_too_long.
      WHEN 11.
        RAISE dp_error_create.
      WHEN 12.
        RAISE dp_error_send.
      WHEN 13.
        RAISE dp_error_write.
      WHEN 14.
        RAISE unknown_dp_error.
      WHEN 15.
        RAISE access_denied.
      WHEN 16.
        RAISE dp_out_of_memory.
      WHEN 17.
        RAISE disk_full.
      WHEN 18.
        RAISE dp_timeout.
      WHEN 19.
        RAISE file_not_found.
      WHEN 20.
        RAISE dataprovider_exception.
      WHEN 21.
        RAISE control_flush_error.
      WHEN OTHERS.
        RAISE unknown_error.
    ENDCASE.
  ENDIF.

ENDFORM.                               " DOWNLAOD_EMPLOYEE_DATA_TO_PC
*&---------------------------------------------------------------------*
*&      FORM  OPEN_MS_WORD
*&---------------------------------------------------------------------*
* Opens the MS Word Document
*----------------------------------------------------------------------*
* No parameters passed here.
*----------------------------------------------------------------------*
FORM start_ms_word .
  DATA: xcode   LIKE sy-xcode,
        ok_code LIKE sy-xcode,
        rc TYPE i,
        platform TYPE i,
        registry_entry(255) TYPE c,
        reg_value TYPE string,
        temp_dir TYPE string.
  DATA: version_str(80) TYPE c,
        word_version TYPE i.
  DATA: documents TYPE ole2_object.

* START WITH OLE AUTOMATION
  CALL METHOD cl_gui_frontend_services=>registry_get_value
    EXPORTING
      root                = cl_gui_frontend_services=>hkey_classes_root
      key                 = 'WORD.BASIC\CURVER'
      value               = ''
    IMPORTING
      reg_value           = reg_value
    EXCEPTIONS
      get_regvalue_failed = 1
      cntl_error          = 2
      error_no_gui        = 3
      OTHERS              = 4.
  IF sy-subrc <> 0.
    RAISE download_problem.
  ENDIF.
  CALL METHOD cl_gui_cfw=>flush.
  version_str = reg_value.

  SHIFT version_str LEFT BY 11 PLACES.
  MOVE version_str TO word_version.

  IF word_version < 8.
    CREATE OBJECT wordobj 'WORD.BASIC'.
  ELSE.
    CREATE OBJECT worddoc 'WORD.DOCUMENT'.
    GET PROPERTY OF worddoc 'APPLICATION' = wordapp.
    SET PROPERTY OF wordapp 'VISIBLE' = 1.
    GET PROPERTY OF wordapp 'WORDBASIC' = wordobj.
    CALL METHOD OF
        wordobj
        'FILECLOSE'.
  ENDIF.
  CALL METHOD OF
      wordobj
      'APPSHOW'.

* SERIENBRIEFDATEI ЖFFNEN
  IF word_version > 8.
    GET PROPERTY OF wordapp 'DOCUMENTS' = documents.

    CALL METHOD OF
        documents
        'OPEN'

      EXPORTING
        #01       = dwrkfile  "FILE NAME
        #02       = 0.              "CONFIRM CONVERSION
  ELSE.
    CALL METHOD OF
        wordobj
        'FILEOPEN'

      EXPORTING
        #01        = dwrkfile
        #02        = 0.
  ENDIF.

ENDFORM.                    " OPEN_MS_WORD
*&---------------------------------------------------------------------*
*&      FORM  FILL_MS_WORD_WITH_DATA
*&---------------------------------------------------------------------*
* Fills the MS word merge fields with data
*----------------------------------------------------------------------*
* No parameters passed for this subroutine
*----------------------------------------------------------------------*
FORM fill_ms_word_with_data .
  DATA: passwort(15).
  CALL METHOD OF
      wordobj
      'MAILMERGEMAINDOCUMENTTYPE'

    EXPORTING
      #01                         = 0.
  CALL METHOD OF
      wordobj
      'MAILMERGEOPENDATASOURCE'

    EXPORTING
      #01                       = twrkfile
      #02                       = 0
      #03                       = 1
      #04                       = 0
      #05                       = 0
      #06                       = passwort.
  CALL METHOD OF
      wordobj
      'MAILMERGEEDITMAINDOCUMENT'.
  CALL METHOD OF
      wordobj
      'MAILMERGETODOC'.

ENDFORM.                    " FILL_MS_WORD_WITH_DATA
*&---------------------------------------------------------------------*
*&      FORM  GET_ALL_FIELD_NAMES
*&---------------------------------------------------------------------*
*  Gets all the field names from the input word file name
*----------------------------------------------------------------------*
* No parameters for this subroutine.
*----------------------------------------------------------------------*
FORM get_all_field_names.
  TYPE-POOLS: sydes.
  TYPE-POOLS slis.
  DATA:  td TYPE sydes_desc.
  DATA: name_header TYPE sydes_nameinfo.
  DATA: name LIKE name_header.
  DATA: types_header TYPE sydes_typeinfo.
  DATA: type LIKE types_header.
  DATA: prev_tabix LIKE sy-tabix.
  DATA: continue_field(1) TYPE c.
  DATA: search_str(40) TYPE c.
  DATA: s_length(5) TYPE p.

  DATA: BEGIN OF stru_tab OCCURS 0,
          name(30) TYPE c,
          fldname(30) TYPE c,
          index    LIKE sy-tabix,
          length(3) TYPE n,
          type(1)   TYPE c,
          decimals(2) TYPE n,
        END OF stru_tab.

  CLEAR: td.
  DESCRIBE FIELD t_app_letr INTO td.

  CLEAR: stru_tab[], stru_tab.
  DO 1000 TIMES.
    READ TABLE td-types INTO types_header INDEX sy-index.
    IF sy-subrc NE 0.
      EXIT.
    ENDIF.
    type = types_header.
    stru_tab-index = type-idx_name.
    stru_tab-type  = type-type.
    stru_tab-length = type-length.
    stru_tab-decimals = type-decimals.
    CHECK stru_tab-index NE 0.
    APPEND stru_tab.
  ENDDO.

  DO 1000 TIMES.
    READ TABLE td-names INTO name_header INDEX sy-index.
    IF sy-subrc NE 0.
      EXIT.
    ENDIF.
    name = name_header.
    IF continue_field NE space.
      READ TABLE stru_tab INDEX prev_tabix.
      IF sy-subrc EQ 0.
        CONCATENATE stru_tab-fldname name-name INTO stru_tab-fldname.
        MODIFY stru_tab INDEX prev_tabix.
        CLEAR: prev_tabix, continue_field.
      ENDIF.
    ELSE.
      LOOP AT stru_tab WHERE index EQ sy-index.
        stru_tab-fldname = name-name.
        prev_tabix = sy-tabix.
        MODIFY stru_tab.
      ENDLOOP.
    ENDIF.
    IF name-continue EQ '*'.
      continue_field = 'X'.
    ELSE.
      continue_field = space.
    ENDIF.
  ENDDO.
* NOW BUILD FIELDNAMES
  LOOP AT stru_tab.
    fieldnames-field   = stru_tab-fldname.
    APPEND fieldnames.
  ENDLOOP.
ENDFORM.                               " GET_ALL_FIELD_NAMES
 
*&---------------------------------------------------------------------*
*& Report  ZNVK_SEND_HTML_MAIL
*&
*&---------------------------------------------------------------------*
*following blog will tell  you that how to end a  email as other webmails.
*following Example wil show you that how the Employee data will come in a HTML format
*&---------------------------------------------------------------------*
REPORT  znvk_send_html_mail.
*Diclare a types to hold the Employee data
TYPES:BEGIN OF ty_employee,
pernr TYPE pa0002-pernr,
begda TYPE pa0002-begda,
endda TYPE pa0002-endda,
vorna TYPE pa0002-vorna,
nachn TYPE pa0002-nachn,
END OF ty_employee.
*Diclate a types for employee data table
TYPES:tt_employee  TYPE  STANDARD  TABLE  OF  ty_employee.
*Diclate a workarea  to hold the Employee data
DATA: gf_employee     TYPE  ty_employee.
*Diclate a table  to hold the Employee data
DATA: gt_employee     TYPE  tt_employee.
*All the diclarations to send the email is same for this also
*except that diclare the doc type specify as HTML
DATA:
*- Structure to hold Output Details in delimited format
         gf_output_soli TYPE  soli,
*- Structure to hold Imported Object Components
         gf_objpack     TYPE sopcklsti1,
*- Structure to hold data in single line format
         gf_objhead     TYPE solisti1,
*- Structure to hold data in single line format
         gf_objtxt      TYPE solisti1,
*- Structure to hold data for API Recipient List
         gf_reclist     TYPE somlreci1,
*- Structure to hold  email data
         gf_doc_chng    TYPE sodocchgi1,
*- Internal Table to hold Output Details in delimited format
         gt_output_soli TYPE TABLE OF soli,
*- Internal Table to hold Imported Object Components
         gt_objpack     TYPE TABLE OF sopcklsti1,
*- Internal Table to hold data in single line format
         gt_objhead     TYPE TABLE OF solisti1,
*- Internal Table to hold data in single line format
         gt_objtxt      TYPE TABLE OF solisti1,
*- Internal Table to hold data for API Recipient List
         gt_reclist     TYPE TABLE OF somlreci1.
DATA:BEGIN OF lt_emp OCCURS 0,
       emp TYPE pa0001-pernr,
 END OF lt_emp.
DATA:l_begda(10),
     l_endda(10).
DATA: g_lines     TYPE sy-tabix,  "To hold number of records
      g_msg_lines TYPE sy-tabix,  "To hold number of records
      g_sent_all(1) TYPE c.
**                C O N S T A N T S                                     **
CONSTANTS : c_int(3)      TYPE c VALUE 'INT',   "Internet mail address
            c_doc_type_htm(3) TYPE c VALUE 'HTM',   "Code for document class
            c_rec_type    TYPE c VALUE 'U',     "Recipient type
            c_express     TYPE c VALUE 'X'.     "Send express

START-OF-SELECTION.
*Hotcoaded few employee numbers
  lt_emp-emp = 00000003.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000004.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000005.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000006.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000007.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000008.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000009.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000010.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000012.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000013.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000014.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000015.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000016.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000017.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000018.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000024.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000025.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000027.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000028.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000029.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000030.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000032.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000033.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000034.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000035.
  APPEND  lt_emp.CLEAR lt_emp.
  lt_emp-emp = 00000036.
  APPEND  lt_emp.CLEAR lt_emp.
*select to get the employee Biodata
  SELECT
    pernr
    begda
    endda
    vorna
    nachn
  FROM pa0002
  INTO TABLE gt_employee
  FOR ALL ENTRIES IN lt_emp
  WHERE pernr = lt_emp-emp.
*Once the Employee Diodata came
*As following we can pripare the html Body format
*Set the Subject line
  gf_doc_chng-obj_name  = 'HTML Format Email from SAP'.
  gf_doc_chng-obj_descr = 'HTML Format Email from SAP'.
*Set the Body background colour
  gf_objtxt-line = '<body bgcolor = "#E6E6FA">'.
*- Append
  APPEND gf_objtxt TO gt_objtxt.
*- Clear
  CLEAR gf_objtxt.
*Set font color and its type
  CONCATENATE '<FONT COLOR = "#191970" face="Garamond">' '<b>' INTO gf_objtxt-line.
*- Append
  APPEND gf_objtxt TO gt_objtxt.
*- Clear
  CLEAR gf_objtxt.
*Pripare mail body
  CONCATENATE '<p>' 'Dear Sir/Madam,' '</p>'
              INTO gf_objtxt-line.
*- Append
  APPEND gf_objtxt TO gt_objtxt.
*- Clear
  CLEAR gf_objtxt.
  gf_objtxt-line = space.
*- Append
  APPEND gf_objtxt TO gt_objtxt.
*- Clear
  CLEAR gf_objtxt.
  CONCATENATE '<p>'
              '    The following employee has updated  His/Her profile.'
              '</p>'
                 INTO gf_objtxt-line SEPARATED BY space.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  gf_objtxt-line = '<center>'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
*  Pripare Employee data in table format to dispay in Mail body
  gf_objtxt-line = '<TABLE  width= "100%" border="1">'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<TR ><td align = "LEFT" BGCOLOR = "#708090">'
              '<FONT COLOR = "BLUE"><B>Employee number</B> </FONT>'
                '</td>'  INTO gf_objtxt-line.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<td align = "LEFT"  BGCOLOR = "#708090">'
                '<FONT COLOR = "BLUE"> <B>Begin Date</B> </FONT>'
                '</td>'  INTO gf_objtxt-line.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<td align = "LEFT"  BGCOLOR = "#708090">'
                '<FONT COLOR = "BLUE"><B>End date</B> </FONT>'
                '</td>'  INTO gf_objtxt-line.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<td align = "LEFT"  BGCOLOR = "#708090">'
                   ' <FONT COLOR = "BLUE"><B>first name</B> </FONT>'
                   '</td>'  INTO gf_objtxt-line.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<td align = "LEFT"  BGCOLOR = "#708090">'
                   '<FONT COLOR = "BLUE"><B>last name</B> </FONT>'
                   '</td></tr>'  INTO gf_objtxt-line.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  LOOP AT gt_employee INTO gf_employee.
    WRITE: gf_employee-begda TO  l_begda.
    WRITE: gf_employee-endda TO  l_endda.
    CONCATENATE '<TR><td align = "LEFT">'
                '<FONT COLOR = "BLUE">' gf_employee-pernr '</FONT>'
                '</td>'  INTO gf_objtxt-line.
    APPEND gf_objtxt TO gt_objtxt.
    CLEAR  gf_objtxt.

    CONCATENATE '<td align = "LEFT">'
                '<FONT COLOR = "BLUE">' l_begda '</FONT>'
                  '</td>'  INTO gf_objtxt-line.
    APPEND gf_objtxt TO gt_objtxt.
    CLEAR  gf_objtxt.
    CONCATENATE '<td align = "LEFT">'
                '<FONT COLOR = "BLUE">' l_endda '</FONT>'
                  '</td>'  INTO gf_objtxt-line.
    APPEND gf_objtxt TO gt_objtxt.
    CLEAR  gf_objtxt.
    CONCATENATE '<td align = "LEFT">'
                '<FONT COLOR = "BLUE">' gf_employee-vorna '</FONT>'
                 '</td>'  INTO gf_objtxt-line.
    APPEND gf_objtxt TO gt_objtxt.
    CLEAR  gf_objtxt.
    CONCATENATE '<td align = "LEFT">'
                '<FONT COLOR = "BLUE">'    gf_employee-nachn '</FONT>'
                     '</td></tr>'  INTO gf_objtxt-line.
    APPEND gf_objtxt TO gt_objtxt.
    CLEAR  gf_objtxt.
  ENDLOOP.
  gf_objtxt-line = '</TABLE>'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  gf_objtxt-line = '</center>'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<p>' ' Please confirm the appropriate actions'
                       'have taken place in regards to this change'
                 '</p>'
                 INTO gf_objtxt-line SEPARATED BY space.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR  gf_objtxt.
  CONCATENATE '<p>' ' For further questions, please contact HR Direct'
                 '</p>'
                 INTO gf_objtxt-line SEPARATED BY space.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR gf_objtxt.
  gf_objtxt-line =   'Regards,<br />'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR gf_objtxt.
  gf_objtxt-line =   'Vamsi<br />'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR gf_objtxt.
  gf_objtxt-line = '<br><br><b><center><i><font color = "RED">This is an auto generated Email.'.
  APPEND gf_objtxt TO gt_objtxt.
  CLEAR gf_objtxt.
  gf_objtxt-line = '</FONT></body>'.
*- Append
  APPEND gf_objtxt TO gt_objtxt.
*- Clear
  CLEAR gf_objtxt.

END-OF-SELECTION.
  DESCRIBE TABLE gt_objtxt LINES g_msg_lines.
  READ TABLE gt_objtxt INTO gf_objtxt INDEX g_msg_lines.
  gf_doc_chng-doc_size = ( g_msg_lines - 1 ) * 255 + strlen( gf_objtxt ).
*- Creation of the entry for the compressed document
  gf_objpack-transf_bin = ' '.
  gf_objpack-head_start = 1.
  gf_objpack-head_num   = 0.
  gf_objpack-body_start = 1.
  gf_objpack-body_num   = g_msg_lines.
  gf_objpack-doc_type   = c_doc_type_htm.
*- Append
  APPEND gf_objpack TO gt_objpack.
*- Clear
  CLEAR gf_objpack.
*- Creation of the document attachment
*- Describe
  DESCRIBE TABLE gt_output_soli LINES g_lines.
*- Don't create attachment if no data is present
  IF g_lines <> 0.
    LOOP AT gt_output_soli INTO gf_output_soli.
      gf_objtxt = gf_output_soli.
*- Append
      APPEND gf_objtxt TO gt_objtxt.
*- Clear
      CLEAR gf_objtxt.
    ENDLOOP.
  ENDIF.
*- Completing the recipient list
  gf_reclist-receiver = 'vamsin@intelligroup.com'.
  gf_reclist-rec_type = c_rec_type.
  gf_reclist-express  = c_express.
*- Append
  APPEND gf_reclist TO gt_reclist.
*- Clear
  CLEAR gf_reclist.
  CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
    EXPORTING
      document_data              = gf_doc_chng
      put_in_outbox              = 'X'
      sender_address             = 'NTWDEV'
      commit_work                = 'X'
    IMPORTING
      sent_to_all                = g_sent_all
    TABLES
      packing_list               = gt_objpack
      object_header              = gt_objhead
      contents_txt               = gt_objtxt
      receivers                  = gt_reclist
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
  IF sy-subrc = 0.
    cl_os_transaction_end_notifier=>raise_commit_requested( ).
    CALL FUNCTION 'DB_COMMIT'.
    cl_os_transaction_end_notifier=>raise_commit_finished( ).
  ENDIF.
 
*send email notification to user using PDF attachment

DATA: lv_filesize TYPE i,
      lv_buffer TYPE string,
      lv_attachment TYPE i,
      lv_testo TYPE i.

DATA: li_pdfdata TYPE STANDARD TABLE OF tline,
      li_mess_att TYPE STANDARD TABLE OF solisti1,
      li_mtab_pdf TYPE STANDARD TABLE OF tline,
      li_objpack TYPE STANDARD TABLE OF sopcklsti1,
      li_objtxt TYPE STANDARD TABLE OF solisti1,
      li_objbin TYPE STANDARD TABLE OF solisti1,
      li_reclist TYPE STANDARD TABLE OF somlreci1,
      li_objhead TYPE soli_tab.

DATA: lwa_pdfdata TYPE tline,
      lwa_objpack TYPE sopcklsti1,
      lwa_mess_att TYPE solisti1,
      lwa_objtxt TYPE solisti1,
      lwa_objbin TYPE solisti1,
      lwa_reclist TYPE somlreci1,
      lwa_doc_chng TYPE sodocchgi1.

CONSTANTS: lc_u TYPE char1 VALUE 'U',
            lc_0 TYPE char1 VALUE '0',
            lc_1 TYPE char1 VALUE '1',
            lc_pdf TYPE char3 VALUE 'PDF',
            lc_raw TYPE char3 VALUE 'RAW',
            lc_ordform TYPE char15 VALUE 'ZORDCONFIRM_01',
            lc_attachment TYPE char10 VALUE 'ATTACHMENT'.

CALL FUNCTION 'CONVERT_OTF'
  EXPORTING
    format                = lc_pdf
    max_linewidth         = 132
  IMPORTING
    bin_filesize          = lv_filesize
  TABLES
    otf                   = pv_otfdata
    lines                 = li_pdfdata
  EXCEPTIONS
    err_max_linewidth     = 1
    err_format            = 2
    err_conv_not_possible = 3
    err_bad_otf           = 4
    OTHERS                = 5.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.

LOOP AT li_pdfdata INTO lwa_pdfdata.
  TRANSLATE lwa_pdfdata USING ' ~'.
  CONCATENATE lv_buffer lwa_pdfdata INTO lv_buffer.
  CLEAR lwa_pdfdata.
ENDLOOP.

TRANSLATE lv_buffer USING '~ '.
DO.
  lwa_mess_att = lv_buffer.
  APPEND lwa_mess_att TO li_mess_att.
  CLEAR lwa_mess_att.
  SHIFT lv_buffer LEFT BY 255 PLACES.
  IF lv_buffer IS INITIAL.
    EXIT.
  ENDIF.
ENDDO.

* Object with PDF.
REFRESH li_objbin.
li_objbin[] = li_mess_att[].
DESCRIBE TABLE li_objbin LINES lv_attachment.

* Object with main text of the mail.
lwa_objtxt = space.
APPEND lwa_objtxt TO li_objtxt.
CLEAR lwa_objtxt.

DESCRIBE TABLE li_objtxt LINES lv_testo.

* Create the document which is to be sent

lwa_doc_chng-obj_name = text-008.
lwa_doc_chng-obj_descr = text-008.

lwa_doc_chng-sensitivty = lc_0.
lwa_doc_chng-obj_prio = lc_1.
lwa_doc_chng-doc_size = lv_testo * 225.

* Pack to main body.
CLEAR lwa_objpack-transf_bin.

* header
lwa_objpack-head_start = 1.

* The document needs no header (head_num = 0)
lwa_objpack-head_num = 0.

* body
lwa_objpack-body_start = 1.
lwa_objpack-body_num = lv_testo.
lwa_objpack-doc_type = lc_raw.
APPEND lwa_objpack TO li_objpack.
CLEAR lwa_objpack.

* Create the attachment.
* Fill the fields of the packing_list for the attachment:
lwa_objpack-transf_bin = gc_x .

* header
lwa_objpack-head_start = 1.
lwa_objpack-head_num = 1.

* body
lwa_objpack-body_start = 1.
lwa_objpack-body_num = lv_attachment.
lwa_objpack-doc_type = lc_pdf.
lwa_objpack-obj_name = lc_attachment.

lwa_objpack-obj_descr = text-008.

lwa_objpack-doc_size = lv_attachment * 255.
APPEND lwa_objpack TO li_objpack.
CLEAR lwa_objpack.

lwa_reclist-receiver = pv_emailid.
lwa_reclist-rec_type = lc_u.
lwa_reclist-notif_del = gc_x.
lwa_reclist-notif_ndel = gc_x.
APPEND lwa_reclist TO li_reclist.

IF li_reclist IS NOT INITIAL.

  CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    EXPORTING
      document_data              = lwa_doc_chng
      put_in_outbox              = gc_x
    TABLES
      packing_list               = li_objpack
      object_header              = li_objhead
      contents_bin               = li_objbin
      contents_txt               = li_objtxt
      receivers                  = li_reclist
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.

  IF sy-subrc <> 0.
* MESSAGE ID sy-msgid TYPE 'I' NUMBER sy-msgno
* WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDIF.
 

The Notes client is an OLE automation controller and server.External applications can create and reference the automation objects, then work down through the object hierarchies.A Notes client must be installed on the same machine as SAP GUI is installed. Notes runs as a separate process when acting as an OLE automation server.

The automation is based on  late binding. A Notes.NotesSession object has to be created and work down through the hierarchies using the available methods. For example, if you want to send a mail, create a Notes.NotesSession OLE automation object, and then use the GetDatabase method of NotesSession to set a reference variable.The below shown codes explains in detail about different OLE objects and how to send a mail. 

The following OLE objects must be declared for the process.

  • Notessession
  • NotesDatabase
  • NotesDocument
  • NotesRichTextItem

Sample Code .

TYPE-POOLS ole2 .
parameters: email(50).

DATA  : notes TYPE ole2_object,
             dbdirectory TYPE ole2_object.
             database TYPE ole2_object.
             document TYPE ole2_object.
             attachment TYPE ole2_object.
             notesrtf TYPE ole2_object.
             notesregistration TYPE ole2_object.
             notesstyle TYPE ole2_object.

CREATE OBJECT notes 'Lotus.Notessession'. "Represents the current environment and access to information(Address book,User info etc) 
CREATE OBJECT database 'Lotus.notesDatabase'."Represents the Notes Database
 
CREATE OBJECT document 'Lotus.notesDocument'. "Represents a document in database
 
CREATE OBJECT notesrtf  'Lotus.notesRichTextItem'."Represents a Rich Text Item type
 

 **//  Initialize a COM Session with the current User-Id

CALL METHOD OF notes 'Initialize'.

**// Creates a new DbDirectory object using the name of the server you want to access.

CALL METHOD OF notes 'getdbDirectory' = dbdirectory EXPORTING #1 = ''.

**// Opens the current user's mail database.

CALL METHOD OF dbdirectory 'OpenMailDatabase' = database .

**// Creates a document in a database and returns a Document object that represents the new document.

CALL METHOD OF database 'CreateDocument' = document .

**//Use the "SendTo" property to populate the recievers//

CALL METHOD OF document 'ReplaceItemValue' EXPORTING #1 = 'SendTo' #2 = email.

**//use the "Subject" property to set the subject of the mail

CALL METHOD OF document 'ReplaceItemValue' EXPORTING #1 = 'Subject' #2 = 'hi'.

**//The body of the mail can be created as a rich text item//

CALL METHOD OF document 'CreateRichTextItem' = notesrtf EXPORTING #1 = 'Body'.

**//Append the text to the body of the mail//

CALL METHOD OF notesrtf 'AppendText' EXPORTING #1 = 'Hi...From SAP,through lotus notes..regards..jinesh'.

**// "Send" Method mails a document.

**// If true, the form is stored and sent along with the document. If false, it isn't.

CALL METHOD OF document 'Send' EXPORTING #1 = 'FALSE'.
if sy-subrc = 0.
write : 'Mail Send Successfully'.
endif.

//**Free all the objects.

FREE OBJECT notes.
FREE OBJECT dbdirectory .
FREE OBJECT database.
FREE OBJECT document .
FREE OBJECT attachment .
FREE OBJECT notesrtf .
FREE OBJECT notesregistration .
FREE OBJECT notesstyle.

Note : I have not  included a proper error handling method in the above code.

  
           There might be a scenario where in an E-mail notification is required in a classical report where data outputted resides in many internal tables with complex logic. Here it is not a feasible option to send the list output to E-mail with excel as it may take lot of time in building the E-mailing logic. This article addresses this issue in a simple way.
Just copy paste below piece of code in a new report to understand the functionality.

Sample Code: 

DATA: li_receivers       TYPE STANDARD TABLE OF soos1,
      li_listobject      TYPE STANDARD TABLE OF abaplist,
      li_ali             TYPE STANDARD TABLE OF soli,
      li_ali1            TYPE STANDARD TABLE OF soli,
      li_ali2            TYPE STANDARD TABLE OF soli,
      lwa_objecthdchange TYPE sood1,
      lwa_receivers      TYPE soos1,
      lwa_ali            TYPE soli.
DATA: l_lines   TYPE i,
      l_length  TYPE i.
DO 10 TIMES.
  NEW-LINE.
  ULINE (99).
  WRITE: /1 sy-vline,
          2 'column1',
         24 sy-vline,
         25 'Column2',
         49 sy-vline,
         50 'Column3',
         74 sy-vline,
         75 'Column4',
         99 sy-vline.
ENDDO.
NEW-LINE.
ULINE (99).
NEW-LINE.
CALL FUNCTION 'SAVE_LIST'
  EXPORTING
    list_index         = '0'              "Pass the list index like 0, 1, 2...
  TABLES
    listobject         = li_listobject
  EXCEPTIONS
    list_index_invalid = 1
    OTHERS             = 2.
IF sy-subrc NE 0.
  RAISE invalid_list.
ENDIF.
Convert the list to ALI format
CALL FUNCTION 'TABLE_COMPRESS'
  TABLES
    in             = li_listobject
    out            = li_ali
  EXCEPTIONS
    compress_error = 1
    OTHERS         = 2.
IF sy-subrc NE 0.
  RAISE compress_error.
ENDIF.
CLEAR: lwa_objecthdchange.
DESCRIBE TABLE li_ali LINES l_lines.
DESCRIBE FIELD lwa_ali LENGTH l_length IN CHARACTER MODE.
lwa_objecthdchange-objlen = l_length * l_lines.
lwa_objecthdchange-objla  = sy-langu.
lwa_objecthdchange-objnam = 'List'.
MOVE sy-title TO lwa_objecthdchange-objdes.
MOVE: 1 TO lwa_objecthdchange-objpri,
      0 TO lwa_objecthdchange-objsns.
CLEAR: lwa_receivers.
MOVE: 'X'                 TO lwa_receivers-snddr,
      'X'                 TO lwa_receivers-sndex,
      'U'                 TO lwa_receivers-recesc,
      'E-MAIL' TO lwa_receivers-recextnam.          "Pass the recipient ID here.
APPEND lwa_receivers TO li_receivers.Send email
CALL FUNCTION 'SO_OBJECT_SEND'
 EXPORTING
*   FOLDER_ID                        = ' '
*   FORWARDER                        = ' '
*   OBJECT_FL_CHANGE                 = ' '
   object_hd_change                 = lwa_objecthdchange
*   OBJECT_ID                        = ' '
   object_type                      = 'ALI'
*   OUTBOX_FLAG                      = ' '
   owner                            = sy-uname
*   STORE_FLAG                       = ' '
*   DELETE_FLAG                      = ' '
   sender                           = sy-uname
*   CHECK_SEND_AUTHORITY             = ' '
*   CHECK_ALREADY_SENT               = ' '
*   GIVE_OBJECT_BACK                 =
*   ORIGINATOR                       = ' '
*   ORIGINATOR_TYPE                  = 'J'
*   LINK_FOLDER_ID                   = ' '
*   SEND_REQUEST_OID                 = ' '
*   IP_ENCRYPT                       = 'U'
*   IP_SIGN                          = 'U'
*   IP_REC_COUNT_ADD                 =IMPORTING
*   OBJECT_ID_NEW                    =
*   SENT_TO_ALL                      =
*   ALL_BINDING_DONE                 =
*   OFFICE_OBJECT_KEY                =
*   ORIGINATOR_ID                    =
*   E_SEND_REQUEST_OID               =
TABLES
   objcont                          = li_ali
*   OBJHEAD                          =
*   OBJPARA                          =
*   OBJPARB                          =
   receivers                        = li_receivers
*   PACKING_LIST                     =
*   ATT_CONT                         =
*   ATT_HEAD                         =
*   NOTE_TEXT                        =
*   LINK_LIST                        =
*   APPLICATION_OBJECT               =
 EXCEPTIONS
   active_user_not_exist            = 1
   communication_failure            = 2
   component_not_available          = 3
   folder_not_exist                 = 4
   folder_no_authorization          = 5
   forwarder_not_exist              = 6
   note_not_exist                   = 7
   object_not_exist                 = 8
   object_not_sent                  = 9
   object_no_authorization          = 10
   object_type_not_exist            = 11
   operation_no_authorization       = 12
   owner_not_exist                  = 13
   parameter_error                  = 14
   substitute_not_active            = 15
   substitute_not_defined           = 16
   system_failure                   = 17
   too_much_receivers               = 18
   user_not_exist                   = 19
   originator_not_exist             = 20
   x_error                          = 21
   OTHERS                           = 22.
   IF sy-subrc IS INITIAL.
     MESSAGE 'Mail has been sent successfully' TYPE 'S'.
   ELSE.
     MESSAGE 'Error occured while sending the mail' TYPE 'S'.
   ENDIF.



 

 Above code shows a sample output of the report without any processing logic. The actual output data determination logic is much complex in real time scenarios.  A scanned copy of the output is sent as a mail notification to the recipients i.e. what you see in report output and E-mail is one and the same. This is best suited only for classical reports. For ALV reports it is always better to use E-mail with excel attachment as we have all the data available in one final internal table and lot of options are available with excel.


 

Thanks,

Vinod.

 

Author: Prasath Natesan
Submitted: 04-Jan-2008
Modif 08-Mar-2010: Sandra Rossi
Related Links/References:

Introduction

Emails are one of the common methods of notifying users about various changes performed in the system. But when the user needs to view/process the data he/she needs to manually login to the system through the required transactions to access the data. SAP shortcuts come handy in these situations enabling the users to login to the required transactions directly.

Using SAP shortcuts through email will benefit the users in the following ways,

  1. Delivered to a single inbox, hence user does not have to keep checking the UWL/SBWP or other inboxes
  2. User does not need to remember the different transactions that he/she needs to work on.
  3. Option of parameter handling simplifies the job of user by preloading the screen with required information

Creating SAP shortcut at run time

The following function module can be used to create a shortcut for any SAP transaction. Further, certain values available in the transaction can be defaulted by passing the values as parameters to this FM. This shortcut created can then be attached in a mail and sent to the appropriate recipients.

Before creating the function modulen you have to define ZST_SHORTCUT_PAR as a DDIC structure, which 2 components FIELDNAME of type C of length 60, and FIELDVALUE of type C of length 255.

Note: if you want to test the program quickly without creating the function module and the DDIC structure, have a look at appendix 2.

FUNCTION zfm_create_shortcut.
*"---------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(RECIPIENT_USER_ID) TYPE  SYUNAME
*"     REFERENCE(TRANSACTION) TYPE  TCODE
*"  EXPORTING
*"     REFERENCE(CONTENT) TYPE  STRING
*"  TABLES
*"      SHORTCUT_PARAM STRUCTURE  ZST_SHORTCUT_PAR OPTIONAL
*"---------------------------------------------------------------------

*** Declaration for shortcut content
  DATA :  parameter TYPE text255,
          v_pernr(12) TYPE c.
  DATA :  v_tcode TYPE tcode.

* Check if transaction code is available
  CLEAR v_tcode.
  SELECT SINGLE tcode FROM tstc
                INTO v_tcode
                WHERE tcode EQ transaction.

  IF v_tcode IS INITIAL.
    MESSAGE 'Enter a valid transaction' TYPE 'E' DISPLAY LIKE 'A'.
    EXIT.
  ENDIF.

* Populate the parameters to be passed to the shortcut
  IF NOT shortcut_param[] IS INITIAL.
    CLEAR parameter.
    LOOP AT shortcut_param.
      CONCATENATE parameter shortcut_param-fieldname '='
    shortcut_param-fieldvalue ';'
                INTO parameter.
    ENDLOOP.
  ENDIF.

*** create the shortcut content for the required transaction
  CALL FUNCTION 'SWN_CREATE_SHORTCUT'
    EXPORTING
      i_transaction           = transaction
      i_parameter             = parameter
      i_sysid                 = sy-sysid
      i_client                = sy-mandt
      i_user                  = recipient_user_id
      i_language              = sy-langu
      i_windowsize            = 'Normal window'
    IMPORTING
      shortcut_string         = content
    EXCEPTIONS
      inconsistent_parameters = 1
      OTHERS                  = 2.
  IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFUNCTION.

This FM receives RECIPIENT_USER_ID and TRANSACTION as import parameters. The value of parameters if any can be passed through table parameter SHORCTCUT_PARAM. On execution the shortcut content is created and returned through the export parameter "CONTENT". The table SHORTCUT_PARAM refers to a custom structure described in Appendix 1.

Example scenario

Consider a scenario where the employee has requested for a change in address. Now once the change in address is completed a notification email is sent to the employee indicating the successful change in address. In a normal scenario the employee needs to log into the system manually and enter the required transaction. Then the required details (employee number, infotype and subtype) need to be entered before displaying the updated information.

This process can be simplified by sending a shortcut which will navigate the user to the required transaction with all required data pre-loaded. The sample code for this process is given below

*&---------------------------------------------------------------------*
*& Report  ZRP_MAIL_SHORTCUT
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zrp_mail_shortcut.

************************************************************************
***    Report to send mail to employee to display temp address   ***
************************************************************************
*** Declarations for attachment creation
DATA: doc_chng  LIKE sodocchgi1.
DATA: tab_lines LIKE sy-tabix,
      body_start LIKE sy-tabix.
DATA: it_objtxt LIKE solisti1 OCCURS 0 WITH HEADER LINE.
DATA: it_objpack   LIKE sopcklsti1 OCCURS 2 WITH HEADER LINE.
DATA: it_objbin    LIKE solisti1 OCCURS 10 WITH HEADER LINE.
DATA: it_reclist   LIKE somlreci1 OCCURS 5 WITH HEADER LINE.
DATA: it_shortcut_param LIKE zst_shortcut_par OCCURS 0 WITH HEADER LINE.
DATA: content TYPE string.

*** Pass the required parameters and create the shortcut
CLEAR it_shortcut_param.
REFRESH it_shortcut_param.

it_shortcut_param-fieldname = 'RP50G-PERNR'.
it_shortcut_param-fieldvalue = '1001'. "Employee number
APPEND it_shortcut_param.

it_shortcut_param-fieldname = 'RP50G-CHOIC'.
it_shortcut_param-fieldvalue = '0006'. " Address Infotype
APPEND it_shortcut_param.

it_shortcut_param-fieldname = 'RP50G-TIMR1'.
it_shortcut_param-fieldvalue = 'X'.    "Period selected as "Today"
APPEND it_shortcut_param.

it_shortcut_param-fieldname = 'RP50G-SUBTY'.
it_shortcut_param-fieldvalue = '2'.    "Temporary address subtype
APPEND it_shortcut_param.

CALL FUNCTION 'ZFM_CREATE_SHORTCUT'
  EXPORTING
    recipient_user_id = 'DEVHYD'
    transaction       = 'PA20'
  IMPORTING
    content           = content
  TABLES
    shortcut_param    = it_shortcut_param.

*** Mail Subject
doc_chng-obj_descr = 'Employee address changed'.
*** Mail Contents
CONCATENATE ' The requested change has been made to your temporary address.'
' Please double click on the attachment and choose display to view the updated address'
INTO it_objtxt.
APPEND it_objtxt.

*** Creation of the entry for the document
DESCRIBE TABLE it_objtxt LINES tab_lines.
CLEAR it_objpack-transf_bin.
it_objpack-head_start = 1.
it_objpack-head_num = 0.
it_objpack-body_start = 1.
it_objpack-body_num = tab_lines.
it_objpack-doc_type = 'RAW'.
APPEND it_objpack.

*** Populate attachment content
CLEAR : tab_lines, it_objbin.
CONCATENATE content it_objbin-line INTO it_objbin-line.
APPEND it_objbin.
DESCRIBE TABLE it_objbin LINES tab_lines.

*** Creation of the entry for the compressed attachment
it_objpack-transf_bin = 'X'. "Will get content from content_bin
it_objpack-head_start = 1.
it_objpack-head_num   = 1.
it_objpack-body_start = 1.
it_objpack-body_num   = tab_lines.
it_objpack-doc_type   = 'EXT'.
it_objpack-obj_name   = 'SAPSHORTCUTMAIL'.
it_objpack-obj_descr  = 'DisplayAddress.SAP'.
it_objpack-doc_size   = tab_lines * 255.
APPEND it_objpack.


*** target recipent(s)
CLEAR it_reclist.
it_reclist-receiver = 'employeemailid@employeecompany.com'.
it_reclist-rec_type = 'U'.
APPEND it_reclist.

*** Sending the document to recipients with the shortcut attachment
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
  EXPORTING
    document_data              = doc_chng
    put_in_outbox              = 'X'
    commit_work                = 'X'
  TABLES
    packing_list               = it_objpack
    contents_bin               = it_objbin
    contents_txt               = it_objtxt
    receivers                  = it_reclist
  EXCEPTIONS
    too_many_receivers         = 1
    document_not_sent          = 2
    operation_no_authorization = 4
    OTHERS                     = 99.

The above code uses the function module ZFM_CREATE_SHORTCUT to create the required SAP shortcut and then sends it as attachment by email. The user can now double click on the shortcut from his email and reach the transaction directly with required information preloaded.

When the user double clicks on the attachment the pop up window for entering the password is opened as shown below,

Once the user enters the password and clicks on "Log on" the required transaction is opened up directly as shown below,


As highlighted in the above picture the values - Employee number, Period, Infotype and subtype are preloaded when the user reaches the transaction. The user can now hit the display button and view the required data.

Note: The system on which the shortcut is executed should have SAP GUI installed and have the target system configured in the SAP logon pad. If the configuration is not already available then on launching the shortcut the system asks for the logon details as shown below,

Appendix 1: Structure for passing shortcut parameters

A custom name-value pair structure as shown below was created for passing the shortcut parameters.

Appendix 2: creating the report without the FM and DDIC structure

This section shows how to test the program quickly without creating the function module and the DDIC structure.*

In the program, perform the following changes:

Replace this section

By this section

REPORT  zrp_mail_shortcut.

************************************************************************
***    Report to send mail to employee to display temp address   ***
************************************************************************
REPORT  zrp_mail_shortcut.

DATA : BEGIN OF zst_shortcut_par,
          fieldname   TYPE c LENGTH 60,
          fieldvalue  TYPE c LENGTH 255,
        END OF zst_shortcut_par.

************************************************************************
***    Report to send mail to employee to display temp address   ***
************************************************************************
CALL FUNCTION 'ZFM_CREATE_SHORTCUT'
  EXPORTING
    recipient_user_id = 'DEVHYD'
    transaction       = 'PA20'
  IMPORTING
    content           = content
  TABLES
    shortcut_param    = it_shortcut_param.
PERFORM zfm_create_shortcut
  TABLES
    it_shortcut_param
  USING
    'DEVHYD'
    'PA20'
  CHANGING
    content.

[At the end of the report]

*&---------------------------------------------------------------------*
*&      Form  zfm_create_shortcut
*&---------------------------------------------------------------------*
FORM zfm_create_shortcut
  TABLES
    shortcut_param    STRUCTURE  zst_shortcut_par
  USING
    recipient_user_id TYPE  syuname
    transaction       TYPE  tcode
  CHANGING
     content          TYPE  string.


*** Declaration for shortcut content
  DATA :  parameter TYPE text255,
          v_pernr(12) TYPE c.
  DATA :  v_tcode TYPE tcode.

* Check if transaction code is available
  CLEAR v_tcode.
  SELECT SINGLE tcode FROM tstc
                INTO v_tcode
                WHERE tcode EQ transaction.

  IF v_tcode IS INITIAL.
    MESSAGE 'Enter a valid transaction' TYPE 'E' DISPLAY LIKE 'A'.
    EXIT.
  ENDIF.

* Populate the parameters to be passed to the shortcut
  IF NOT shortcut_param[] IS INITIAL.
    CLEAR parameter.
    LOOP AT shortcut_param.
      CONCATENATE parameter shortcut_param-fieldname '='
    shortcut_param-fieldvalue ';'
                INTO parameter.
    ENDLOOP.
  ENDIF.

*** create the shortcut content for the required transaction
  CALL FUNCTION 'SWN_CREATE_SHORTCUT'
    EXPORTING
      i_transaction           = transaction
      i_parameter             = parameter
      i_sysid                 = sy-sysid
      i_client                = sy-mandt
      i_user                  = recipient_user_id
      i_language              = sy-langu
      i_windowsize            = 'Normal window'
    IMPORTING
      shortcut_string         = content
    EXCEPTIONS
      inconsistent_parameters = 1
      OTHERS                  = 2.
  IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    "zfm_create_shortcut

Here is the code to send the Smartform to mail as PDF attachment.

REPORT ztest_nreddy_pdf_mail.
* Internal Table declarations
DATA: i_otf TYPE itcoo OCCURS 0 WITH HEADER LINE,
      i_tline TYPE TABLE OF tline WITH HEADER LINE,
      i_receivers TYPE TABLE OF somlreci1 WITH HEADER LINE,
      i_record LIKE solisti1 OCCURS 0 WITH HEADER LINE,
* Objects to send mail.
      i_objpack LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
      i_objtxt LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      i_objbin LIKE solisti1 OCCURS 0 WITH HEADER LINE,
      i_reclist LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
* Work Area declarations
      wa_objhead TYPE soli_tab,
      w_ctrlop TYPE ssfctrlop,
      w_compop TYPE ssfcompop,
      w_return TYPE ssfcrescl,
      wa_doc_chng TYPE sodocchgi1,
      w_data TYPE sodocchgi1,
      wa_buffer TYPE string, "To convert from 132 to 255
* Variables declarations
      v_form_name TYPE rs38l_fnam,
      v_len_in LIKE sood-objlen,
      v_len_out LIKE sood-objlen,
      v_len_outn TYPE i,
      v_lines_txt TYPE i,
      v_lines_bin TYPE i.

CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
  EXPORTING
    formname           = 'ZTEST'
  IMPORTING
    fm_name            = v_form_name
  EXCEPTIONS
    no_form            = 1
    no_function_module = 2
    OTHERS             = 3.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
w_ctrlop-getotf = 'X'.
w_ctrlop-no_dialog = 'X'.
w_compop-tdnoprev = 'X'.
CALL FUNCTION v_form_name
  EXPORTING
    control_parameters = w_ctrlop
    output_options     = w_compop
    user_settings      = 'X'
  IMPORTING
    job_output_info    = w_return
  EXCEPTIONS
    formatting_error   = 1
    internal_error     = 2
    send_error         = 3
    user_canceled      = 4
    OTHERS             = 5.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
  WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
i_otf[] = w_return-otfdata[].
CALL FUNCTION 'CONVERT_OTF'
  EXPORTING
    format                = 'PDF'
    max_linewidth         = 132
  IMPORTING
    bin_filesize          = v_len_in
  TABLES
    otf                   = i_otf
    lines                 = i_tline
  EXCEPTIONS
    err_max_linewidth     = 1
    err_format            = 2
    err_conv_not_possible = 3
    OTHERS                = 4.
IF sy-subrc <> 0.
ENDIF.
LOOP AT i_tline.
  TRANSLATE i_tline USING '~'.
  CONCATENATE wa_buffer i_tline INTO wa_buffer.
ENDLOOP.
TRANSLATE wa_buffer USING '~'.
DO.
  i_record = wa_buffer.
  APPEND i_record.
  SHIFT wa_buffer LEFT BY 255 PLACES.
  IF wa_buffer IS INITIAL.
    EXIT.
  ENDIF.
ENDDO.
* Attachment
REFRESH: i_reclist,
          i_objtxt,
          i_objbin,
          i_objpack.
CLEAR wa_objhead.
i_objbin[] = i_record[].
* Create Message Body Title and Description
i_objtxt = 'test with pdf-Attachment!'.
APPEND i_objtxt.
DESCRIBE TABLE i_objtxt LINES v_lines_txt.
READ TABLE i_objtxt INDEX v_lines_txt.
wa_doc_chng-obj_name = 'smartform'.
wa_doc_chng-expiry_dat = sy-datum + 10.
wa_doc_chng-obj_descr = 'smartform'.
wa_doc_chng-sensitivty = 'F'.
wa_doc_chng-doc_size = v_lines_txt * 255.
* Main Text
CLEAR i_objpack-transf_bin.
i_objpack-head_start = 1.
i_objpack-head_num = 0.
i_objpack-body_start = 1.
i_objpack-body_num = v_lines_txt.
i_objpack-doc_type = 'RAW'.
APPEND i_objpack.
* Attachment (pdf-Attachment)
i_objpack-transf_bin = 'X'.
i_objpack-head_start = 1.
i_objpack-head_num = 0.
i_objpack-body_start = 1.
DESCRIBE TABLE i_objbin LINES v_lines_bin.
READ TABLE i_objbin INDEX v_lines_bin.
i_objpack-doc_size = v_lines_bin * 255 .
i_objpack-body_num = v_lines_bin.
i_objpack-doc_type = 'PDF'.
i_objpack-obj_name = 'smart'.
i_objpack-obj_descr = 'test'.
APPEND i_objpack.
CLEAR i_reclist.
i_reclist-receiver = 'nareshreddy.k@gmail.com'.
i_reclist-rec_type = 'U'.
APPEND i_reclist.
CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
  EXPORTING
    document_data              = wa_doc_chng
    put_in_outbox              = 'X'
    commit_work                = 'X'
  TABLES
    packing_list               = i_objpack
    object_header              = wa_objhead
    contents_bin               = i_objbin
    contents_txt               = i_objtxt
    receivers                  = i_reclist
  EXCEPTIONS
    too_many_receivers         = 1
    document_not_sent          = 2
    document_type_not_exist    = 3
    operation_no_authorization = 4
    parameter_error            = 5
    x_error                    = 6
    enqueue_error              = 7
    OTHERS                     = 8.
IF sy-subrc <> 0.
  WRITE:/ 'Error When Sending the File', sy-subrc.
ELSE.
  WRITE:/ 'Mail sent'.
ENDIF.
 

If you want to send some text as Body of the Mail then follow this once.

When you are calling the FM 'SO_NEW_DOCUMENT_ATT_SEND_API1'.. points to remember

  1. You have to pass the body of content in table CONTENTS_TXT(ia m using I_OBJBIN) (each line a record) then. Suppose i have appended 11 records to the table CONTENTS_TXT
  2. PACKING_LIST(i am using I_OBJPACK) table you have to append a record as follows
i_objpack-transf_bin = ' '.
i_objpack-head_start = 000000000000001.
i_objpack-head_num = 000000000000001.
i_objpack-body_start = 000000000000002.
i_objpack-body_num = 000000000000010.
i_objpack-doc_type = 'RAW'.
APPEND i_objpack.
 

By the above code system treat the first line in table I_OBJBIN as header and the 2nd line to 10 lines tread as body.

CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
  EXPORTING
    document_data              = wa_doc_chng
    put_in_outbox              = 'X'
  TABLES
    packing_list               = i_objpack
    object_header              = wa_objhead
    contents_bin               = i_objbin
    contents_txt               = i_objtxt
    receivers                  = i_reclist
  EXCEPTIONS
    too_many_receivers         = 1
    document_not_sent          = 2
    document_type_not_exist    = 3
    operation_no_authorization = 4
    parameter_error            = 5
    x_error                    = 6
    enqueue_error              = 7
    OTHERS                     = 8.
 

Author: Alessandro Spadoni
Submitted: 16,Nov 2010
Related Links: http://en.wikipedia.org/wiki/Regular_expression

Snippet to validate an Email using class CL_ABAP_REGEX

DATA: regex   TYPE REF TO cl_abap_regex,
 matcher TYPE REF TO cl_abap_matcher,
 match   TYPE c LENGTH 1,
 mail_to_check(100),
 result TYPE WDY_BOOLEAN.

 mail_to_check = 'mail@example.com'.

 result = abap_true.  "Email is valid

CREATE OBJECT regex
 EXPORTING
 pattern     = '\w+(\.\w+)*@(\w+\.)+(\w{2,4})'
 ignore_case = abap_true.

matcher = regex->create_matcher( text = mail_to_check ).

 IF matcher->match( ) IS INITIAL.
 result = abap_false.  "Email not valid
 EXIT.
 ENDIF.

Author: Devendra R Paralkar
Submitted: July 6, 2007
Related Links:

Description

In many cases it is required to send notifications/messages to Users depending upon some event/action that has occurred in SAP. There are standard function modules available in SAP for achieving this functionality. Here we will discuss in addition to sending mails how we can achieve text formatting using a combination of powerful SAP function modules and simple HTML tags.

Program Logic

SAP has provided us many function modules for this purpose. We will use "SO_DOCUMENT_SEND_API1" in our case. One of the parameters that need to be passed to this Function is the structure document_data. Here we have a field doc_type, in order to have required text formatting we pass this parameter as 'HTM'. By using this extension we can format the body of this mail using HTML tags.

REPORT Z_SEND_HTML_MAIL .

* Selection screen: enter receiver (default is yourself)
PARAMETERS p_rec TYPE so_recname OBLIGATORY DEFAULT sy-uname.
PARAMETERS p_typ TYPE so_escape OBLIGATORY DEFAULT 'B'. "sap user

* Data Declaration
DATA: wa_docdata TYPE sodocchgi1,
      wa_objpack TYPE sopcklsti1 ,
      it_objpack TYPE TABLE OF sopcklsti1,
      wa_objtxt TYPE solisti1,
      it_objtxt TYPE TABLE OF solisti1,
      wa_reclist TYPE somlreci1,
      it_reclist TYPE TABLE OF somlreci1.
DATA: tab_lines TYPE i.

* Start program
PERFORM fill_text.
PERFORM fill_object_details.
*create receiver list
PERFORM create_receivers_list.
*send mail
PERFORM send_mail.
WRITE: / 'End of Program'.
*---------------------------------------------------------------------*
*Form fill_text
*---------------------------------------------------------------------*
FORM fill_text .
  wa_objtxt = '<SPAN style="font-family:arial;font-size:10.5pt;color:blue">'.
  APPEND wa_objtxt TO it_objtxt.
  wa_objtxt = '<B><U>Test Program for Send Mail.</U></B> <BR>'.
  APPEND wa_objtxt TO it_objtxt.
  wa_objtxt = '<A HREF="http://www.sap.com">Best wishes</A>'.
  APPEND wa_objtxt TO it_objtxt.
  wa_objtxt = '<I>This code is formatted using HTML.</I>'.
  APPEND wa_objtxt TO it_objtxt.
  wa_objtxt = 'Have a nice day.'.
  APPEND wa_objtxt TO it_objtxt.
  wa_objtxt = '<SPAN>'.
  APPEND wa_objtxt TO it_objtxt.
ENDFORM. " fill_text
*---------------------------------------------------------------------*
*Form fill_object_details
*---------------------------------------------------------------------*
FORM fill_object_details .
  DESCRIBE TABLE it_objtxt LINES tab_lines.
  READ TABLE it_objtxt INTO wa_objtxt INDEX tab_lines.
  wa_docdata-obj_name = 'TEST_HTML'.
  wa_docdata-obj_descr = 'Test for HTML Code'.
  wa_docdata-doc_size = ( tab_lines - 1 ) * 255 + STRLEN( wa_objtxt ).
  CLEAR wa_objpack-transf_bin.
  wa_objpack-head_start = 1.
  wa_objpack-head_num = 0.
  wa_objpack-body_start = 1.
  wa_objpack-body_num = tab_lines.
  wa_objpack-doc_type = 'HTM'.
  APPEND wa_objpack TO it_objpack.
ENDFORM. " fill_object_details
*---------------------------------------------------------------------*
*Form create_receivers_list
*---------------------------------------------------------------------*
FORM create_receivers_list .
  wa_reclist-receiver = p_rec.
  wa_reclist-rec_type = p_typ.
  APPEND wa_reclist TO it_reclist.
ENDFORM. " create_receivers_list
*---------------------------------------------------------------------
*Form send_mail
*---------------------------------------------------------------------\
FORM send_mail .
  CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
    EXPORTING
      document_data              = wa_docdata
      put_in_outbox              = ' '
      commit_work                = 'X'
    TABLES
      packing_list               = it_objpack
      contents_txt               = it_objtxt
      receivers                  = it_reclist
    EXCEPTIONS
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      OTHERS                     = 8.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno
    WITH sy-msgv1.
  ELSE.
    WRITE : / 'Mail sent to', p_rec.
  ENDIF.
ENDFORM. " send_mail

Author: Jatra Riwayanto
Submitted: 24.09.2007

Description:
There is several folder in our workplace like inbox, outbox, private folder.
This simple program will display mail list in inbox folder.

Selection Screen

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
SELECTION-SCREEN BEGIN OF BLOCK BLC01 WITH FRAME TITLE TEXT-S10.
  PARAMETERS: P_UNAME LIKE SY-UNAME OBLIGATORY DEFAULT SY-UNAME.
SELECTION-SCREEN END OF BLOCK BLC01.

Class Definition

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
CLASS LCL_MAIN DEFINITION.
  PUBLIC SECTION.
    METHODS: DISPLAY_INBOX.
*             DISPLAY_MAIL IMPORTING IM_MAILID TYPE STRING.
    EVENTS:  MESSAGE EXPORTING VALUE(MSG1) TYPE STRING
                               VALUE(MSG2) TYPE STRING OPTIONAL
                               VALUE(MSG3) TYPE STRING OPTIONAL
                               VALUE(MSG4) TYPE STRING OPTIONAL.
  PRIVATE SECTION.
    METHODS: CLEAR_DATA,
             GET_INBOX_CONTENT.
*---------------------------------
* L.O.C.A.L  D.A.T.A.
*---------------------------------
    DATA: USER      TYPE SOUDNAMEI1,
          UDAT      TYPE SOUDATAI1,
          FDAT      TYPE SOFOLDATI1,
          IT_FDAT   TYPE TABLE OF SOFOLENTI1,
          WA_FDAT   TYPE SOFOLENTI1.

    DATA: MSG1      TYPE STRING,
          MSG2      TYPE STRING,
          MSG3      TYPE STRING,
          MSG4      TYPE STRING.

    DATA: FOLD_ID   TYPE SOODK.
ENDCLASS.                    "lcl_main DEFINITION

CLASS LCL_HANDLER DEFINITION.
  PUBLIC SECTION.
    METHODS HANDLE_MESSAGE
            FOR EVENT MESSAGE OF LCL_MAIN
            IMPORTING MSG1 MSG2 MSG3 MSG4.
ENDCLASS.                    "lcl_handler DEFINITION

Class Implementation

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
CLASS LCL_MAIN IMPLEMENTATION.
*----------------------------------------------*
* METHOD clear_data                            *
*----------------------------------------------*
  METHOD CLEAR_DATA.
    CLEAR:    USER,
              UDAT,
              FDAT,
              IT_FDAT[],
              WA_FDAT,
              FOLD_ID
  ENDMETHOD.                    "clear_data

*----------------------------------------------*
* METHOD DISPLAY_INBOX                         *
*----------------------------------------------*
  METHOD DISPLAY_INBOX.
    CALL METHOD CLEAR_DATA( ).
    CALL METHOD GET_INBOX_CONTENT( ).
    IF IT_FDAT[] IS INITIAL.
      RAISE EVENT MESSAGE EXPORTING MSG1 = 'No emails in this inbox'.
    ENDIF.

    ULINE AT (114).
    FORMAT COLOR COL_HEADING.
    WRITE: / '|' NO-GAP, (020) 'Object ID'        LEFT-JUSTIFIED,
             '|' NO-GAP, (030) 'Subject'          LEFT-JUSTIFIED,
             '|' NO-GAP, (015) 'Date Recieved'    LEFT-JUSTIFIED,
             '|' NO-GAP, (040) 'Sender '          LEFT-JUSTIFIED,
             '|'.
    ULINE AT /(114).
    FORMAT COLOR OFF.

    LOOP AT IT_FDAT INTO WA_FDAT.
      FORMAT COLOR COL_NORMAL INTENSIFIED ON.
      WRITE: / '|' NO-GAP, (020) WA_FDAT-OBJECT_ID  UNDER 'Email ID'
                                 HOTSPOT ON,
               '|' NO-GAP, (030) WA_FDAT-OBJ_DESCR   LEFT-JUSTIFIED,
               '|' NO-GAP, (015) WA_FDAT-REC_DATE    LEFT-JUSTIFIED,
               '|' NO-GAP, (040) WA_FDAT-SEND_FNAM   LEFT-JUSTIFIED,
               '|'.
    ENDLOOP.
    ULINE AT /(114).
  ENDMETHOD.                    "DISPLAY_INBOX

*----------------------------------------------*
* METHOD GET_INBOX_CONTENT                         *
*----------------------------------------------*
  METHOD GET_INBOX_CONTENT.
    MOVE P_UNAME TO USER-SAPNAME.
    CALL FUNCTION 'SO_USER_READ_API1'
      EXPORTING
        USER                      = USER
*    prepare_for_folder_access = 'X'
      IMPORTING
        USER_DATA                 = UDAT
      EXCEPTIONS
        USER_NOT_EXIST            = 1
        PARAMETER_ERROR           = 2
        X_ERROR                   = 3
        OTHERS                    = 4.

    IF SY-SUBRC NE 0.
      CASE SY-SUBRC.
        WHEN 1. MSG1 = 'User Does not exist !'.
        WHEN 2. MSG1 = 'Parameter Error !'.
        WHEN 3. MSG1 = 'X Error!'.
        WHEN 4. MSG1 = 'Others Error !'.
      ENDCASE.
      RAISE EVENT MESSAGE EXPORTING MSG1 = MSG1.
    ENDIF.

*   Select inbox folder
    MOVE UDAT-INBOXFOL TO FOLD_ID.

    CALL FUNCTION 'SO_FOLDER_READ_API1'
      EXPORTING
        FOLDER_ID                  = FOLD_ID
      IMPORTING
        FOLDER_DATA                = FDAT
      TABLES
        FOLDER_CONTENT             = IT_FDAT
      EXCEPTIONS
        FOLDER_NOT_EXIST           = 1
        OPERATION_NO_AUTHORIZATION = 2
        X_ERROR                    = 3
        OTHERS                     = 4.

    IF SY-SUBRC NE 0.
      CASE SY-SUBRC.
        WHEN 1. MSG1 = 'Folder Does not exist !'.
        WHEN 2. MSG1 = 'No Authorization !'.
        WHEN 3. MSG1 = 'X Error!'.
        WHEN 4. MSG1 = 'Others Error !'.
      ENDCASE.
      RAISE EVENT MESSAGE EXPORTING MSG1 = MSG1.
    ENDIF.

  ENDMETHOD.                    "GET_INBOX_CONTENT

ENDCLASS.                    "lcl_main IMPLEMENTATION

CLASS LCL_HANDLER IMPLEMENTATION.

  METHOD HANDLE_MESSAGE .
    MESSAGE I398(00) WITH MSG1 MSG2 MSG3 MSG4.
    LEAVE LIST-PROCESSING..
  ENDMETHOD.                    "handle_message

ENDCLASS.                    "lcl_handler IMPLEMENTATION

Main Program

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
START-OF-SELECTION.
  DATA: O_MAIN           TYPE REF TO LCL_MAIN,
        O_HANDLER        TYPE REF TO LCL_HANDLER.

  CREATE OBJECT: O_MAIN, O_HANDLER.
  SET HANDLER O_HANDLER->HANDLE_MESSAGE FOR ALL INSTANCES.

  CALL METHOD O_MAIN->DISPLAY_INBOX.

Selection Screen:

*Inbox Content:*

The code below demonstrates how to send an SAP mail to a users inbox (SBWP)

REPORT zsapmail NO STANDARD PAGE HEADING.

TABLES: drad,
        qinf,
        draw,
        souc,
        sofd,
        drap.

DATA: p_return_code LIKE sy-subrc.

DATA: d_username LIKE drap-prnam.

* mail declarations
DATA : BEGIN OF new_object_id.         " the newly created email object
        INCLUDE STRUCTURE soodk.
DATA : END OF new_object_id.

DATA : BEGIN OF folder_id.             " the folder id of the outbox
        INCLUDE STRUCTURE soodk.
DATA : END OF folder_id.

DATA : BEGIN OF rec_tab OCCURS 5.     " the table which will contain the
        INCLUDE STRUCTURE soos1.       " information on the destination
DATA : END OF rec_tab.

DATA : BEGIN OF object_hd_change.      " the table which contains the
        INCLUDE STRUCTURE sood1.       " info for the object we will be
DATA : END OF object_hd_change.        " creating

DATA : object_type LIKE sood-objtp.    " the type of object

DATA : BEGIN OF objhead OCCURS 5.      " the header of the object
        INCLUDE STRUCTURE soli.
DATA : END OF objhead.

DATA : BEGIN OF objcont OCCURS 0.      " the contents of the object
        INCLUDE STRUCTURE soli.        " i.e. the text etc
DATA : END OF objcont.

DATA : BEGIN OF objpara OCCURS 5.      " formatting options
        INCLUDE STRUCTURE selc.
DATA : END OF objpara.

DATA : BEGIN OF objparb OCCURS 5.      " formatting options
        INCLUDE STRUCTURE soop1.
DATA : END OF objparb.

DATA : BEGIN OF t_mail_text OCCURS 0,  "Message table for messages to
        string(255),                   "user via mailbox
       END OF t_mail_text.

PARAMETER: p_uname LIKE sy-uname.

************************************************************************
**START-OF-SELECTION
START-OF-SELECTION.
  d_username = p_uname.
  PERFORM populate_email_text.

  PERFORM setup_trx_and_rtx_mailboxes USING p_return_code.
  PERFORM create_and_send_mail_object.

*---------------------------------------------------------------------*
*       FORM POPULATE_EMAIL_TEXT                                      *
*---------------------------------------------------------------------*
*       Inserts text for email message                                *
*---------------------------------------------------------------------*
FORM populate_email_text.
  CLEAR t_mail_text-string.            "puts a blank line in
  APPEND t_mail_text.
  APPEND t_mail_text.

*  adds failed list  on to end of success list.
  t_mail_text-string = 'Test email message line 1'.
  APPEND t_mail_text.
  t_mail_text-string = 'Test email message line 1'.
  APPEND t_mail_text.
  CLEAR t_mail_text-string.            "puts a blank line in
  APPEND t_mail_text.
  t_mail_text-string = 'Header1    Header2    Header3'.
  APPEND t_mail_text.
  t_mail_text-string = '-----------    ----------    -----------'.
  APPEND t_mail_text.
ENDFORM.                    "POPULATE_EMAIL_TEXT

*&---------------------------------------------------------------------*
*&      Form  SETUP_TRX_&_RTX_MAILBOXES
*&---------------------------------------------------------------------*
*   Ensure that the mailboxes of the sender (INTMGR) are set up OK
*----------------------------------------------------------------------*
FORM setup_trx_and_rtx_mailboxes USING p_return_code.

* get the user no of the sender in order to add the mail to the
* user name's outbox for future reference
  SELECT SINGLE * FROM souc
           WHERE sapnam = sy-uname.    "SAP name of a SAPoffice user
  IF sy-subrc NE 0.
    "Error finding the SAPoffice user info for the user
    MESSAGE e064(zr53) WITH sy-uname.
    p_return_code = 1.
    EXIT.
  ENDIF.
*Get the outbox No for the sender from the user No where the folder
  " type is an outbox
  SELECT * FROM sofd WHERE owntp = souc-usrtp   "Owner type from ID
                       AND ownyr = souc-usryr   "Owner year from the ID
                       AND ownno = souc-usrno   "Owner number from the I
                       AND folrg = 'O'."Output box
  ENDSELECT.

  IF sy-subrc NE 0.
    " Error getting folder information for the user
    MESSAGE e065(zr53) WITH sy-uname.
    p_return_code = 1.
    EXIT.
  ENDIF.
ENDFORM.                               " SETUP_TRX_&_RTX_MAILBOXES

*&---------------------------------------------------------------------*
*&      Form  CREATE_AND_SEND_MAIL_OBJECT
*&---------------------------------------------------------------------*
FORM create_and_send_mail_object.

  folder_id-objtp = sofd-foltp.        " the folder type ( usually FOL )
  folder_id-objyr = sofd-folyr.        " the folder year ( usually 22 )
  folder_id-objno = sofd-folno.        " the folder no.
  object_type     = 'RAW'.             " the type of object being added

* build up the object information for creating the object
  object_hd_change-objla  = sy-langu.  " the language of the email
  object_hd_change-objnam = 'PS to DM Interface'. " the object name

* mail subject 'Mass Linking of QA, pass/fail'
  MOVE text-002 TO object_hd_change-objdes.

  object_hd_change-dldat = sy-datum.   " the date of the email
  object_hd_change-dltim = sy-uzeit.   " the time of the email
  object_hd_change-objpri = '1'.       " the priority ( highest )
  object_hd_change-objsns = 'F'.       " the object sensitivity
* F is functional, C - company sensitive

* object_hd_change-skips  = ' '.       " Skip first screen
* object_hd_change-acnam  = 'SM35'.    " Batch imput transaction

* object_hd_change-vmtyp  = 'T'.       " Transaction type

* add the text lines into the contents of the email
  CLEAR objcont.
  REFRESH objcont.
*  free objcont.      " added this to delete the mail contents records
  LOOP AT t_mail_text.
    objcont-line = t_mail_text-string.
    APPEND objcont.
  ENDLOOP.
  CLEAR objcont.

* build up the table of receivers for the email
  rec_tab-rcdat = sy-datum.            " the date to send the email
  rec_tab-rctim = sy-uzeit.            " the time to send the email
* the SAP username of the person who will receive the email
  rec_tab-recnam = d_username.
* the user type of the person who will send the email ( USR )
  rec_tab-sndtp = souc-usrtp.
* the user year of the person who will send the email ( 22 )
  rec_tab-sndyr = souc-usryr.
* the user number of the person who will send the email
  rec_tab-sndno = souc-usrno.
* the sap username of the person who will send the email
  rec_tab-sndnam = sy-uname.

* get the user info for the receiver of the document
  SELECT SINGLE * FROM souc WHERE sapnam = d_username.
  IF sy-subrc NE 0.
    WRITE : / text-001, d_username.    "usnam.
    EXIT.
  ENDIF.

* the user number of the person who will receive the email ( USR )
  rec_tab-recno = souc-usrno.
* the user type of the person who will receive the email ( USR )
  rec_tab-rectp = souc-usrtp.
* the user year of the person who will receive the email ( USR )
  rec_tab-recyr = souc-usryr.
* the priority of the email ( highest )
  rec_tab-sndpri = '1'.
* check for delivery on the email
  rec_tab-deliver = 'X'.
* send express so recipient knows there is a problem
  rec_tab-sndex = 'X'.
* check for a return receipt
  rec_tab-read = 'X'.
* the sap username of the person receiving the email
  rec_tab-adr_name = d_username.       "usnam.
* add this receiver to the internal table
  APPEND rec_tab.
  CLEAR rec_tab.

* call the function to create the object in the outbox of the sender
  CALL FUNCTION 'SO_OBJECT_INSERT'
    EXPORTING
      folder_id                  = folder_id
      object_hd_change           = object_hd_change
      object_type                = object_type
      owner                      = sy-uname
    IMPORTING
      object_id                  = new_object_id
    TABLES
      objcont                    = objcont
      objhead                    = objhead
      objpara                    = objpara
      objparb                    = objparb
    EXCEPTIONS
      active_user_not_exist      = 1
      communication_failure      = 2
      component_not_available    = 3
      dl_name_exist              = 4
      folder_not_exist           = 5
      folder_no_authorization    = 6
      object_type_not_exist      = 7
      operation_no_authorization = 8
      owner_not_exist            = 9
      parameter_error            = 10
      substitute_not_active      = 11
      substitute_not_defined     = 12
      system_failure             = 13
      x_error                    = 14
      OTHERS                     = 15.
  IF sy-subrc NE 0.
    MESSAGE a063(zr53) WITH sy-subrc.
    EXIT.
  ENDIF.

* call the function to send the already created email to the receivers
  CALL FUNCTION 'SO_OBJECT_SEND'
    EXPORTING
      folder_id                  = folder_id
      object_id                  = new_object_id
      outbox_flag                = 'X'
      owner                      = sy-uname
    TABLES
      receivers                  = rec_tab
    EXCEPTIONS
      active_user_not_exist      = 1
      communication_failure      = 2
      component_not_available    = 3
      folder_not_exist           = 4
      folder_no_authorization    = 5
      forwarder_not_exist        = 6
      note_not_exist             = 7
      object_not_exist           = 8
      object_not_sent            = 9
      object_no_authorization    = 10
      object_type_not_exist      = 11
      operation_no_authorization = 12
      owner_not_exist            = 13
      parameter_error            = 14
      substitute_not_active      = 15
      substitute_not_defined     = 16
      system_failure             = 17
      too_much_receivers         = 18
      user_not_exist             = 19
      x_error                    = 20
      OTHERS                     = 21.
  IF sy-subrc EQ 0.
    MESSAGE i035(zr53) WITH new_object_id d_username. "usnam.
  ELSE.
    MESSAGE i036(zr53) WITH d_username."      sy-subrc.
  ENDIF.
ENDFORM.                               " CREATE_AND_SEND_MAIL_OBJECT
 

Sending mail from SAP and getting read-receipt.
  

  1. BASIS settings to be done :            SCOT->Settings->Confirmation of Receipts -> SAP expects receipt confirmations for Internet mail   
  2. Requesting Read Receipt using Class:               CLEAR send_request.
        TRY.
    *     ------- create persistent send request -----------------------
            send_request = cl_bcs=>create_persistent( ).

*     ------- create and set document with attachment --------------
*     create document from internal table with text

*Create the content of the mail
 ONCATENATE 'This is for test' INTO v_objdes SEPARATED BY space.
        APPEND  v_objdes TO text.
        document = cl_document_bcs=>create_document(
                        i_type    = 'RAW'
                        i_text    = i_text
                        i_subject = v_objdes ).
  
        REFRESH i_text.
        CLEAR v_objdes.   
CALL METHOD send_request->set_document( document ).
 sender = cl_sapuser_bcs=>create( sy-uname ).        
        CALL METHOD send_request->set_sender
          EXPORTING
            i_sender = sender.
          
  *     -------- add recipient (e-mail address) ----------------------
*     create recipient - please replace e-mail address !!!
*    here only need to specify about read receipt
         {}v_mail  = 'papiya@gmail.com'.
          l_recipient_soos-recesc = 'U'.
        l_recipient_soos-recextnam = v_mail.
        l_recipient_soos-read      = 'X'.

        TRY.
            CALL METHOD cl_send_request_bcs=>create_recipient_from_soos1
              EXPORTING
                i_soos1 = l_recipient_soos
              RECEIVING
                result  = recipient.
          CATCH cx_send_req_bcs .
        ENDTRY.
*     add recipient with its respective attributes to send request
        CALL METHOD send_request->add_recipient
          EXPORTING
            i_recipient = recipient
            i_express   = 'X'.
        CLEAR v_mail.
TRY.
          CALL METHOD send_request->set_status_attributes
            EXPORTING
              i_requested_status = i_requested_status
              i_status_mail      = i_status_mail.
* CATCH cx_send_req_bcs .
        ENDTRY.
 SPAN

Unknown macro: { font-family}

.L0S33

Unknown macro: { color}

.L0S52

Unknown macro: { color}

CALL METHOD send_request->send(
          EXPORTING
            i_with_error_screen = 'X'
          RECEIVING
            result              = sent_to_all ).WITH FUNCTION MODULE :
 DATA: wa_email TYPE zdm_email_id_s,
         wa_document      TYPE sodocchgi1,
         v_desc_lines    TYPE sy-tabix,
         it_mail_msg_ob  TYPE TABLE OF solisti1,
         wa_mail_msg_ob  TYPE solisti1,
         it_packing_ob   TYPE TABLE OF sopcklsti1,
         wa_packing_ob   TYPE sopcklsti1,
         it_receivers_ob TYPE TABLE OF somlreci1,
         wa_receivers_ob TYPE somlreci1.

  CONSTANTS: c_sender         TYPE soextreci1-receiver VALUE 'WF-BATCH',
             c_ehs_email_ob   TYPE sopcklsti1-obj_name VALUE 'EHS_EMAIL',
             c_int_ob         TYPE soextreci1-adr_typ  VALUE 'INT',
             c_255_ob         TYPE i       VALUE '255',
             c_zero_ob(15)    TYPE c       VALUE '0'  ,
             c_one_ob(15)     TYPE c       VALUE '1'  ,
             c_doc_type_ob(3TYPE c       VALUE 'RAW'.

  IF zdm_email[] IS NOT INITIAL.
**  Getting the receivers email IDs

      wa_receivers_ob-receiver = 'papiya@gmail.com'.

      wa_receivers_ob-rec_type = 'U'.
      wa_receivers_ob-notif_read = 'X'.

      APPEND wa_receivers_ob TO it_receivers_ob.
    **  Filling the Mail Content
 
        clear wa_mail_msg_ob.
        CONCATENATE text-025
                    text-026
               INTO wa_mail_msg_ob
          SEPARATED BY space.
        APPEND wa_mail_msg_ob to it_mail_msg_ob.
        clear wa_mail_msg_ob.
        move text-027 to wa_mail_msg_ob.
        append wa_mail_msg_ob to it_mail_msg_ob.

        move space to wa_mail_msg_ob.
        APPEND wa_mail_msg_ob to it_mail_msg_ob.

 
    CONCATENATE 'This is just a test document' '.'
           INTO wa_mail_msg_ob
      SEPARATED BY space.
    APPEND wa_mail_msg_ob TO it_mail_msg_ob.

    DESCRIBE TABLE it_mail_msg_ob LINES v_desc_lines.
    READ TABLE it_mail_msg_ob INDEX v_desc_lines
                            INTO wa_mail_msg_ob.
    wa_document-doc_size  = ( v_desc_lines - 1 ) * c_255_ob
                                              + STRLEN( wa_mail_msg_ob ).
    wa_document-obj_langu = sy-langu.
    wa_document-obj_name  = c_ehs_email_ob.
**  Filling the Mail Title

    CONCATENATE 'ATTN:This is test.'
           INTO wa_document-obj_descr
      SEPARATED BY space.

    wa_packing_ob-transf_bin = space.
    wa_packing_ob-head_start = c_one_ob.
    wa_packing_ob-head_num   = c_zero_ob.
    wa_packing_ob-body_start = c_one_ob.
    DESCRIBE TABLE it_mail_msg_ob LINES wa_packing_ob-body_num.
    wa_packing_ob-doc_type   = c_doc_type_ob.
    APPEND wa_packing_ob TO it_packing_ob.
** Sending Mail for obsolete
    CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
      EXPORTING
        document_data                    = wa_document
        sender_address                   = c_sender
*                 SENDER_ADDRESS_TYPE              = 'B'
       commit_work                      = 'X'
      TABLES
        packing_list                     = it_packing_ob
        contents_txt                     = it_mail_msg_ob
        receivers                        = it_receivers_ob
      EXCEPTIONS
         too_many_receivers               = 1
         document_not_sent                = 2
         document_type_not_exist          = 3
         operation_no_authorization       = 4
         parameter_error                  = 5
         x_error                          = 6
         enqueue_error                    = 7
         OTHERS                           = 8
              .
    IF sy-subrc <> 0.

    ENDIF.

  ENDIF.

  EXIT.
To check if the settings done by you are correct:
You need to check the MIME data of an email:
To check the MIME:
A) Please implement note 845449 if it is not already in your
system.


B) Please run report RSCONN06 and select the Always Save option for
outgoing emails. Send another email and then display the MIME
version of this email. The MIME version can be displayed for outbound
e-mails in transaction SOST by right-clicking on a send job using
'Display MIME display ' or 'MIME version'.
If it is showing like the settings below your settings are perfect.
Disposition-Notification-To: Papiya <papiya@gmail.com>
Return-Receipt-To: Papiya <papiya@gmail.com>
Lastly also these steps has to be noted for the delivery and the read receipt settings to work perfectly:
When 'A' sends email with a *Delivery Receipt* request, to "B" the Delivery Receipt is answered by ESMTP on B's mail server. A Delivery Receipt is sent from the server hosting the recipient's mailbox, when the message is delivered to the mail box. The purpose of this is to confirm to the sender that the message reached the recipient's mailbox's (Delivery Service Notifications) refers to both a service that may optionally be provided by Message Transfer Agents
 (MTAs) using the Simple Mail Transfer Protocol (SMTP), and a message format to be used to return indications of message delivery to the sender of that message. Specifically, the DSN SMTP service is used to request that indications of successful delivery or delivery failure (in the DSN format) be returned. Issuance of a DSN upon delivery failure is the default behavior, whereas issuance of a DSN upon successful delivery requires a specific request from the sender.
Moreover some settings need to be done in the recipient client's mail box also.
For Microsoft outlook the settings that need to be done are:

In many email clients, you can configure delivery and read receipts.  A delivery receipt is an email alert when your email has been delivered to an accepting mail server for the recipient of your email.  A read receipt is an email you receive when a user reads the email.  However, a read receipt is only sent if the user desires to send you one - as such I find it unreliable.  I also find it annoying when I receive emails with a read receipt request.  They cause outlook to give a popup message unless you've configured it to always ignore or always send read receipts.  This article will show you how to configure your Outlook 2007 email client (this might also work the same in Outlook 2003 and before) to request delivery receipts (read receipts are on the same screen if you insist) on all emails you send out.

  1. From the Oulook Tools menu, select Options (if you don't see the Options menu item, you may ahve to expand the menu window with that little double arrow that points downward).
  2. In the next screen for Options, click on the Email Options button
  3. In the next screen Email Options, click on the Tracking Options button.
  4. In the Tracking Options screen, you have a checkmark for Delivery receipt.  Click this and all your emails you send out will give you an alert when your email server delivers them.

If you start getting annoyed with all of the delivery receipts, then just come back here and take that check mark off.  Also notice the options on this screen for how to reply to read receipts and why I don't believe in them.  Never send a response is an option.  Additionally, if they have checked Always send a response and it only becomes "read" from their preview pane in Outlook (which you should turn off), but they didn't actually read it, you get a read receipt.

Sending Mails - Home Page

Author: Suresh Maryala
Submitted: 07/10/2008
Related Links:

  • Selection Screen Details

As part of the Selection screen user inputs Training Name, Location, Begin date, End Date, Pernr or User type and Pernr number or user id. . 

Program Logic

Based on information provided to selection screen, program reads infotype 105 to find the user id or pernr and also the e-mail address. User id is stored in sub type 0001 and e-mail address is stored in sub type 0010.  Process

  • *# Read infotype 0105 to find the PERNR, User ID and E-mail address
    1. Build internal table for Microsoft calendar entry
    2. Build training details to be part of text
    3. Call so_raw_to_rtf to convert the calendar entry details to have line breaks
    4. Call method send_request to send the e-mail 
    5. Add entry in table TSOPE with VCS and ASCII check box selected
  •  

ABAP Code

DATA: text               TYPE bcsy_text.
DATA: document           TYPE REF TO cl_document_bcs.
DATA: sender             TYPE REF TO cl_sapuser_bcs.
DATA: recipient          TYPE REF TO if_recipient_bcs.
DATA: bcs_exception      TYPE REF TO cx_bcs.
DATA: sent_to_all        TYPE os_boolean.
DATA: it_content         TYPE soli_tab.
DATA: it_attach          TYPE soli_tab.
DATA: send_request       TYPE REF TO cl_bcs.
DATA: l_subject          LIKE sodocchgi1-obj_descr,
      l_sender_type      LIKE soextreci1-adr_typ,
      l_recsize          TYPE i,
      l_receiver         TYPE sy-subrc.
DATA: lt_soli            TYPE soli_tab    .
DATA: ls_soli            LIKE LINE OF lt_soli.
DATA: lt_soli_new        TYPE soli_tab.
DATA: ls_email           TYPE pa0105-usrid_long.
DATA: ls_uname           TYPE pa0105-usrid.
DATA: ls_pernr           TYPE pernr-pernr.
DATA: ls_begin(10)       TYPE c.
DATA: ls_end(10)         TYPE c.
DATA: result        TYPE REF TO cl_document_bcs.
DATA: BEGIN OF ls_data,
  sender TYPE lsoppvar-sender,  "sender
  kbgda  TYPE ppvar-kbgda,      "begin date
  kndda  TYPE ppvar-endda,      "end date
  kbtim  TYPE ppvar-kbtim,      "begin time first day
  ketim  TYPE ppvar-ketim,      "end time last day
  kstxt  TYPE ppvar-kstxt,      "training text
  b_ort  TYPE ppvar-b_ort,      "training location
  rstxt  TYPE ppvar-rstxt,      "room text
  amail  TYPE lsoppvar-amail,   "recipient eMail
  astxt  TYPE ppvar-astxt,      "recipient
END OF ls_data.
FIELD-SYMBOLS: <fs_soli> LIKE ls_soli.
************************************************************************
* SELECTION SCREEN DEFINITION
************************************************************************
SELECTION-SCREEN BEGIN OF BLOCK group WITH FRAME TITLE text-001.
PARAMETERS:  p_trnam   LIKE p1000-stext DEFAULT 'TRAINING NAME',
             p_locnm   LIKE p1000-stext DEFAULT 'LOCATION',
             p_begda   LIKE p1000-begda DEFAULT '20081101',
             p_endda   LIKE p1000-endda DEFAULT '20081104',
             p_ltype   LIKE lso_borkey_participation-learnertype DEFAULT 'P',
             p_lid     LIKE lso_borkey_participation-learnerid DEFAULT '10000137'.
SELECTION-SCREEN END   OF BLOCK group.
************************************************************************
* INITIALIZATION
************************************************************************
INITIALIZATION.

START-OF-SELECTION.
  CASE p_ltype.
    WHEN 'P'.
* Move PERNR number to variable
      ls_pernr = p_lid.
    WHEN 'US'.
      ls_uname = p_lid.
      CONDENSE ls_uname.
      SELECT SINGLE pernr FROM pa0105 INTO ls_pernr WHERE
                                usrid = ls_uname AND
                                begda LE sy-datum AND
                                endda GE sy-datum AND
                                subty = '0001'.
  ENDCASE.
* Read infotype 0105 and subtypes 0001 and 0010
* Sub type 0001 has username
* sub type 0010 has e-mail
  SELECT SINGLE usrid_long FROM pa0105 INTO ls_email WHERE
                         pernr = ls_pernr AND
                         begda LE sy-datum AND
                         endda GE sy-datum AND
                         subty = '0010'.
  SELECT SINGLE usrid FROM pa0105 INTO ls_uname WHERE
                         pernr = ls_pernr AND
                         begda LE sy-datum AND
                         endda GE sy-datum AND
                         subty = '0001'.
  PERFORM f_data.
*&---------------------------------------------------------------------*
*&      Form  f_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM f_data .
* Calendar logic begin
  ls_soli-line = 'BEGIN:VCALENDAR'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'VERSION:1.0'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'METHOD:REQUEST'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'BEGIN:VEVENT'.
  APPEND ls_soli TO lt_soli.
  CONCATENATE 'ATTENDEE;CN=' ls_uname ';ROLE=REQ-PARTICIPANT;RSVP=TRUE:MAILTO:' ls_email INTO ls_soli-line.
  APPEND ls_soli TO lt_soli.
  CONCATENATE 'DTSTART:' p_begda 'T140000Z' INTO ls_soli-line.
  APPEND ls_soli TO lt_soli.
  CONCATENATE 'DTEND:' p_endda 'T220000Z' INTO ls_soli-line.
  APPEND ls_soli TO lt_soli.
  CONCATENATE 'LOCATION:' p_locnm INTO ls_soli-line.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'TRANSP:OPAQUE'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'SEQUENCE:1'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'DESCRIPTION: Course Participation'.
  APPEND ls_soli TO lt_soli.
  CONCATENATE 'SUMMARY: Course Participation for ' ls_uname INTO ls_soli-line SEPARATED BY space.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'PRIORITY:5'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'X-MICROSOFT-CDO-IMPORTANCE:1'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'CLASS:PUBLIC'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'END:VEVENT'.
  APPEND ls_soli TO lt_soli.
  ls_soli-line = 'END:VCALENDAR'.
  APPEND ls_soli TO lt_soli.
* End of Calendar
* Call this function module to convert data created for calendar entry
*
  CALL FUNCTION 'SO_RAW_TO_RTF'
    TABLES
      objcont_old = lt_soli[]
      objcont_new = lt_soli_new[].
  l_subject = 'Course Participation'.
  ls_soli-line = 'This is to notify following course has been approved'.
  APPEND ls_soli TO it_content.
  CLEAR ls_soli.
  APPEND ls_soli TO it_content.
  CONCATENATE 'Training Name: ' p_trnam INTO ls_soli-line.
  APPEND ls_soli TO it_content.
  CLEAR ls_soli.
  APPEND ls_soli TO it_content.
  WRITE p_begda TO ls_begin.
  WRITE p_endda TO ls_end.
  CONCATENATE 'Begin Date: ' ls_begin INTO ls_soli-line.
  APPEND ls_soli TO it_content.
  CLEAR ls_soli.
  APPEND ls_soli TO it_content.
  CONCATENATE 'End Date: ' ls_end INTO ls_soli-line.
  APPEND ls_soli TO it_content.
  CLEAR ls_soli.
  APPEND ls_soli TO it_content.
  CONCATENATE 'Location Name: ' p_locnm INTO ls_soli-line.
  APPEND ls_soli TO it_content.
  CLEAR ls_soli.
  APPEND ls_soli TO it_content.
  TRY.
* Create persistent send request
      send_request = cl_bcs=>create_persistent( ).
      document = cl_document_bcs=>create_document(
                                    i_type    = 'RAW'
                                    i_text = it_content[]
                                    i_subject = l_subject ).
      DESCRIBE TABLE lt_soli.
      CALL METHOD document->add_attachment
        EXPORTING
          i_attachment_type    = 'VCS'
          i_attachment_subject = 'Course'
          i_att_content_text   = lt_soli_new[].
* Add document to send request
      CALL METHOD send_request->set_document( document ).
* Get sender object
      sender = cl_sapuser_bcs=>create( sy-uname ).
* Add sender
      CALL METHOD send_request->set_sender
        EXPORTING
          i_sender = sender.
*     ------ add recipient (e-mail address) ----------------------
*     create recipient

*  Enter a valid e-mail address
      recipient = cl_cam_address_bcs=>create_internet_address(
                                        ls_email ).
*     add recipient with its respective attributes to send request
      CALL METHOD send_request->add_recipient
        EXPORTING
          i_recipient  = recipient
          i_express    = 'U'
          i_copy       = ' '
          i_blind_copy = ' '
          i_no_forward = ' '.
********Trigger e-mails immediately****************************
      send_request->set_send_immediately( 'X' ).
      CALL METHOD send_request->send(
        EXPORTING
          i_with_error_screen = 'X'
        RECEIVING
          result              = sent_to_all ).
      IF sent_to_all = 'X'.
        WRITE 'Document Sent Successfully'.
      ENDIF.
      COMMIT WORK.
    CATCH cx_document_bcs INTO bcs_exception.
      WRITE: 'Error Occurred'.
      WRITE: 'Error Type', bcs_exception->error_type.
      EXIT.
  ENDTRY.
ENDFORM.                    " f_data

Author: Subrahmanya Pindiproli
Submitted: 14-May-2012

HTML Formatted attachments using ABAP 

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*-----------------------------------------------------------------------*

* Program Name        : ZRPT_FORMATTED_EMAIL_1                          *
* Author              : Subrahmanya Pindiproli                          *
* Requested By        : N.A                                             *
* Date created        : 2012/04/12                                      *
* SAP Release         : ECC6.0                                          *
* Project Name        : N.A                                             *
* Task #              :                                                 *
* Description         : Formatted Emails using HTML in ABAP using the   *
*                       FM : SO_NEW_DOCUMENT_ATT_SEND_API1              *
*-----------------------------------------------------------------------*
* Change History                                                        *
*-----------------------------------------------------------------------*
*                                                                       *
*                                                                       *
*-----------------------------------------------------------------------*
REPORT  zrpt_formatted_email_1.

*-----------------------------------------------------------------------*
*                   D A T A    D E C L A R A T I O N S                  *
*-----------------------------------------------------------------------*

DATA:
t_objtxt   TYPE STANDARD TABLE OF solisti1,             " Message body
t_objpack  TYPE STANDARD TABLE OF sopcklsti1,           " Packing list
t_reclist  TYPE STANDARD TABLE OF somlreci1,            " Receipient list
t_html     TYPE STANDARD TABLE OF w3html.               " Html


DATA:
lv_tmp_str TYPE                   string,
wa_htmlline TYPE                  w3html.

DATA : t_table       TYPE STANDARD TABLE OF ssfbin,
       t_attachment  TYPE STANDARD TABLE OF solix.


DATA:
wa_docdata TYPE sodocchgi1,                             " Document data
wa_objtxt  TYPE solisti1,                               " Message body
*wa_objbin  TYPE solisti1,                               " Attachment data
wa_objpack TYPE sopcklsti1,                             " Packing list
wa_reclist TYPE somlreci1.                              " Receipient list

*DATA: w_tab_lines TYPE i.                               " Table lines

* Internal Table for Data in Email Body
TYPES : BEGIN OF ty_mara,
        matnr TYPE matnr,
        bismt TYPE bismt,
        groes TYPE groes,
  END OF ty_mara.

DATA : t_mara   TYPE STANDARD TABLE OF ty_mara,
*       l_count  TYPE                   i,
       v_ld_sender_address LIKE  soextreci1-receiver,
       v_ld_sender_address_type LIKE  soextreci1-adr_typ,
       v_sent_all(1) TYPE c.

* Constants
CONSTANTS :   c_u TYPE so_escape VALUE 'U'.              "Specification of recipient type
*              c_x TYPE sonv-flag VALUE 'X'.

*-----------------------------------------------------------------------*
*                S E L E C T I O N     S C R E E N                      *
*-----------------------------------------------------------------------*
PARAMETERS: p_email TYPE char120 OBLIGATORY
                    VISIBLE LENGTH 40 LOWER CASE.

*-----------------------------------------------------------------------*
*              S T A R T    O F    S E L E C T I O N                    *
*-----------------------------------------------------------------------*
START-OF-SELECTION.

* Get Report Data
  PERFORM get_data.

* Process Data ( Placeholder Subroutine )
  PERFORM process_data.

* Creating message
  PERFORM create_message.

* Sending Message
  PERFORM send_message.

*&---------------------------------------------------------------------*
*&      Form  create_message
*&---------------------------------------------------------------------*
*       Create the Email Title, Description, Body and populate the     *
*       receiver list.                                                 *
*----------------------------------------------------------------------*
FORM create_message .

**1 Title, Description & Body
  PERFORM create_title_desc_body.

**2 Receivers
  PERFORM fill_receivers.

ENDFORM.                    " create_message

*&---------------------------------------------------------------------*
*&      Form  CREATE_TITLE_DESC_BODY
*&---------------------------------------------------------------------*
*       Title, Description and body
*----------------------------------------------------------------------*
FORM create_title_desc_body.

  PERFORM itab_to_html.
  PERFORM build_email_body.

ENDFORM.                    " CREATE_TITLE_DESC_BODY

*&---------------------------------------------------------------------*
*&      Form  fill_receivers
*&---------------------------------------------------------------------*
*       Filling up the Receivers
*----------------------------------------------------------------------*
FORM fill_receivers .

  wa_reclist-receiver = p_email.
  wa_reclist-rec_type = c_u.
  APPEND wa_reclist TO t_reclist.
  CLEAR  wa_reclist.


ENDFORM.                    " fill_receivers
*&---------------------------------------------------------------------*
*&      Form  send_message
*&---------------------------------------------------------------------*
*       Sending Mail
*----------------------------------------------------------------------*
FORM send_message .

* function module to send email
  IF NOT t_attachment[] IS INITIAL .
*Describe the body of the message
    CLEAR wa_objpack.
    REFRESH t_objpack.
    wa_objpack-transf_bin = space.
    wa_objpack-head_start = 1.
    wa_objpack-head_num = 0.
    wa_objpack-body_start = 1.

    DESCRIBE TABLE t_objtxt LINES wa_objpack-body_num.
    wa_objpack-doc_type = 'RAW'.
    APPEND wa_objpack TO t_objpack.

*Create attachment notification
    wa_objpack-transf_bin = 'X'.
    wa_objpack-head_start = 1.
    wa_objpack-head_num   = 1.
    wa_objpack-body_start = 1.

*Create packing list
    DESCRIBE TABLE t_attachment LINES wa_objpack-body_num.
    wa_objpack-doc_type   =  'HTML'.
    wa_objpack-obj_descr  =  'Material Master Data'.
    wa_objpack-doc_size   =  wa_objpack-body_num * 255.
    APPEND wa_objpack TO t_objpack.

    CLEAR v_sent_all.

*Call FM to send e-mail with attachment
    CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
      EXPORTING
        document_data              = wa_docdata
        put_in_outbox              = 'X'
        sender_address             = v_ld_sender_address
        sender_address_type        = v_ld_sender_address_type
        commit_work                = 'X'
      IMPORTING
        sent_to_all                = v_sent_all
      TABLES
        packing_list               = t_objpack
        contents_hex               = t_attachment
        contents_txt               = t_objtxt
        receivers                  = t_reclist
      EXCEPTIONS
        too_many_receivers         = 1
        document_not_sent          = 2
        document_type_not_exist    = 3
        operation_no_authorization = 4
        parameter_error            = 5
        x_error                    = 6
        enqueue_error              = 7
        OTHERS                     = 8.

    IF sy-subrc NE 0.
      WRITE: 'Sending Failed'.
    ELSE.
      WRITE: 'Sending Successful'.
    ENDIF.

  ENDIF.
ENDFORM.                    " send_message
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       A core subroutine to fetch the data from the corresponding     *
*       database tables.                                               *
*----------------------------------------------------------------------*
FORM get_data .
  REFRESH t_mara.
  SELECT matnr bismt groes UP TO 10 ROWS
         FROM mara INTO TABLE t_mara.

  IF sy-subrc EQ 0.
    SORT t_mara BY matnr.
  ENDIF.
ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  PROCESS_DATA
*&---------------------------------------------------------------------*
*       This is a placeholder subroutine and can be used for processing*
*       the report data and getting into final internal tables before  *
*       starting the HTML formatting and emailing the data             *
*----------------------------------------------------------------------*
FORM process_data .

ENDFORM.                    " PROCESS_DATA

*&---------------------------------------------------------------------*
*&      Form  ITAB_TO_HTML
*&---------------------------------------------------------------------*
*       This is a subroutine which uses standard SAP Function Modules  *
*       WWW_ITAB_TO_HTML_HEADERS, WWW_ITAB_TO_HTML_LAYOUT  and         *
*       WWW_ITAB_TO_HTML                                               *
*----------------------------------------------------------------------*
FORM itab_to_html.

  DATA:
    t_header  TYPE STANDARD TABLE OF w3head WITH HEADER LINE,    " Header
    t_fields  TYPE STANDARD TABLE OF w3fields WITH HEADER LINE,  " Fields
    fs_header TYPE w3head,
    w_head    TYPE w3head.

  DATA:  t_fcat  TYPE                   lvc_t_fcat,             " Fieldcatalog
         wa_fcat LIKE LINE OF           t_fcat.

*-Populate Fieldcatalog
  REFRESH t_fcat. CLEAR wa_fcat.
  wa_fcat-coltext = 'Material Number'.
  APPEND wa_fcat TO t_fcat.
  wa_fcat-coltext = 'Old Material No.'.
  APPEND wa_fcat TO t_fcat.
  wa_fcat-coltext = 'Size/Dimensions'.
  APPEND wa_fcat TO t_fcat.

*-Fill the Column headings and Properties

  LOOP AT t_fcat INTO wa_fcat.
    w_head-text = wa_fcat-coltext.
*-Populate the Column Headings
    CALL FUNCTION 'WWW_ITAB_TO_HTML_HEADERS'
      EXPORTING
        field_nr = sy-tabix
        text     = w_head-text
        fgcolor  = 'black'
        bgcolor  = 'red'
      TABLES
        header   = t_header.

*-Populate Column Properties
    CALL FUNCTION 'WWW_ITAB_TO_HTML_LAYOUT'
      EXPORTING
        field_nr = sy-tabix
        fgcolor  = 'black'
        size     = '7'
      TABLES
        fields   = t_fields.
  ENDLOOP.

*-Title of the Display
  fs_header-text = 'Automated Emails from SAP Applications'.
  fs_header-font = 'Arial'.
  fs_header-size = '2'.

*-Preparing the HTML from Intenal Table
  REFRESH t_html.

  CALL FUNCTION 'WWW_ITAB_TO_HTML'
    EXPORTING
      table_header = fs_header
    TABLES
      html         = t_html
      fields       = t_fields
      row_header   = t_header
      itable       = t_mara.


  LOOP AT t_html INTO wa_htmlline.
    CONCATENATE lv_tmp_str wa_htmlline INTO lv_tmp_str.
  ENDLOOP .


**** Convert HTML data in pit_attach-content to RAW data format
  IF NOT lv_tmp_str IS INITIAL.
    CALL FUNCTION 'SSFH_STRING_TO_TABUTF8'
      EXPORTING
       cstr_input_data         = lv_tmp_str
       codepage                = '4110'
* IMPORTING
*   OSTR_INPUT_DATA_L       =
      TABLES
        ostr_input_data         = t_table
   EXCEPTIONS
     conversion_error        = 1
     internal_error          = 2
     OTHERS                  = 3.

    IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.

    t_attachment[] = t_table[].
    REFRESH: t_table[].
  ENDIF.



ENDFORM.                    "ITAB_TO_HTML
*&---------------------------------------------------------------------*
*&      Form  BUILD_EMAIL_BODY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM build_email_body .

*...Title
  wa_docdata-obj_name  = 'This is the Email Subject'.

*...Description
  wa_docdata-obj_descr = 'Description of Email with a max length of 50 Chars'.


  wa_objtxt-line = 'Dear Sir / Madam'.
  APPEND wa_objtxt TO t_objtxt.

  wa_objtxt-line = 'This is an Automated Email from SAP Applications. '.
  APPEND wa_objtxt TO t_objtxt.



  CLEAR wa_objtxt.  APPEND wa_objtxt TO t_objtxt.
  CLEAR wa_objtxt.  APPEND wa_objtxt TO t_objtxt.
  CLEAR wa_objtxt.  APPEND wa_objtxt TO t_objtxt.


*   Signature with background color
  wa_objtxt-line = 'Best Regards,'.
  APPEND wa_objtxt TO t_objtxt.
  wa_objtxt-line = 'Subrahmanya Pindiproli'.
  APPEND wa_objtxt TO t_objtxt.
  wa_objtxt-line = 'Principal Consultant - ERP'.
  APPEND wa_objtxt TO t_objtxt.
ENDFORM.                    " BUILD_EMAIL_BODY

Sending an email in ABAP should be done via BCS (class CL_BCS and related).

Don't use these obsolete APIs:

  • SO_OBJECT_SEND is an old function module for sending emails.
  • Etc.

This WIKI can be used as a reference for sending the report output as a screenshot in the body of the E-mail.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
DATA: li_receivers       TYPE STANDARD TABLE OF soos1,
      li_listobject      TYPE STANDARD TABLE OF abaplist,
      li_ali             TYPE STANDARD TABLE OF soli,
      li_ali1            TYPE STANDARD TABLE OF soli,
      li_ali2            TYPE STANDARD TABLE OF soli,
      lwa_objecthdchange TYPE sood1,
      lwa_receivers      TYPE soos1,
      lwa_ali            TYPE soli.
DATA: l_lines   TYPE i,
      l_length  TYPE i.

DO 10 TIMES.
  NEW-LINE.
  ULINE (99).
  WRITE: /1 sy-vline,
          2 'column1',
         24 sy-vline,
         25 'Column2',
         49 sy-vline,
         50 'Column3',
         74 sy-vline,
         75 'Column4',
         99 sy-vline.
ENDDO.

NEW-LINE.
ULINE (99).
NEW-LINE.

CALL FUNCTION 'SAVE_LIST'
  EXPORTING
    list_index         = '0'    "Pass the list index like 0, 1, 2...
  TABLES
    listobject         = li_listobject
  EXCEPTIONS
    list_index_invalid = 1
    OTHERS             = 2.
IF sy-subrc NE 0.
  RAISE invalid_list.
ENDIF.

* Convert the list to ALI format
CALL FUNCTION 'TABLE_COMPRESS'
  TABLES
    in             = li_listobject
    out            = li_ali
  EXCEPTIONS
    compress_error = 1
    OTHERS         = 2.
IF sy-subrc NE 0.
  RAISE compress_error.
ENDIF.

CLEAR: lwa_objecthdchange.
DESCRIBE TABLE li_ali LINES l_lines.
DESCRIBE FIELD lwa_ali LENGTH l_length IN CHARACTER MODE.

lwa_objecthdchange-objlen = l_length * l_lines.
lwa_objecthdchange-objla  = sy-langu.
lwa_objecthdchange-objnam = 'List'.

MOVE sy-title TO lwa_objecthdchange-objdes.

MOVE: 1 TO lwa_objecthdchange-objpri,
      0 TO lwa_objecthdchange-objsns.

CLEAR: lwa_receivers.
MOVE: 'X'                 TO lwa_receivers-snddr,
      'X'                 TO lwa_receivers-sndex,
      'U'                 TO lwa_receivers-recesc,
      'E-MAIL' TO lwa_receivers-recextnam.          "Pass the recipient ID here.

APPEND lwa_receivers TO li_receivers.

* Send email
CALL FUNCTION 'SO_OBJECT_SEND'
 EXPORTING
*   FOLDER_ID                        = ' '
*   FORWARDER                        = ' '
*   OBJECT_FL_CHANGE                 = ' '
   object_hd_change                 = lwa_objecthdchange
*   OBJECT_ID                        = ' '
   object_type                      = 'ALI'
*   OUTBOX_FLAG                      = ' '
   owner                            = sy-uname
*   STORE_FLAG                       = ' '
*   DELETE_FLAG                      = ' '
   sender                           = sy-uname
*   CHECK_SEND_AUTHORITY             = ' '
*   CHECK_ALREADY_SENT               = ' '
*   GIVE_OBJECT_BACK                 =
*   ORIGINATOR                       = ' '
*   ORIGINATOR_TYPE                  = 'J'
*   LINK_FOLDER_ID                   = ' '
*   SEND_REQUEST_OID                 = ' '
*   IP_ENCRYPT                       = 'U'
*   IP_SIGN                          = 'U'
*   IP_REC_COUNT_ADD                 =
* IMPORTING
*   OBJECT_ID_NEW                    =
*   SENT_TO_ALL                      =
*   ALL_BINDING_DONE                 =
*   OFFICE_OBJECT_KEY                =
*   ORIGINATOR_ID                    =
*   E_SEND_REQUEST_OID               =
TABLES
   objcont                          = li_ali
*   OBJHEAD                          =
*   OBJPARA                          =
*   OBJPARB                          =
   receivers                        = li_receivers
*   PACKING_LIST                     =
*   ATT_CONT                         =
*   ATT_HEAD                         =
*   NOTE_TEXT                        =
*   LINK_LIST                        =
*   APPLICATION_OBJECT               =
 EXCEPTIONS
   active_user_not_exist            = 1
   communication_failure            = 2
   component_not_available          = 3
   folder_not_exist                 = 4
   folder_no_authorization          = 5
   forwarder_not_exist              = 6
   note_not_exist                   = 7
   object_not_exist                 = 8
   object_not_sent                  = 9
   object_no_authorization          = 10
   object_type_not_exist            = 11
   operation_no_authorization       = 12
   owner_not_exist                  = 13
   parameter_error                  = 14
   substitute_not_active            = 15
   substitute_not_defined           = 16
   system_failure                   = 17
   too_much_receivers               = 18
   user_not_exist                   = 19
   originator_not_exist             = 20
   x_error                          = 21
   OTHERS                           = 22.

IF sy-subrc IS INITIAL.
  MESSAGE 'Mail has been sent successfully' TYPE 'S'.
ELSE.
  MESSAGE 'Error occured while sending the mail' TYPE 'S'.
ENDIF.


For more information, go to the dedicated space: Web Dynpro ABAP Home.


Author: Ashim Chowdhury
Submitted: November 1, 2006
Related Links:

This article explains how to create your own application logging program in ABAP.
SAP provides standard functionality to write into as well as view the application log. This article will explain in detail how to create your own logging function module for application logging using standard SAP log facility. Two transaction code related to application logging are

  • SLG0 -> Used to maintain the log object
  • SLG1 -> Used to view the log

Configuration step

In this step create a log object.

  1. Open transaction SLG0. An information message about cross-client table will come.
  2. 2. Click the button "New Entries". Enter the name and description of your log object (say ZTESTLOG as object name and "Test Log" as object description) and save.

Development Step

The following standard function modules provided by SAP has been used to create the Z function module for logging.

  • BAL_GLB_MSG_DEFAULTS_SET
  • BAL_DB_SAVE
  • BAL_LOG_MSG_ADD

Here are the steps:

1. Go to transaction SE11. Create a z-structure Z_LOG_MESSAGE having the following fields

Component

Component Type

MSGTY

SYMSGTY

MSG_TEXT_1

SYMSGV

MSG_TEXT_2

SYMSGV

MSG_TEXT_3

SYMSGV

MSG_TEXT_4

SYMSGV

2. Crate a message class say ZMESSAGE in transaction SE91 and a message 999 with four placeholder ( & ) as the text.

3. Go to transaction SE37. Create a function group say ZLOG

4. After the function group is created, create a function module in that group. Let is name it ZIU_MESSAGE_LOGGING.

Import parameters:
a. I_LOG_OBJECT type BALOBJ_D -> Application log: Object name (Application code)
b. I_EXTNUMBER type String -> Application Log: External ID

Export parameters: None
Changing parameters: None
Tables parameters:
T_LOG_MESSAGE type Z_LOG_MESSAGE
Exceptions:
LOG_HEADER_INCONSISTENT
LOGGING_ERROR

Paste the code below as the source code

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
FUNCTION ZIU_MESSAGE_LOGGING.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" REFERENCE(I_LOG_OBJECT) TYPE BALOBJ_D
*" REFERENCE(I_EXTNUMBER) TYPE STRING
*" TABLES
*" T_LOG_MESSAGE STRUCTURE Z_LOG_MESSAGE
*" EXCEPTIONS
*" LOG_HEADER_INCONSISTENT
*" LOGGING_ERROR
*"----------------------------------------------------------------------

* Author :Ashim Chowdhury

* DESCRIPTION: This function module is used insert messages in the
* application log

  CONSTANTS: c_message TYPE syst-msgid VALUE 'ZMESSAGE',
  c_999 TYPE syst-msgno VALUE '999'.

  DATA:
  l_log_handle TYPE balloghndl,
  l_s_log TYPE bal_s_log,
  l_dummy TYPE string,
  l_ext_no TYPE bal_s_log-extnumber,
  l_s_mdef TYPE bal_s_mdef.

  IF t_log_message[] IS NOT INITIAL.

    l_s_log-object = i_log_object.
    l_ext_no = i_extnumber.
    l_s_log-extnumber = l_ext_no.

* Create the log with header data
    CALL FUNCTION 'BAL_LOG_CREATE'
      EXPORTING
        i_s_log                 = l_s_log
      IMPORTING
        e_log_handle            = l_log_handle
      EXCEPTIONS
        log_header_inconsistent = 1
        OTHERS                  = 2.

    IF sy-subrc <> 0.
      CASE sy-subrc.
        WHEN 1.
          RAISE log_header_inconsistent.
        WHEN OTHERS.
          RAISE logging_error.
      ENDCASE.
    ENDIF.

    l_s_mdef-log_handle = l_log_handle.

* Set the default value
    CALL FUNCTION 'BAL_GLB_MSG_DEFAULTS_SET'
      EXPORTING
        i_s_msg_defaults = l_s_mdef
      EXCEPTIONS
        OTHERS           = 0.

* Loop the message table and write the messages into the log
    LOOP AT t_log_message.

* Use the message type ZMESSAGE and msg no 999
* Issue the message in a dummy variable
      MESSAGE ID c_message TYPE t_log_message-msgty NUMBER c_999
      WITH t_log_message-msg_text_1 t_log_message-msg_text_2
      t_log_message-msg_text_3 t_log_message-msg_text_4
      INTO l_dummy.

* The parameters set by message statement will be used
* Add the message in the log
      PERFORM msg_add.
    ENDLOOP.


* save logs in the database
    CALL FUNCTION 'BAL_DB_SAVE'
      EXPORTING
        i_save_all       = 'X'
      EXCEPTIONS
        log_not_found    = 1
        save_not_allowed = 2
        numbering_error  = 3
        OTHERS           = 4.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.

  ENDIF.

ENDFUNCTION.
Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
*--------------------------------------------------------------------
* FORM MSG_ADD
*--------------------------------------------------------------------
* Add the message to the log
*-------------------------------------------------------------------*
FORM msg_add.
  DATA:
  l_s_msg TYPE bal_s_msg.

* define data of message for Application Log
  l_s_msg-msgty = sy-msgty.
  l_s_msg-msgid = sy-msgid.
  l_s_msg-msgno = sy-msgno.
  l_s_msg-msgv1 = sy-msgv1.
  l_s_msg-msgv2 = sy-msgv2.
  l_s_msg-msgv3 = sy-msgv3.
  l_s_msg-msgv4 = sy-msgv4.

* add this message to log file
* (I_LOG_HANDLE is not specified, we want to add to the default log.
* If it does not exist we do not care =>EXCEPTIONS log_not_found = 0)
  CALL FUNCTION 'BAL_LOG_MSG_ADD'
  EXPORTING
* I_LOG_HANDLE =
  i_s_msg = l_s_msg
  EXCEPTIONS
  log_not_found = 0
  OTHERS = 1.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.

Using the function module:
In your ABAP program write the following code and use this function module ZIU_MESSAGE_LOGGING for logging.

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
* Data declaration->
* Internal table for message logging
DATA: it_log_message TYPE STANDARD TABLE OF z_log_message,
wa_log_message TYPE z_log_message,
l_ext_number TYPE string.

Constants:
c_obj_zxiproxy TYPE balobj_d VALUE 'ZTESTLOG'.

* Now populate the internal table with the log messages as shown below. wa_log_message-
* msgty is the type of the message.
* E -> Error, W -> Warning, S -> Success

* Logging code for insert message into log
CLEAR wa_log_message.
wa_log_message-msgty = 'E'. " Can use W or S
wa_log_message-msg_text_1 = < Message text 1>.
wa_log_message-msg_text_2 = < Message text 2>
wa_log_message-msg_text_3 = < Message text 3>
wa_log_message-msg_text_4 = < Message text 4>

* Append the message into the internal table
APPEND wa_log_message TO it_log_message.

At the end transfer the log message to the system log by calling function module ZIU_MESSAGE_LOGGING. L_EXT_NUMBER will bt any string of your choice.

* Function module ZIU_MESSAGE_LOGGING will do the logging
* i_log_object is the object type (to be configrd using txn SLG0

CALL FUNCTION 'ZIU_MESSAGE_LOGGING'
EXPORTING
i_log_object = c_obj_zxiproxy
i_extnumber = l_ext_number
TABLES
t_log_message = it_log_message
EXCEPTIONS
log_header_inconsistent = 1
logging_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDIF.

The logged messages can be viewed in transaction SLG1. For filtering the messages use the Object type.



Consuming Web Services with ABAP - WSDL

To get the process started, we turn to SE80 TCODE go to workbench & edit object.
From the Enterprise Services Tab, we are going to select Client Proxy and then hit new create button.

Next up we have to choose where our WSDL file is going to come from.
But in this case we are going to connect directly to the WSDL definition to a file on our local machine.

Give the path of WSDL file .

Now we are asked what Package we want to place the generated object in as well as what prefix we want to use. I am going to make the object Local Private by putting in my $TMP package. To follow SAP naming standards, as well as my company's standards, I will get the object a prefix of ZES_

Activate the Client Proxy.
You can see

  1. ABAP class
  2. Structures and table types to represent all the importing and exporting data.ABAP CLASS

Structures and table types to represent all the importing and exporting data.

Now we need to configure a Logical Port for it.
We can do this in transaction LPCONFIG.
We can configure more than one Logical Port and specify the one we want at runtime. However for this solution we will just configure one port and make it the default.

Inside the definition of the Logical Port we can adjust settings for the Client Proxy.
 settings that were imported from the WSDL definition.

We can then return to SE80 in Enterprise service tag  and perform a test on the WebService by hitting F8. We then get a dialog that allows us to set parameters for our test.

you get a success message like the following:

Now coding In SE38

Error rendering macro 'code': Invalid value specified for parameter 'com.atlassian.confluence.ext.code.render.InvalidValueException'
PARAMETER: p_isbn(100) TYPE c OBLIGATORY.
DATA:
* Reference variables for proxy and exception class
  lo_clientproxy     TYPE REF TO zes_co_looky_book_service_soap,
  lo_sys_exception   TYPE REF TO cx_ai_system_fault,
* Structures to set and get message content
   ls_request         TYPE zes_get_info_soap_in,
   ls_response        TYPE zes_get_info_soap_out.
**Set the input parameter
ls_request-value = 'INPUT TEST'.
**Create the Proxy and Clall it.
CREATE OBJECT lo_clientproxy.
TRY.
    CALL METHOD lo_clientproxy->get_info
      EXPORTING
        input  = ls_request
      IMPORTING
        output = ls_response.
  CATCH cx_ai_system_fault INTO lo_sys_exception.
*   Error handling
ENDTRY.
COMMIT WORK.
**Write Out the Basic Information
WRITE: / ls_response-value.