Pages

Wednesday, August 13, 2014

Easy way of passing values from custom program to Exits - without IMPORT/EXPORT or memory id

Often its required to transfer values from custom program to EXITS while calling any Object creation BAPi.
Using IMPORT/EXPORT to memory or INDX is not very reliable especially when the custom programs are ran in background mode.

One of the easy way is to :
- use SAVE_TEXT to update the value to the Biz object in the custom program
_ call the creation BAPI for Deivery, order, billing etc.
- during the creation process, find an exit where the VALUEs can be impported using READ_TEXT.
- after creation process , once control comes back to the custom program, delete the value from the object using DELETE_TEXT.

custom program

DATAlt_range TYPE TABLE OF zrange.
FIELD-SYMBOLS TYPE zrange,
                LIKE xvbpa.

DATAlv_name TYPE tdobname,
      lt_lines TYPE STANDARD TABLE OF tline,
      ls_lines LIKE LINE OF lt_lines,
      ls_lips  TYPE lips,
      lv_ebelp TYPE ebelp.

CONSTANTSco_savelang  TYPE thead-tdspras VALUE 'E'.

* check for availability of PO doc
IF ekko-ebeln IS INITIAL.
  RETURN.
ENDIF.

* Read ZRANGE for triggering of below logic
SELECT FROM zrange INTO TABLE lt_range
  WHERE application  'HUBSTOSA' AND
        program_name 'MV50AFZ1' AND
        identifier  ekko-ekorg.

IF sy-subrc EQ 0.
  SORT lt_range BY fieldname.
  "Check doc type
  READ TABLE lt_range ASSIGNING  WITH KEY fieldname 'LFART' BINARY SEARCH.
  IF sy-subrc NE AND  IS NOT ASSIGNED.
    RETURN.
  ELSEIF  IS ASSIGNED.
    IF -low NE likp-lfart.
      RETURN.
    ENDIF.
  ENDIF.
  READ TABLE lt_range ASSIGNING  WITH KEY fieldname 'BSART' BINARY SEARCH.
  IF sy-subrc NE AND  IS NOT ASSIGNED.
    RETURN.
  ELSEIF  IS ASSIGNED.
    IF -low NE ekko-bsart.
      RETURN.
    ENDIF.
  ENDIF.
ELSE.
  RETURN.
ENDIF.


CHECK sy-tcode EQ 'ZSD_SCHEDULE_HUB' OR sy-batch EQ 'X'.

READ TABLE xvbpa[] ASSIGNING  WITH KEY parvw 'ZB'."during change this Partner will be there
IF sy-subrc EQ 0.
  RETURN."it means this code has been called during DN creation time. We need thi code during DN change
ENDIF.

********* Read Text *********

