ABAP Blog Posts
cancel
Showing results for 
Search instead for 
Did you mean: 

This blog post is a little call to the community to share code snippets of "copy programs" for BAPI business objects. I explain the concept, how to create such a program, and propose one example.

It may be a little bit difficult to develop a program from scratch for creating a Business Object (*) by calling a create BAPI function module:

  1. Pass the right values to make the BAPI succeed (consistent values, fields to be entered either in internal or in external format, etc.)
  2. Use of additional function modules (for long texts, to cleanup memory or special commit, BAPI_TRANSACTION_COMMIT and ROLLBACK)
  3. Special technical parameters for some BAPI
  4. Custom fields via the EXTENSIONIN parameter

That would be much easier if there was a copy program provided to create a business object via BAPI from an existing business object:

  1. Ask the functional team or end user to create manually the expected business object(s)
  2. Run the copy program to copy the business object
  3. Debug the copy program to see the values passed to the create BAPI
  4. Now it should be easier to create the custom program as per the requirements

Again, the goal of the custom program is not to copy a template business object in the production system, but to create a business object from scratch according to some client requirements; the goal of the copy program is to help developing this custom program.

The easiest way to create a copy program is to call the read BAPI to get all the business object details and pass them to the create BAPI, because the parameters are usually very similar. When they differ, usually only a small conversion logic is needed.

Here's one example of what could be such a copy program, applied to the business object BUS2172 (projects in the SAP Portfolio and Project Management module - PPM). The BAPI used by this copy program are BAPI_BUS2172_GET_DETAIL and BAPI_BUS2172_CREATE. For information, this business object is mainly stored in the table DPR_PROJECT; it can be created and maintained via the Web Dynpro application INM_WORKCENTER_APP (with the URL query ?iv_appl_type=DPO&iv_context=WS&iv_obj_type_r=DPO&iv_portal_role=DPR_PROJECT&sap-client=...)

To fill the parameters of the create BAPI, the easiest way is to call the "read" BAPI (BAPI_BUS2172_GET_DETAIL) because the parameters are usually very similar.

The read and create BAPI parameters may differ, so the parameters must be converted. For BUS2172, they differ on these points:

  • The read BAPI may return the project name in different languages in an internal table while the create BAPI has only one name in the language defined in the component PROJECT_DESCRIPTION_NAME of the parameter IS_PROJECT_DEFINITION
  • Same thing for the project description. Also, the read BAPI may return the description as a table of text lines while the create BAPI has 4 binary components. It's explained below how to convert it.
  • The read BAPI returns the dates in external format while the create BAPI expects the dates in internal format

BAPI_BUS2172_CREATE has several specificities (which are documented in the function module documentation):

  • Commit is to be done via BAPI_CPROJECTS_COMMIT_WORK and rollback via BAPI_CPROJECTS_ROLLBACK_WORK
  • The technical parameter IS_PROJECT_DEFINITION_UPD is a structure with components to be set with "X" values for all the fields to initialize by the values in the parameter IS_PROJECT_DEFINITION.
  • The components PROJECT_DESCRIPTION_PARTX (X = 1 to 4) components of the parameter IS_PROJECT_DEFINITION are binary fields with a total length of 1020 bytes which must be initialized from a text via the method CL_DPR_BAPI_SERVICES=>CONVERT_STRING_TO_RAWPARTS (UTF-8 with the last bytes to be spaces).

This copy program should work in all projects. Don't add anything custom when you share it.

Now we can run this copy program.

After making sure the copy program has created the business object, the parameters passed to BAPI_BUS2172_CREATE can be carefully analyzed by debug:

Sandra_Rossi_0-1767196979039.png

Now, the custom program may be created (manually) with the required logic to reproduce the same parameter values (at least for the first test run).

That would be great if people can share such copy programs because they are easy to create, they are useful and they don't contain any confidential information.

Thanks a lot for reading me!

Sandra

Here's the code of the copy program for BUS2172 (note that it's currently limited because it doesn't copy the project elements like the phases, tasks, checklist headers and items, which correspond respectively to the business object types BUS2173, BUS2175, BUS2176 and BUS2174). It works in an ABAP 7.40 system:

REPORT z_bus2172_copy_program.

PARAMETERS projguid TYPE bapi_ts_guid-project_definition_guid.
PARAMETERS projnum TYPE dpr_project-project_id.

CLASS lcl_app DEFINITION DEFERRED.

DATA go_app TYPE REF TO lcl_app.

LOAD-OF-PROGRAM.
  CALL METHOD lcl_app=>('CREATE')
    RECEIVING
      result = go_app.

