• BAPI To Update Sales Order Reason For Rejection

    Please find below a sample program using the BAPI \’BAPI_SALESORDER_CHANGE\’ to demonstrate how to update the reason for rejection (VBAP-ABGRU) for all items in a sales order.

     

    REPORT ztestbapiso1.
    *&--------------------------------------------------------------------&*
    *& Program Description:                                               &*
    *& -----------------------                                            &*
    *& This demo program will update the reason for rejection for all     &*
    *& items in a selected sales order.                                   &*
    *&                                                                    &*
    *& The program demonstrate the use of the \'BAPI_SALESORDER_CHANGE\'.   &*
    *&                                                                    &*
    *& Author:  ABAPCOOKBOOK                                              &*
    *& Website: www.abapcookbook.com                                      &*
    ************************************************************************
    
    ************************************************************************
    * DATA DECLARATIONS                                                    *
    ************************************************************************
    *Tables:
    TABLES:
      vbap.
    
    *Internal tables:
    DATA:
      gt_vbap           TYPE STANDARD TABLE OF vbap,
      gt_item_in        TYPE STANDARD TABLE OF bapisditm,
      gt_item_inx       TYPE STANDARD TABLE OF bapisditmx,
      gt_return         TYPE STANDARD TABLE OF bapiret2.
    
    *Field Symbols:
    FIELD-SYMBOLS:
      <fs_vbap>         TYPE vbap.
    
    *Structures:
    DATA:
      gst_item_hedx     TYPE bapisdh1x,
      gst_item_in       TYPE bapisditm,
      gst_item_inx      TYPE bapisditmx.
    
    *Variables:
    DATA:
      gv_msg            TYPE string.
    
    *Constants:
    CONSTANTS:
      gc_error          TYPE string VALUE \': An error occured, no change done to the sales order.\',
      gc_success        TYPE string VALUE \': Sales order changed successfully.\'.
    
    ************************************************************************
    * SELECTION SCREEN                                                     *
    ************************************************************************
    SELECT-OPTIONS:
    *  Sales Order Number.
       s_vbeln FOR vbap-vbeln OBLIGATORY.
    
    PARAMETERS:
    *   Reason for Rejection.
        p_abgru TYPE vbap-abgru OBLIGATORY.
    
    
    ************************************************************************
    * CODE LOGIC                                                           *
    ************************************************************************
    
    *Select sales order data from table VBAP.
    SELECT *
      FROM vbap
      INTO TABLE gt_vbap
      WHERE vbeln IN s_vbeln.
    
    IF sy-subrc EQ 0.
    
      LOOP AT gt_vbap ASSIGNING <fs_vbap>.
    
    *   (Order Header Level)
    *   Setting the update flag at order header level to update mode.
        gst_item_hedx-updateflag = \'U\'.
    
    *   (Order Item Level)
    *   Setting of the material number(MATNR) at order item level.
        gst_item_in-material = <fs_vbap>-matnr.
    
    *   Setting of the item number(POSNR) at order item level.
        gst_item_in-itm_number  = <fs_vbap>-posnr.
        gst_item_inx-itm_number = <fs_vbap>-posnr.
    
    *   Setting of the reason for rejection(ABGRU) at order item level.
        gst_item_in-reason_rej  = p_abgru.
        gst_item_inx-reason_rej = \'X\'.
    
    *   Setting the update flag at order item level to update mode.
        gst_item_inx-updateflag = \'U\'.
    
    *   BAPI items level tables:
        APPEND:
          gst_item_in  TO gt_item_in,
          gst_item_inx TO gt_item_inx.
    
    *   Calling BAPI to update reason for rejection in the selected sales order.
        CALL FUNCTION \'BAPI_SALESORDER_CHANGE\'
          EXPORTING
            salesdocument    = <fs_vbap>-vbeln
            order_header_inx = gst_item_hedx
          TABLES
            return           = gt_return
            order_item_in    = gt_item_in
            order_item_inx   = gt_item_inx.
    
    *   Preparing the result message.
        CONCATENATE <fs_vbap>-vbeln   \" Sales Order Number
                    <fs_vbap>-posnr   \" Item Number
               INTO gv_msg            \" Message
       SEPARATED BY space.            \" Space
    
    *   Check if at least one error was raised by the BAPI. Loop inside
    *   loop is not advise, however, the return table will contains small
    *   amount of entries. We can use that for our demo.
        LOOP AT gt_return TRANSPORTING NO FIELDS
        WHERE type EQ \'E\'
           OR type EQ \'A\'.
    
    *     Exit and rollback changes.
          EXIT.
    
        ENDLOOP.
    
    *   If error found, rollback database changes.
        IF sy-subrc EQ 0.
    
    *     Rollback changes.
          CALL FUNCTION \'BAPI_TRANSACTION_ROLLBACK\'.
    
    *     Preparing error message.
          CONCATENATE gv_msg        \"Sales Order and Item Number
                      gc_error      \"Error Message
                 INTO gv_msg
         SEPARATED BY space.
    
    *     Output message.
          WRITE / gv_msg.
    
    *   Else, no error found, commit database changes.
        ELSE.
    
    *     Commit changes.
          CALL FUNCTION \'BAPI_TRANSACTION_COMMIT\'
            EXPORTING
              wait = abap_true.
    
    *     Preparing success message.
          CONCATENATE gv_msg        \"Sales Order and Item Number
                      gc_success    \"Success Message
                 INTO gv_msg
         SEPARATED BY space.
    
    *     Output message.
          WRITE / gv_msg.
    
        ENDIF.
    
    *   Write a line after each sales order.
        AT END OF vbeln.
          WRITE: sy-uline.
        ENDAT.
    
    *   Clearing of variables and structures:
        CLEAR:
    *     Variables:
          gv_msg,
    *     Structures:
          gst_item_hedx,
          gst_item_in,
          gst_item_inx.
    
    *   Refreshing internal tables:
        REFRESH:
          gt_item_in,
          gt_item_inx,
          gt_return.
    
      ENDLOOP.
    
    ENDIF.

    In case of error, please check the BAPI return messages available in the internal table \’GT_RETURN\’.

  • Get Date & Time Based on Timezone in ABAP

    Please find below a sample program which allows to generate the current date and time in ABAP.

    The date time can also be returned based on the timezone set.

    REPORT ZTIMEDATE.
    
    *Data Declarations.
    *Variables:
    DATA:
      lv_currenttime    TYPE brf_ref_time_stamp.
    
    *Constants:
    CONSTANTS:
      lc_tzone          TYPE sy-zonlo     VALUE space.
    
    
    *Creation Date Column.
    *Get the current system time.
    GET TIME.
    
    *Convert the time to the correct format
    *before adding it to the traceability table.
    *Please note that the format of the time will
    *be \'YYYYMMDDhhmmss\'.
    *For example: 20170101052501 which equals to 2017-01-01 05:25:01.
    CONVERT
      DATE sy-datum                       \" Date
      TIME sy-uzeit                       \" Time
      INTO TIME STAMP lv_currenttime      \" Creation Date Time
      TIME ZONE lc_tzone.                 \" Timezone
    
    *Write Time.
    WRITE lv_currenttime.

    Please note that the data element \’BRF_REF_TIME_STAMP\’ contains the domain \’BRF_TIMESTAMP\’ which has a conversion routine which also returns the date/time in the format \’DD-MM-YYYY HH:MM:SS\’.

  • Sales Order : Error Message Item X does not exist

    If ever you got an error message like \’Item 000020 does not exist\’ from the function module ‘BAPI_SALESORDER_CHANGE’ (BAPI used to modify sales order).

     

    Problem:

    This means that there are inconsistent data between tables VBAP and VBKD. That is,some item number are present VBKD and not in table VBAP.

     

    How is table VBKD updated:

    • If we have different partner details (like ship-to address) at header and item level for a particular item, an entry with that item number will be created in table VBKD
    • In VBKD, the line with item number ‘000000’ is created when a sales order is created. If only the line with item number ‘000000’ is available, this means that partner details (like ship-to address) for all items (item level) are equals to partner details at header level.

     

    For Example:

    If we create a sales order with 5 items, where all items have same partner details at both header and item level

    > A line will be created in table VBKD with item number ‘000000’

     

    If on the same sales order, we modify the partner details (like different ship-to address at header and item level) for item ‘000030\’

    > A line will be created in table VBKD with item number ‘000030’

     

    If on the same sales order, we delete the item ‘000030\’

    > The line with item number ‘000030’ will be deleted in table VBKD

     

    Possible Solution:

    Try to manually delete the item number(s) mentioned in the error message from table VBKD.  This not recommended solution, try it at your own risks.

    Please refer to the following post on how to enable options which allow to modify entries from standard SAP table.

  • Function Module To Add Days To A Date

    Function module \’BKK_ADD_WORKINGDAY\’ is a nice FM that allows to add days to a date. The function module can also consider non-working days (like Saturday, Sunday and public holidays) based on the calendar maintained in the the system.

    Below is a sample code of how to use the function module \’BKK_ADD_WORKINGDAY\’.

    REPORT zadddaystodate.
    
    *Data Declarations:
    *Constants:
    CONSTANTS:
      lc_number_of_days_to_add TYPE i            VALUE 1,
      lc_holiday_cal_id        TYPE scal-hcalid  VALUE \'FR\'.
    
    *Variables:
    DATA:
      lv_date       TYPE sy-datum,
      lv_added_date TYPE sy-datum,
      lv_subrc      TYPE sy-subrc.
    
    *Input Date.
    lv_date = \'20170301\'.
    
    CALL FUNCTION \'BKK_ADD_WORKINGDAY\'
      EXPORTING
        i_date   = lv_date
        i_days   = lc_number_of_days_to_add
    *   The parameter \'I_CALENDAR1\' allows the FM to consider
    *   non-working days (like Saturday, Sunday and public holidays) during
    *   the calculation of the new added date.
    *   i_calendar1 = lc_holiday_cal_id
      IMPORTING
        e_date   = lv_added_date
        e_return = lv_subrc.
    
    IF lv_subrc EQ 0.
    
      WRITE lv_added_date.
    
    ENDIF.

     

  • Top 15 ABAP Coding Practices

    The following best ABAP coding practices will help you make your ABAP program more performance and robust:

    1. Make sure that the code has explicit comments about the functionality of the implemented code logic.
    2. Unused variables or constants must be removed from the program.
    3. Limit hard coding elements.
    4. Declare elements (variables, internal tables, etc…) locally when used only in sub routines and pass globally declared elements to sub routines via parameters.
    5. Reduce code redundancy (avoid duplication of codes) by modularizing code whenever possible.
    6. Make sure that variables, work areas or internal tables have been cleared properly when required (especially inside loop).
    7. Implement appropriate checks in loop to prevent infinite loop.
    8. Before the FOR ALL ENTRIES statement, check if the table is not empty first, SORT the table and DELETE ADJACENT DUPLICATES from the table using the same set of keys that will be used on the FOR ALL ENTRIES statement. Please note: Empty tables in FOR ALL ENTRIES will retrieved all entries from database tables and can cause performance issue.
    9. Make sure all primary keys have been selected in FOR ALL ENTRIES select statement else it will retrieve only none duplicates lines of the selected fields.
    10. Make sure \’FOR ALL ENTRIES\’ is not done on cluster tables.
    11. No database statement (like SELECT, INSERT, UPDATE, DELETE, etc..) inside loop.
    12. Avoid multiple select statements on the same database table in the same program.
    13. The \’SORT INT_TABL BY <FIELDS X Y X>\’ statement must be used instead of just SORT INT_TABL (this will sort all fields in the internal table and this affect the performance). Also avoid sorting inside loop.
    14. Make sure BINARY SEARCH statement is used in READ statement and make sure table is sorted correctly before using BINARY search.
    15. Use \’SELECT UP TO 1 ROWS\’ when you don\’t have all primary keys and \’SELECT SINGLE\’ when you have all primary keys.

    Happy coding.

  • Solve SAP Logon History Problem

    Sometimes the history (in transaction SE38, SE11, etc…) does not work properly.

    To solve this problem:

    Step 1: Delete all files in the following path \”C:\\Users\\YOUR_COMPUTER_USERNAME\\AppData\\Roaming\\SAP\\SAP GUI\\History\”.

    Step 2: Restart SAP Logon once all files have been deleted.

    This will force SAP Logon to re generate the appropriate files to maintain the history.

    Hope this helps. 😉

  • Output Types Debugging

    Le\’ts say you a scenario where a particular output type (output type created from VA02) generates an iDoc and you want to debug the generation of the iDoc.

     

    Step 1: In VA02 (or any other transaction), after generating the output type (from menu Extras > Output > Header > Edit), click on the button \’Further data\’.

    \"further-data-output-type\"

    Step 2: Change the dispatch time to \’Send with periodically scheduled job\’. This will prevent the output type to be generated automatically.

    \"dispatch-time-output-type\"

    Step 3: Put appropriate break point in the output type program to debug and execute program \’RSNAST00\’ with the output type in question.

    \"rsnast00-output-type\"

    The debugger shall be triggered on execution of the above program.

  • How To Enable or Disable Autocomplete in SAP 7.40

    To change the auto complete options in SAP 7.40, please follow the steps below:

     

    Step 1: Go to the \’SAP Logon\’ options.

    \"sap-logon-options\"

     

    Step 2: On the menu \’Interaction Design\’, select \’Visualization 2\’ and change the option \’Enhanced Search\’ (highlighted in green on the screenshot below):

    \"sap-visualization-settings\"

  • Read Data From ABAP Stack

    When implementing an enhancement, sometimes we need to read a field defined in the main program but which is not available in the enhancement point.

    There is a technique which allows us the read the field if it is available in the ABAP stack.

    Like for example (please refer to below screenshot), the field ‘TVAK-FPART’ is available in the main program ‘SAPMV45A’, however if the field is not available in the subroutine ‘VBAK_FUELLEN’ (program SAPFV45K) we can still access the field from the ABAP stack using the field symbol technique.

    \"ABAP

     

    Please find below a sample source code how to read data from the ABAP stack:

    *Data Declarations:
    *Constants.
    CONSTANTS:
      lc_stack_loc(20)    TYPE c    VALUE \'(SAPMV45A)TVAK-FPART\'.
    
    *Field Symbols.
    FIELD-SYMBOLS:
      <fs_stackvalue>                TYPE ANY.
    
    *If we have been able to read the required data
    *from ABAP stack, proceed.
    ASSIGN (lc_stack_loc) TO <fs_stackvalue>.
    
    IF sy-subrc EQ 0
    AND <fs_stackvalue> IS NOT INITIAL.
    
    * Write the value read from ABAP stack.
      WRITE <fs_stackvalue>.
    
    ENDIF.