SORT xlips[] BY vgpos."text ID will always be there for the 1st item of the delivery as per Report logic
READ TABLE xlips[] INTO ls_lips INDEX 1.
MOVE ls_lips-vgpos+1(5TO lv_ebelp.

IF sy-subrc EQ 0.

  MOVE ls_lips-vgbel TO lv_name.

  CALL FUNCTION 'READ_TEXT'
    EXPORTING
*     client                  = sy-mandt
      id                      'L04'
      language                co_savelang
      name                    lv_name
      object                  'EKPO'
    TABLES
      lines                   lt_lines
    EXCEPTIONS
      id                      1
      language                2
      name                    3
      not_found               4
      object                  5
      reference_check         6
      wrong_access_to_archive 7
      OTHERS                  8.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  READ TABLE lt_lines INTO ls_lines INDEX 1.
  IF sy-subrc EQ 0.
    "Loop has been used here, so that in case of data issues, when multiple
    "DNs are created, all DN should have the HUB Partner number
    LOOP AT  xvbpa[] ASSIGNING  WHERE parvw 'WE'.
      MOVE ls_lines-tdline TO -kunnr.
      SELECT adrnr UP TO ROWS INTO -adrnr
        FROM kna1 WHERE kunnr -kunnr.
      ENDSELECT.
    ENDLOOP.
  ENDIF.

ENDIF.


------- call BAPI for Outboud delivery creation
Include          MV50AFZ1
FORM USEREXIT_SAVE_DOCUMENT_PREPARE.

SORT xlips[] BY vgpos."text ID will always be there for the 1st item of the delivery as per Report logic
READ TABLE xlips[] INTO ls_lips INDEX 1.
MOVE ls_lips-vgpos+1(5TO lv_ebelp.

IF sy-subrc EQ 0.

  MOVE ls_lips-vgbel TO lv_name.

  CALL FUNCTION 'READ_TEXT'
    EXPORTING
*     client                  = sy-mandt
      id                      'L04'
      language                co_savelang
      name                    lv_name
      object                  'EKPO'
    TABLES
      lines                   lt_lines
    EXCEPTIONS
      id                      1
      language                2
      name                    3
      not_found               4
      object                  5
      reference_check         6
      wrong_access_to_archive 7
      OTHERS                  8.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  READ TABLE lt_lines INTO ls_lines INDEX 1.
  IF sy-subrc EQ 0.
    "Loop has been used here, so that in case of data issues, when multiple
    "DNs are created, all DN should have the HUB Partner number
    LOOP AT  xvbpa[] ASSIGNING  WHERE parvw 'WE'.
      MOVE ls_lines-tdline TO -kunnr.
      SELECT adrnr UP TO ROWS INTO -adrnr
        FROM kna1 WHERE kunnr -kunnr.
      ENDSELECT.
    ENDLOOP.
  ENDIF.


---------------------- return to custom program


    ELSE.
*****
      CALL FUNCTION 'DELETE_TEXT'
        EXPORTING
          client          sy-mandt
          id              ls_thead-tdid
          language        co_savelang
          name            ls_thead-tdname
          object          ls_thead-tdobject
          savemode_direct 'X'
        EXCEPTIONS
          not_found       1
          OTHERS          2.
      IF sy-subrc <> 0.
* Implement suitable error handling here
      ENDIF.

    ENDIF.

Changing PARTNER details before Outbound delivery commit to system

By this point OB is already decided for splitting and all validation has happened.
We want to skip the validations and change the Partner numbers.

REMEMEBER: Mandatory partners determined by the TPAER table cannot be changed. Actaully it can be changed but system hangs while ceration of the Delv since it tries to delete the partner from VLPMA table.

Here READ_TEXT is reading the partner numbers passed from the custom Report to generate OB:


DATAlt_range TYPE TABLE OF zrange.
FIELD-SYMBOLS TYPE zrange,
                LIKE xvbpa.

DATAlv_name TYPE tdobname,
      lt_lines TYPE STANDARD TABLE OF tline,
      ls_lines LIKE LINE OF lt_lines,
      ls_lips  TYPE lips,
      lv_ebelp TYPE ebelp.

CONSTANTSco_savelang  TYPE thead-tdspras VALUE 'E'.

* check for availability of PO doc
IF ekko-ebeln IS INITIAL.
  RETURN.
ENDIF.

* Read ZRANGE for triggering of below logic
SELECT FROM zrange INTO TABLE lt_range
  WHERE application  'HUBSTOSA' AND
        program_name 'MV50AFZ1' AND
        identifier  ekko-ekorg.

IF sy-subrc EQ 0.
  SORT lt_range BY fieldname.
  "Check doc type
  READ TABLE lt_range ASSIGNING  WITH KEY fieldname 'LFART' BINARY SEARCH.
  IF sy-subrc NE AND  IS NOT ASSIGNED.
    RETURN.
  ELSEIF  IS ASSIGNED.
    IF -low NE likp-lfart.
      RETURN.
    ENDIF.
  ENDIF.
  READ TABLE lt_range ASSIGNING  WITH KEY fieldname 'BSART' BINARY SEARCH.
  IF sy-subrc NE AND  IS NOT ASSIGNED.
    RETURN.
  ELSEIF  IS ASSIGNED.
    IF -low NE ekko-bsart.
      RETURN.
    ENDIF.
  ENDIF.
ELSE.
  RETURN.
ENDIF.


CHECK sy-tcode EQ 'ZSD_SCHEDULE_HUB' OR sy-batch EQ 'X'.

READ TABLE xvbpa[] ASSIGNING  WITH KEY parvw 'ZB'."during change this Partner will be there
IF sy-subrc EQ 0.
  RETURN."it means this code has been called during DN creation time. We need thi code during DN change
ENDIF.

********* Read Text *********

SORT xlips[] BY vgpos."text ID will always be there for the 1st item of the delivery as per Report logic
READ TABLE xlips[] INTO ls_lips INDEX 1.
MOVE ls_lips-vgpos+1(5TO lv_ebelp.

IF sy-subrc EQ 0.

  MOVE ls_lips-vgbel TO lv_name.

  CALL FUNCTION 'READ_TEXT'
    EXPORTING
*     client                  = sy-mandt
      id                      'L04'
      language                co_savelang
      name                    lv_name
      object                  'EKPO'
    TABLES
      lines                   lt_lines
    EXCEPTIONS
      id                      1
      language                2
      name                    3
      not_found               4
      object                  5
      reference_check         6
      wrong_access_to_archive 7
      OTHERS                  8.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  READ TABLE lt_lines INTO ls_lines INDEX 1.
  IF sy-subrc EQ 0.
    "Loop has been used here, so that in case of data issues, when multiple
    "DNs are created, all DN should have the HUB Partner number
    LOOP AT  xvbpa[] ASSIGNING  WHERE parvw 'WE'.
      MOVE ls_lines-tdline TO -kunnr.
      SELECT adrnr UP TO ROWS INTO -adrnr
        FROM kna1 WHERE kunnr -kunnr.
      ENDSELECT.
    ENDLOOP.
  ENDIF.

ENDIF.

Changing Outbound delivery data before creation

BADI and User exit for OB before even Delivery data checks starts.
- before delivery split criteria is determined.
- before sending data to GN_DELIVERY_CREATE
- changing data for OB created from STO - BAPI_OUTB_DELIVERY_CREATE_STO

Basic idea is to target the Delivery creation structure - it_komdlgn

inside GN_DELIVERY_CREATE at the beginning it self you have a BADI. But this BADI has all IMPORTING parameters for the Method - IMPORT. SO its not directly possible to change the data.
Use STACK table assignment using Field-symbols to change the data.

BADI - shp_badi_gn_delivery_create
Implementation:
IF_EX_SHP_GN_DELIVERY_CREATE~IMPORT

Requirement - to change the LFDAT field which is read from EKET table and Spitting of MATNR is done based on that.
METHOD if_ex_shp_gn_delivery_create~import.

  DATAlt_range TYPE TABLE OF zrange.
  FIELD-SYMBOLS TYPE zrange,
                  TYPE komdlgn,
                  TYPE ANY TABLE.

  DATAlv_name TYPE tdobname,
        lt_lines TYPE STANDARD TABLE OF tline,
        ls_lines LIKE LINE OF lt_lines,
        ls_lips  TYPE lips,
        lv_ebeln TYPE ebeln,
        lv_ekorg TYPE ekorg,
        lv_bsart TYPE bsart,
        lv_prog TYPE string VALUE '(SAPLV50S)XKOMDLGN[]'.

  CONSTANTSco_savelang  TYPE thead-tdspras VALUE 'E'.

*** Dynamic accessing of variables in Stack programs
  ASSIGN (lv_progTO .
  CHECK  IS ASSIGNED.


* Read table available in BADI to get SA num
  READ TABLE xkomdlgn ASSIGNING  INDEX 1.
  CHECK sy-subrc EQ 0.
  MOVE -vgbel TO lv_name."for READ_TEXT
  MOVE -vgbel TO lv_ebeln."for SELECT query

* Get SA details for verification with ZRANGE table
  SELECT ekorg bsart UP TO ROWS INTO (lv_ekorg,lv_bsart)
    FROM ekko
    WHERE ebeln EQ lv_ebeln.
  ENDSELECT.

* Read ZRANGE for triggering of below logic
  SELECT FROM zrange INTO TABLE lt_range
    WHERE application  'HUBSTOSA' AND
          program_name 'MV50AFZ1' AND
          identifier  lv_ekorg.


  IF sy-subrc EQ 0.
    SORT lt_range BY fieldname.
    READ TABLE lt_range ASSIGNING  WITH KEY fieldname 'BSART' BINARY SEARCH.
    IF sy-subrc NE AND  IS NOT ASSIGNED.
      RETURN.
    ELSEIF  IS ASSIGNED.
      IF -low NE lv_bsart.
        RETURN.
      ENDIF.
    ENDIF.
  ELSE.
    RETURN.
  ENDIF.
*

  CHECK sy-tcode EQ 'ZSD_SCHEDULE_HUB' OR sy-batch EQ 'X'.

*
  CALL FUNCTION 'READ_TEXT'
    EXPORTING
*     client                  = sy-mandt
      id                      'L04'
      language                co_savelang
      name                    lv_name
      object                  'EKPO'
    TABLES
      lines                   lt_lines
    EXCEPTIONS
      id                      1
      language                2
      name                    3
      not_found               4
      object                  5
      reference_check         6
      wrong_access_to_archive 7
      OTHERS                  8.
  IF sy-subrc <> 0.
    RETURN.
  ENDIF.
  READ TABLE lt_lines INTO ls_lines INDEX 2.

  LOOP AT  ASSIGNING .
    MOVE ls_lines-tdline TO -lfdat.
  ENDLOOP.

ENDMETHOD.