START-OF-SELECTION.
  CALL METHOD go_app->('START_OF_SELECTION').

CLASS lcl_app DEFINITION FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    CLASS-METHODS class_constructor.

    CLASS-METHODS create
      RETURNING VALUE(result) TYPE REF TO lcl_app.

    METHODS start_of_selection.

  PRIVATE SECTION.
    CLASS-DATA initial_external_date TYPE bapi_date.

    CLASS-METHODS conv_date_ext_to_int
      IMPORTING iv_date_format_externe_courant TYPE csequence
      RETURNING VALUE(result)                  TYPE d.
ENDCLASS.


CLASS lcl_app IMPLEMENTATION.
  METHOD class_constructor.
    DATA(d) = VALUE d( ).
    WRITE d TO initial_external_date.
  ENDMETHOD.

  METHOD conv_date_ext_to_int.
    IF iv_date_format_externe_courant = initial_external_date.
      result = VALUE #( ).
    ELSE.
      cl_abap_datfm=>conv_date_ext_to_int( EXPORTING im_datext = iv_date_format_externe_courant
                                           IMPORTING ex_datint = result ).
    ENDIF.
  ENDMETHOD.

  METHOD create.
    result = NEW lcl_app( ).
  ENDMETHOD.

  METHOD start_of_selection.
    TYPES tt_description_lines TYPE STANDARD TABLE OF dpr_tv_bapi_description WITH EMPTY KEY.

    DATA project_definition_guid      TYPE bapi_ts_guid-project_definition_guid.
    DATA es_project_definition_detail TYPE bapi_ts_project_def_detail.
    DATA es_extension_out             TYPE bapiparex.
    DATA et_name                      TYPE STANDARD TABLE OF bapi_ts_name.
    DATA et_description               TYPE STANDARD TABLE OF bapi_ts_description.
    DATA et_status                    TYPE STANDARD TABLE OF bapi_ts_status.
    DATA et_authorization             TYPE STANDARD TABLE OF bapi_ts_authorization_out.
    DATA return_tab                   TYPE STANDARD TABLE OF bapiret2.
    DATA is_extension_in              TYPE bapiparex.
    DATA is_project_definition        TYPE bapi_ts_project_def.
    DATA is_project_definition_upd    TYPE bapi_ts_project_def_upd.

    IF projguid IS NOT INITIAL.
      project_definition_guid = projguid.
    ELSE.
      SELECT SINGLE guid FROM dpr_project WHERE project_id = @projnum INTO @DATA(dpr_project_guid).
      IF sy-subrc <> 0.
        MESSAGE |Project "{ projnum }" not found in table DPR_PROJECT| TYPE 'I' DISPLAY LIKE 'E'.
        RETURN.
      ENDIF.
      project_definition_guid = dpr_project_guid.
    ENDIF.

    CALL FUNCTION 'BAPI_BUS2172_GET_DETAIL'
      EXPORTING
        project_definition_guid      = project_definition_guid
      IMPORTING
        es_project_definition_detail = es_project_definition_detail
        es_extension_out             = es_extension_out
      TABLES
        et_name                      = et_name
        et_description               = et_description
        et_status                    = et_status
        et_authorization             = et_authorization
        return                       = return_tab.

    LOOP AT return_tab REFERENCE INTO DATA(return_line)
         WHERE type CA 'AEX'.
      WRITE / return_line->message.
    ENDLOOP.
    IF sy-subrc = 0.
      MESSAGE 'Error(s) during GET_DETAIL c.f. messages in the list/spool' TYPE 'I' DISPLAY LIKE 'E'.
      RETURN.
    ENDIF.

    is_extension_in = es_extension_out.
    es_extension_out = VALUE #( ).

    DATA(description_lines) = VALUE tt_description_lines( FOR <description_line> IN et_description
                                                          WHERE ( language = es_project_definition_detail-master_language )
                                                          ( <description_line>-description_line ) ).
    CONCATENATE LINES OF description_lines INTO DATA(project_description) RESPECTING BLANKS.
    cl_dpr_bapi_services=>convert_string_to_rawparts( EXPORTING iv_desc_string = project_description
                                                      IMPORTING ev_desc_part1  = DATA(desc_part1)
                                                                ev_desc_part2  = DATA(desc_part2)
                                                                ev_desc_part3  = DATA(desc_part3)
                                                                ev_desc_part4  = DATA(desc_part4) ).
    " The error "Enter an object number" (DPR_CGPL_MESSAGES003) happens if IS_PROJECT_DEFINITION-PROJECT_ID
    "   is filled, but no error if it's empty!? --> let's keep it empty then...
    is_project_definition = VALUE bapi_ts_project_def(
        project_number               = ''
        project_name_language        = es_project_definition_detail-master_language " es_project_definition_detail-project_name_language
        project_name                 = VALUE #( et_name[ language = es_project_definition_detail-master_language ]-name OPTIONAL ) " es_project_definition_detail-project_name
        project_type                 = es_project_definition_detail-project_type
        project_cause                = es_project_definition_detail-project_cause
        responsible_role_guid        = es_project_definition_detail-responsible_role_guid
        priority                     = es_project_definition_detail-priority
        fixed_start_constraint_type  = es_project_definition_detail-fixed_start_constraint_type
        fixed_start_date             = conv_date_ext_to_int( es_project_definition_detail-fixed_start_date )
        fixed_finish_constraint_type = es_project_definition_detail-fixed_finish_constraint_type
        fixed_finish_date            = conv_date_ext_to_int( es_project_definition_detail-fixed_finish_date )
        calendar                     = es_project_definition_detail-calendar
        sold_to_party_number         = es_project_definition_detail-sold_to_party_number
        customer_number              = es_project_definition_detail-customer_number
        grouping                     = es_project_definition_detail-grouping
        search_field                 = es_project_definition_detail-search_field
        actual_work                  = es_project_definition_detail-actual_work
        actual_work_unit             = es_project_definition_detail-actual_work_unit
        responsible_orga_unit        = es_project_definition_detail-responsible_orga_unit
        project_description_language = es_project_definition_detail-master_language " es_project_definition_detail-project_description_language
        project_description_part1    = desc_part1 " es_project_definition_detail-project_description_part1
        project_description_part2    = desc_part2 " es_project_definition_detail-project_description_part2
        project_description_part3    = desc_part3 " es_project_definition_detail-project_description_part3
        project_description_part4    = desc_part4 " es_project_definition_detail-project_description_part4
        location                     = es_project_definition_detail-location
        allocation_unit              = es_project_definition_detail-allocation_unit
        period_type                  = es_project_definition_detail-period_type
        forecasted_start             = conv_date_ext_to_int( es_project_definition_detail-forecasted_start )
        forecasted_finish            = conv_date_ext_to_int( es_project_definition_detail-forecasted_finish )
        master_language              = es_project_definition_detail-master_language ).
    is_project_definition_upd = VALUE bapi_ts_project_def_upd(
        project_number               = xsdbool( is_project_definition-project_number IS NOT INITIAL )
        project_name_language        = xsdbool( is_project_definition-project_name_language IS NOT INITIAL )
        project_name                 = xsdbool( is_project_definition-project_name IS NOT INITIAL )
        project_type                 = xsdbool( is_project_definition-project_type IS NOT INITIAL )
        project_cause                = xsdbool( is_project_definition-project_cause IS NOT INITIAL )
        responsible_role_guid        = xsdbool( is_project_definition-responsible_role_guid IS NOT INITIAL )
        priority                     = xsdbool( is_project_definition-priority IS NOT INITIAL )
        fixed_start_constraint_type  = xsdbool( is_project_definition-fixed_start_constraint_type IS NOT INITIAL )
        fixed_start_date             = xsdbool( is_project_definition-fixed_start_date IS NOT INITIAL )
        fixed_finish_constraint_type = xsdbool( is_project_definition-fixed_finish_constraint_type IS NOT INITIAL )
        fixed_finish_date            = xsdbool( is_project_definition-fixed_finish_date IS NOT INITIAL )
        calendar                     = xsdbool( is_project_definition-calendar IS NOT INITIAL )
        sold_to_party_number         = xsdbool( is_project_definition-sold_to_party_number IS NOT INITIAL )
        customer_number              = xsdbool( is_project_definition-customer_number IS NOT INITIAL )
        grouping                     = xsdbool( is_project_definition-grouping IS NOT INITIAL )
        search_field                 = xsdbool( is_project_definition-search_field IS NOT INITIAL )
        actual_work                  = xsdbool( is_project_definition-actual_work IS NOT INITIAL )
        actual_work_unit             = xsdbool( is_project_definition-actual_work_unit IS NOT INITIAL )
        responsible_orga_unit        = xsdbool( is_project_definition-responsible_orga_unit IS NOT INITIAL )
        project_description_language = xsdbool( is_project_definition-project_description_language IS NOT INITIAL )
        project_description          = xsdbool(    is_project_definition-project_description_part1 IS NOT INITIAL
                                                OR is_project_definition-project_description_part2 IS NOT INITIAL
                                                OR is_project_definition-project_description_part3 IS NOT INITIAL
                                                OR is_project_definition-project_description_part4 IS NOT INITIAL )
        location                     = xsdbool( is_project_definition-location IS NOT INITIAL )
        allocation_unit              = xsdbool( is_project_definition-allocation_unit IS NOT INITIAL )
        period_type                  = xsdbool( is_project_definition-period_type IS NOT INITIAL )
        forecasted_start             = xsdbool( is_project_definition-forecasted_start IS NOT INITIAL )
        forecasted_finish            = xsdbool( is_project_definition-forecasted_finish IS NOT INITIAL )
        extensions                   = xsdbool( is_extension_in IS NOT INITIAL ) ).

    CALL FUNCTION 'BAPI_BUS2172_CREATE'
      EXPORTING
        is_project_definition     = is_project_definition
        is_project_definition_upd = is_project_definition_upd
        is_extension_in           = is_extension_in
      IMPORTING
        es_extension_out          = es_extension_out
      TABLES
        return                    = return_tab.

    LOOP AT return_tab REFERENCE INTO return_line
         WHERE type CA 'AEX'.
      WRITE : / return_line->type, return_line->number, return_line->id, return_line->message.
    ENDLOOP.
    IF sy-subrc = 0.
      CALL FUNCTION 'BAPI_CPROJECTS_ROLLBACK_WORK'
        TABLES
          return = return_tab.
      MESSAGE 'Error(s) during CREATE c.f. messages in the list/spool' TYPE 'I' DISPLAY LIKE 'E'.
      RETURN.
    ENDIF.

    LOOP AT return_tab REFERENCE INTO return_line.
      WRITE : / return_line->type, return_line->number, return_line->id, return_line->message.
    ENDLOOP.

    IF 0 = 1.
      MESSAGE s114(dpr_bapi) ##MG_MISSING.
    ENDIF.
    DATA(success_message) = VALUE #( return_tab[ id     = 'DPR_BAPI'
                                                 number = '114' ] OPTIONAL ).

    CALL FUNCTION 'BAPI_CPROJECTS_COMMIT_WORK'
      TABLES
        return = return_tab.

    LOOP AT return_tab REFERENCE INTO return_line.
      WRITE : / return_line->type, return_line->number, return_line->id, return_line->message.
    ENDLOOP.

    IF success_message IS NOT INITIAL.
      DATA(project_guid) = CONV dpr_project-guid( success_message-message_v1 ).
      SELECT SINGLE project_id FROM dpr_project WHERE guid = @project_guid INTO @DATA(project_id).
      IF sy-subrc = 0.
        WRITE / |GUID { project_guid } = Project { project_id } |.
      ENDIF.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

1 Comment
Sandra_Rossi
Active Contributor

Here's a program to copy a purchase document (header and items only, but it's easy to extend) via BAPI_PO_GETDETAIL2 and BAPI_PO_CREATE1.

I'm using the generic method SET_DEFAULT_BAPIUPDATE_FLAGS to automatically define the value of the parameter POITEMX.

There's also a CHANGE method to copy the first item in an existing purchase order which I used to make sure that it's not needed to pass the other items).

I wondered what the field PO_ITEMX of parameter POITEMX was for, it has apparently no effect, but I asked the question here in case you wonder too: BAPI_PO_CHANGE meaning of X key fields of the X ta... - SAP Community.

REPORT z_po_copy.

PARAMETERS ebeln TYPE ekpo-ebeln DEFAULT '9500000137'.

CLASS lcl_app DEFINITION DEFERRED.

DATA go_app TYPE REF TO lcl_app.

LOAD-OF-PROGRAM.
  CALL METHOD lcl_app=>('CREATE')
    RECEIVING
      result = go_app.

START-OF-SELECTION.
  CALL METHOD go_app->('START_OF_SELECTION').
*  CALL METHOD go_app->('CHANGE').

CLASS lcl_app DEFINITION FINAL
  CREATE PRIVATE.

  PUBLIC SECTION.
    METHODS change.

    CLASS-METHODS create
      RETURNING VALUE(result) TYPE REF TO lcl_app.

    METHODS start_of_selection.

  PRIVATE SECTION.
    CLASS-METHODS set_default_bapiupdate_flags
      IMPORTING is_bapi_parameter   TYPE any
      CHANGING  cs_bapi_parameter_x TYPE any.
ENDCLASS.

CLASS lcl_app IMPLEMENTATION.
  METHOD create.
    result = NEW lcl_app( ).
  ENDMETHOD.

  METHOD start_of_selection.
    DATA(purchaseorder) = EXACT ebeln( ebeln ).
    DATA(items) = VALUE selkz( ).
    DATA(account_assignment) = VALUE selkz( ).
    DATA(schedules) = VALUE selkz( ).
    DATA(history) = VALUE selkz( ).
    DATA(item_texts) = VALUE selkz( ).
    DATA(header_texts) = VALUE selkz( ).
    DATA(services) = VALUE selkz( ).
    DATA(confirmations) = VALUE selkz( ).
    DATA(service_texts) = VALUE selkz( ).
    DATA(extensions) = VALUE selkz( ).
    DATA(po_header) = VALUE bapiekkol( ).
    DATA(po_address) = VALUE bapiaddress( ).
    TYPES po_header_texts            TYPE STANDARD TABLE OF bapiekkotx WITH DEFAULT KEY.
    TYPES po_items                   TYPE STANDARD TABLE OF bapiekpo WITH DEFAULT KEY.
    TYPES po_item_account_assignment TYPE STANDARD TABLE OF bapiekkn WITH DEFAULT KEY.
    TYPES po_item_schedules          TYPE STANDARD TABLE OF bapieket WITH DEFAULT KEY.
    TYPES po_item_confirmations      TYPE STANDARD TABLE OF bapiekes WITH DEFAULT KEY.
    TYPES po_item_texts              TYPE STANDARD TABLE OF bapiekpotx WITH DEFAULT KEY.
    TYPES po_item_history            TYPE STANDARD TABLE OF bapiekbe WITH DEFAULT KEY.
    TYPES po_item_history_totals     TYPE STANDARD TABLE OF bapiekbes WITH DEFAULT KEY.
    TYPES po_item_limits             TYPE STANDARD TABLE OF bapiesuh WITH DEFAULT KEY.
    TYPES po_item_contract_limits    TYPE STANDARD TABLE OF bapiesuc WITH DEFAULT KEY.
    TYPES po_item_services           TYPE STANDARD TABLE OF bapiesll WITH DEFAULT KEY.
    TYPES po_item_srv_accass_values  TYPE STANDARD TABLE OF bapieskl WITH DEFAULT KEY.
    TYPES return                     TYPE STANDARD TABLE OF bapireturn WITH DEFAULT KEY.
    TYPES po_services_texts          TYPE STANDARD TABLE OF bapieslltx WITH DEFAULT KEY.
    TYPES extensionout               TYPE STANDARD TABLE OF bapiparex WITH DEFAULT KEY.
    DATA po_header_texts            TYPE po_header_texts.
    DATA po_items                   TYPE po_items.
    DATA po_item_account_assignment TYPE po_item_account_assignment.
    DATA po_item_schedules          TYPE po_item_schedules.
    DATA po_item_confirmations      TYPE po_item_confirmations.
    DATA po_item_texts              TYPE po_item_texts.
    DATA po_item_history            TYPE po_item_history.
    DATA po_item_history_totals     TYPE po_item_history_totals.
    DATA po_item_limits             TYPE po_item_limits.
    DATA po_item_contract_limits    TYPE po_item_contract_limits.
    DATA po_item_services           TYPE po_item_services.
    DATA po_item_srv_accass_values  TYPE po_item_srv_accass_values.
    DATA return                     TYPE return.
    DATA po_services_texts          TYPE po_services_texts.
    DATA extensionout               TYPE extensionout.

    items = 'X'.
    account_assignment = 'X'.
    schedules          = 'X'.
    history            = 'X'.
    item_texts         = 'X'.
    header_texts       = 'X'.
    services           = 'X'.
    confirmations      = 'X'.
    service_texts      = 'X'.
    extensions         = 'X'.
    CALL FUNCTION 'BAPI_PO_GETDETAIL2'
      EXPORTING
        purchaseorder              = purchaseorder
        items                      = items
        account_assignment         = account_assignment
        schedules                  = schedules
        history                    = history
        item_texts                 = item_texts
        header_texts               = header_texts
        services                   = services
        confirmations              = confirmations
        service_texts              = service_texts
        extensions                 = extensions
      IMPORTING
        po_header                  = po_header
        po_address                 = po_address
      TABLES
        po_header_texts            = po_header_texts
        po_items                   = po_items
        po_item_account_assignment = po_item_account_assignment
        po_item_schedules          = po_item_schedules
        po_item_confirmations      = po_item_confirmations
        po_item_texts              = po_item_texts
        po_item_history            = po_item_history
        po_item_history_totals     = po_item_history_totals
        po_item_limits             = po_item_limits
        po_item_contract_limits    = po_item_contract_limits
        po_item_services           = po_item_services
        po_item_srv_accass_values  = po_item_srv_accass_values
        return                     = return
        po_services_texts          = po_services_texts
        extensionout               = extensionout.

    DATA(poheader) = VALUE bapimepoheader( ).
    DATA(poheaderx)    = VALUE bapimepoheaderx( ).
    DATA(poaddrvendor) = VALUE bapimepoaddrvendor( ).
    DATA(testrun) = VALUE char1( ).
    DATA(memory_uncomplete) = VALUE char1( ).
    DATA(memory_complete) = VALUE char1( ).
    DATA(poexpimpheader)  = VALUE bapieikp( ).
    DATA(poexpimpheaderx) = VALUE bapieikpx( ).
    DATA(versions) = VALUE bapimedcm( ).
    DATA(no_messaging) = VALUE char1( ).
    DATA(no_message_req) = VALUE char1( ).
    DATA(no_authority) = VALUE char1( ).
    DATA(no_price_from_po) = VALUE char1( ).
    DATA(park_complete)    = VALUE char1( ).
    DATA(park_uncomplete)  = VALUE char1( ).
    DATA(exppurchaseorder) = VALUE ebeln( ).
    DATA(expheader) = VALUE bapimepoheader( ).
    DATA(exppoexpimpheader) = VALUE bapieikp( ).
    TYPES return2                TYPE STANDARD TABLE OF bapiret2 WITH DEFAULT KEY.
    " types return  type standard table of bapiret2 with default key.
    TYPES poitem                 TYPE STANDARD TABLE OF bapimepoitem WITH DEFAULT KEY.
    TYPES poitemx                TYPE STANDARD TABLE OF bapimepoitemx WITH DEFAULT KEY.
    TYPES poaddrdelivery         TYPE STANDARD TABLE OF bapimepoaddrdelivery WITH DEFAULT KEY.
    TYPES poschedule             TYPE STANDARD TABLE OF bapimeposchedule WITH DEFAULT KEY.
    TYPES poschedulex            TYPE STANDARD TABLE OF bapimeposchedulx WITH DEFAULT KEY.
    TYPES poaccount              TYPE STANDARD TABLE OF bapimepoaccount WITH DEFAULT KEY.
    TYPES poaccountprofitsegment TYPE STANDARD TABLE OF bapimepoaccountprofitsegment WITH DEFAULT KEY.
    TYPES poaccountx             TYPE STANDARD TABLE OF bapimepoaccountx WITH DEFAULT KEY.
    TYPES pocondheader           TYPE STANDARD TABLE OF bapimepocondheader WITH DEFAULT KEY.
    TYPES pocondheaderx          TYPE STANDARD TABLE OF bapimepocondheaderx WITH DEFAULT KEY.
    TYPES pocond                 TYPE STANDARD TABLE OF bapimepocond WITH DEFAULT KEY.
    TYPES pocondx                TYPE STANDARD TABLE OF bapimepocondx WITH DEFAULT KEY.
    TYPES polimits               TYPE STANDARD TABLE OF bapiesuhc WITH DEFAULT KEY.
    TYPES pocontractlimits       TYPE STANDARD TABLE OF bapiesucc WITH DEFAULT KEY.
    TYPES poservices             TYPE STANDARD TABLE OF bapiesllc WITH DEFAULT KEY.
    TYPES posrvaccessvalues      TYPE STANDARD TABLE OF bapiesklc WITH DEFAULT KEY.
    TYPES poservicestext         TYPE STANDARD TABLE OF bapieslltx WITH DEFAULT KEY.
    TYPES extensionin            TYPE STANDARD TABLE OF bapiparex WITH DEFAULT KEY.
    " types extensionout    type standard table of bapiparex with default key.
    TYPES poexpimpitem           TYPE STANDARD TABLE OF bapieipo WITH DEFAULT KEY.
    TYPES poexpimpitemx          TYPE STANDARD TABLE OF bapieipox WITH DEFAULT KEY.
    TYPES potextheader           TYPE STANDARD TABLE OF bapimepotextheader WITH DEFAULT KEY.
    TYPES potextitem             TYPE STANDARD TABLE OF bapimepotext WITH DEFAULT KEY.
    TYPES allversions            TYPE STANDARD TABLE OF bapimedcm_allversions WITH DEFAULT KEY.
    TYPES popartner              TYPE STANDARD TABLE OF bapiekkop WITH DEFAULT KEY.
    TYPES pocomponents           TYPE STANDARD TABLE OF bapimepocomponent WITH DEFAULT KEY.
    TYPES pocomponentsx          TYPE STANDARD TABLE OF bapimepocomponentx WITH DEFAULT KEY.
    TYPES poshipping             TYPE STANDARD TABLE OF bapiitemship WITH DEFAULT KEY.
    TYPES poshippingx            TYPE STANDARD TABLE OF bapiitemshipx WITH DEFAULT KEY.
    TYPES poshippingexp          TYPE STANDARD TABLE OF bapimeposhippexp WITH DEFAULT KEY.
    TYPES serialnumber           TYPE STANDARD TABLE OF bapimeposerialno WITH DEFAULT KEY.
    TYPES serialnumberx          TYPE STANDARD TABLE OF bapimeposerialnox WITH DEFAULT KEY.
    TYPES invplanheader          TYPE STANDARD TABLE OF bapi_invoice_plan_header WITH DEFAULT KEY.
    TYPES invplanheaderx         TYPE STANDARD TABLE OF bapi_invoice_plan_headerx WITH DEFAULT KEY.
    TYPES invplanitem            TYPE STANDARD TABLE OF bapi_invoice_plan_item WITH DEFAULT KEY.
    TYPES invplanitemx           TYPE STANDARD TABLE OF bapi_invoice_plan_itemx WITH DEFAULT KEY.
    TYPES nfmetallitms           TYPE STANDARD TABLE OF /nfm/bapidocitm WITH DEFAULT KEY.
    DATA return2                TYPE return2.
*    DATA RETURN                 TYPE RETURN.
    DATA poitem                 TYPE poitem.
    DATA poitemx                TYPE poitemx.
    DATA poaddrdelivery         TYPE poaddrdelivery.
    DATA poschedule             TYPE poschedule.
    DATA poschedulex            TYPE poschedulex.
    DATA poaccount              TYPE poaccount.
    DATA poaccountprofitsegment TYPE poaccountprofitsegment.
    DATA poaccountx             TYPE poaccountx.
    DATA pocondheader           TYPE pocondheader.
    DATA pocondheaderx          TYPE pocondheaderx.
    DATA pocond                 TYPE pocond.
    DATA pocondx                TYPE pocondx.
    DATA polimits               TYPE polimits.
    DATA pocontractlimits       TYPE pocontractlimits.
    DATA poservices             TYPE poservices.
    DATA posrvaccessvalues      TYPE posrvaccessvalues.
    DATA poservicestext         TYPE poservicestext.
    DATA extensionin            TYPE extensionin.
*DATA extensionout           TYPE extensionout          .
    DATA poexpimpitem           TYPE poexpimpitem.
    DATA poexpimpitemx          TYPE poexpimpitemx.
    DATA potextheader           TYPE potextheader.
    DATA potextitem             TYPE potextitem.
    DATA allversions            TYPE allversions.
    DATA popartner              TYPE popartner.
    DATA pocomponents           TYPE pocomponents.
    DATA pocomponentsx          TYPE pocomponentsx.
    DATA poshipping             TYPE poshipping.
    DATA poshippingx            TYPE poshippingx.
    DATA poshippingexp          TYPE poshippingexp.
    DATA serialnumber           TYPE serialnumber.
    DATA serialnumberx          TYPE serialnumberx.
    DATA invplanheader          TYPE invplanheader.
    DATA invplanheaderx         TYPE invplanheaderx.
    DATA invplanitem            TYPE invplanitem.
    DATA invplanitemx           TYPE invplanitemx.
    DATA nfmetallitms           TYPE nfmetallitms.

    poheader = VALUE #( BASE CORRESPONDING #( po_header )
                        created_by = cl_abap_syst=>get_user_name( ) ).
    set_default_bapiupdate_flags( EXPORTING is_bapi_parameter   = poheader
                                  CHANGING  cs_bapi_parameter_x = poheaderx ).
    poitem = CORRESPONDING #( po_items ).
    LOOP AT poitem REFERENCE INTO DATA(line_poitem).
      DATA(line_poitemx) = VALUE bapimepoitemx( po_item = line_poitem->po_item ).
      set_default_bapiupdate_flags( EXPORTING is_bapi_parameter   = line_poitem->*
                                    CHANGING  cs_bapi_parameter_x = line_poitemx ).
      INSERT line_poitemx INTO TABLE poitemx.
    ENDLOOP.

    CALL FUNCTION 'BAPI_PO_CREATE1'
      EXPORTING
        poheader               = poheader
        poheaderx              = poheaderx
        poaddrvendor           = poaddrvendor
        testrun                = testrun
        memory_uncomplete      = memory_uncomplete
        memory_complete        = memory_complete
        poexpimpheader         = poexpimpheader
        poexpimpheaderx        = poexpimpheaderx
        versions               = versions
        no_messaging           = no_messaging
        no_message_req         = no_message_req
        no_authority           = no_authority
        no_price_from_po       = no_price_from_po
        park_complete          = park_complete
        park_uncomplete        = park_uncomplete
      IMPORTING
        exppurchaseorder       = exppurchaseorder
        expheader              = expheader
        exppoexpimpheader      = exppoexpimpheader
      TABLES
        return                 = return2
        poitem                 = poitem
        poitemx                = poitemx
        poaddrdelivery         = poaddrdelivery
        poschedule             = poschedule
        poschedulex            = poschedulex
        poaccount              = poaccount
        poaccountprofitsegment = poaccountprofitsegment
        poaccountx             = poaccountx
        pocondheader           = pocondheader
        pocondheaderx          = pocondheaderx
        pocond                 = pocond
        pocondx                = pocondx
        polimits               = polimits
        pocontractlimits       = pocontractlimits
        poservices             = poservices
        posrvaccessvalues      = posrvaccessvalues
        poservicestext         = poservicestext
        extensionin            = extensionin
        extensionout           = extensionout
        poexpimpitem           = poexpimpitem
        poexpimpitemx          = poexpimpitemx
        potextheader           = potextheader
        potextitem             = potextitem
        allversions            = allversions
        popartner              = popartner
        pocomponents           = pocomponents
        pocomponentsx          = pocomponentsx
        poshipping             = poshipping
        poshippingx            = poshippingx
        poshippingexp          = poshippingexp
        serialnumber           = serialnumber
        serialnumberx          = serialnumberx
        invplanheader          = invplanheader
        invplanheaderx         = invplanheaderx
        invplanitem            = invplanitem
        invplanitemx           = invplanitemx
        nfmetallitms           = nfmetallitms.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.
  ENDMETHOD.

  METHOD change.
    TYPES bapiekpo_t TYPE STANDARD TABLE OF bapiekpo WITH DEFAULT KEY.
    DATA lt_msg_bapi TYPE bapiret2_t.

    DATA(purchaseorder) = EXACT ebeln( '9500000140' ).
    DATA(po_items) = VALUE bapiekpo_t( ).
    CALL FUNCTION 'BAPI_PO_GETDETAIL2'
      EXPORTING purchaseorder              = purchaseorder
                items                      = 'X'
      TABLES    po_items                   = po_items.
    data(new_po_item) = exact ekpo-ebelp( po_items[ lines( po_items ) ]-po_item ).
    new_po_item += 10.
    DATA(ls_item) = po_items[ 1 ].
    DATA(lt_poitem) = VALUE bapimepoitem_tp( ).
    DATA(lt_poitemx) = VALUE bapimepoitemx_tp( ).
    DATA(poitemx) = VALUE bapimepoitemx( ).
    DATA(poitem) = VALUE bapimepoitem( BASE CORRESPONDING #( ls_item )
                                       po_item = new_po_item ).
    INSERT poitem INTO TABLE lt_poitem.
    set_default_bapiupdate_flags( EXPORTING is_bapi_parameter   = poitem
                                  CHANGING  cs_bapi_parameter_x = poitemx ).
    poitemx-po_item = new_po_item.
*    poitemx-po_itemx = 'X'. " USELESS!? (https://community.sap.com/t5/abap-forum/bapi-po-change-meaning-of-x-key-fields-of-the-x-table-parameters/m-p/14360432)
    INSERT poitemx INTO TABLE lt_poitemx.
    CALL FUNCTION 'BAPI_PO_CHANGE'
      EXPORTING purchaseorder = purchaseorder
      TABLES    return        = lt_msg_bapi
                poitem        = lt_poitem
                poitemx       = lt_poitemx.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING wait = 'X'.
  ENDMETHOD.

  METHOD set_default_bapiupdate_flags.
    DATA(lo_rtts) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( cs_bapi_parameter_x ) ).
    LOOP AT lo_rtts->get_components( ) REFERENCE INTO DATA(ls_component).
      IF ls_component->type->get_relative_name( ) <> 'BAPIUPDATE'.
        CONTINUE.
      ENDIF.
      ASSIGN is_bapi_parameter-(ls_component->name) TO FIELD-SYMBOL(<lv_bapi_parameter_field>).
      IF sy-subrc <> 0 OR <lv_bapi_parameter_field> IS INITIAL.
        CONTINUE.
      ENDIF.
      ASSIGN cs_bapi_parameter_x-(ls_component->name) TO FIELD-SYMBOL(<lv_bapi_parameter_x_field>).
      IF sy-subrc <> 0.
        CONTINUE.
      ENDIF.
      <lv_bapi_parameter_x_field> = abap_true.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Labels in this area