Skip to Content
-3

How to create multiple sales order with BAPI_SALESORDER_CREATEFROMDAT2?

Dear Experts,

I’m trying to create new sales orders with the BAPI:

CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2'

        EXPORTING
          order_header_in      = ls_order_header_in1
          logic_switch         = ls_logic_switch
        IMPORTING
          salesdocument        = lv_salesdocument
        TABLES
          return               = lt_return1
          order_items_in       = lt_order_items_in1
          order_partners       = lt_order_partners1
          order_schedules_in   = lt_order_schedules_in1
          order_conditions_in  = lt_order_condetions_in
          order_conditions_inx = lt_order_condetions_inx.

IF NOT lv_salesdocument IS INITIAL.
 
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
          EXPORTING
            wait   = abap_false
          IMPORTING
            return = ls_return2.

ELSE. 
   LOOP AT lt_return1 INTO ls_return1.
      MOVE ls_return1-message TO lv_logmessage.
      zcl_log=>i_message( lv_logmessage ).
   ENDLOOP.
   CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

ENDIF.

This worked fine when it is called once. But some times we got documents with more then one sales order. For this reason, I have implement a loop, which call the BAPI several times with different sales order data. I have just carefully inspected the code sequence with the debugger and detected, that with the first call can the BAPI create a sales order successfully. After this the BAPI create a document number (lv_salesdocument) for every sales order and after FM 'BAPI_TRANSACTION_COMMIT' appears the message

Then I look at single prompt

The "Error Info…" is in German and it means “the internal session is terminated with the runtime error SAPSQL_ARRAY_INSERT_DUPREC”. I didn’t find anything about this runtime error in the internet.

Can someone help me please?

Kind regards,

Emal Rahman

message-1.png (39.7 kB)
message-2.png (18.0 kB)
Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

6 Answers

  • Best Answer
    Feb 06 at 09:07 AM

    "The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification — and then shouldn’t be used anyway." Robert C. Martin.

    When you are always disagree with obove assertion, please try to create sales order with the FM: 'BAPI_SALESORDER_CREATEFROMDAT2’. The consumers must be informed in advance, this wonderful FM uses 1034 arguments.

    In this case the error message appears because of line number for new items (ls_order_schedules_in1-sched_line = lv_line_nr.). You have to fill the sched_line field from order_schedules_in with a new number for every new items (ADD 1 TO lv_line_nr.).

    How ever the following code processed a document which containt header and positions data. For every positions it will be created a sales order.

    Please note that the gt_header_data and gt_position_data can be declared globally. Please note also that zcl_log is my class for logging you should use yours.

    METHOD zif_xmlextractor~create_salesorders.
    
    * Constants
      CONSTANTS:
        lc_partner_role                TYPE parvw VALUE 'AG',
        lc_doc_type                    TYPE auart VALUE 'ZV00',
        lc_sales_org                   TYPE vkorg VALUE '0205',
        lc_distr_chan                  TYPE vtweg VALUE '10',
        lc_division                    TYPE spart VALUE '10',
        lc_weight_unit                 TYPE meins VALUE 'KG',
        lc_material_nr                 TYPE matnr VALUE '000000000000070406',
        lc_konditionsmengeneinheit     TYPE kmein VALUE 'LE',
        lc_konditionsart               TYPE kscha VALUE 'ZMAN',
        lc_currency                    TYPE waers VALUE 'EUR',
        lc_kunden_auftragsmenge_in_vme TYPE wmeng VALUE '1.00',
        lc_kondition_herkunft          TYPE kherk VALUE 'A',
        lc_kondition_klasse            TYPE koaid VALUE 'B',
        lc_kondition_applikation       TYPE kappl VALUE 'V',
        lc_kondition_prieseinheit      TYPE kpein VALUE '1',
        lc_kondition_manuell           TYPE kmprs VALUE 'X',
        lc_kondition_rechenregel       TYPE krech VALUE 'C',
        lc_kondition_umrechnungzaehler TYPE kumza VALUE '1',
        lc_kondition_umrechnungsnenner TYPE kumne VALUE '1',
        lc_kondition_update_flag       TYPE updkz_d VALUE 'U',
        lc_anwendungsobjekt            TYPE thead-tdobject VALUE 'VBBP',
        lc_id                          TYPE thead-tdid VALUE '0001',
        lc_current_posnr               TYPE num6 VALUE '000010',
        lc_preisfindungsart(1)         TYPE c VALUE 'C'.  
    
    
    
    
    
    * Data for BAPI
      DATA:
        ls_logic_switch         TYPE bapisdls,
        ls_return2              TYPE bapiret2,
        ls_order_header_in1     TYPE bapisdhd1,
        ls_order_header_intx    TYPE bapisdhd1x,
        lv_salesdocument        TYPE bapivbeln-vbeln,
        ls_order_partners1      TYPE bapiparnr,
        ls_order_items_in1      TYPE bapisditm,
        ls_order_items_in1x     TYPE bapisditmx,
        ls_order_schedules_in1  TYPE bapischdl,
        ls_order_schedules_in1x TYPE bapischdlx,
        ls_order_condetions_in  TYPE bapicond,
        ls_order_condetions_inx TYPE bapicondx,
        lt_return1              TYPE TABLE OF bapiret2,
        ls_return1              LIKE LINE OF lt_return1,
        lt_order_items_in1      TYPE TABLE OF bapisditm,
        lt_order_partners1      TYPE TABLE OF bapiparnr,
        lt_order_schedules_in1  TYPE TABLE OF bapischdl,
        lt_order_condetions_in  TYPE TABLE OF bapicond,
        lt_order_condetions_inx TYPE TABLE OF bapicondx,
        lv_line_nr              TYPE etenr VALUE 1.
    
    
    
    * Processing data
      DATA:
        lv_kreditor(10)    TYPE c,
        lv_debitor(10)     TYPE c,
        ls_rgkopf_lft      TYPE zsd_rgkopf_lft,
        ls_rgpos_lft       TYPE zsd_rgpos_lft,
        lv_positionsnummer TYPE num6,
        gs_knal            TYPE kna1,
        lv_logmessage      TYPE string,
        gt_lines           TYPE TABLE OF tline,
        gs_lines           LIKE LINE OF gt_lines,
        f_name             TYPE tdobname,
        lv_loop_variable   TYPE i.
    
    
    
      LOOP AT gt_header_data INTO ls_rgkopf_lft.
    
        MOVE ls_rgkopf_lft-kreditor TO lv_kreditor.
        SELECT SINGLE kunnr FROM lfa1
        INTO lv_debitor
        WHERE lifnr = lv_kreditor.
        IF NOT sy-subrc = 0.
          zcl_log=>i_message('Write your log message').
          CONTINUE.
        ELSE.
          SELECT SINGLE * FROM kna1
          INTO gs_knal
          WHERE kunnr = lv_debitor AND lifnr = lv_kreditor.
          IF NOT sy-subrc = 0.
            zcl_log=>i_message('Write your log message').
            CONTINUE.
          ENDIF.
        ENDIF.
    
    
    
    
    
        ls_order_partners1-partn_role = lc_partner_role.
        ls_order_partners1-partn_numb = lv_debitor.
        APPEND ls_order_partners1 TO lt_order_partners1.
    
    
    
        ls_order_header_in1-purch_no_c = ls_rgkopf_lft-rechnungsnummer.
        ls_order_header_in1-purch_date = ls_rgkopf_lft-rechnungsdatum .
        ls_order_header_in1-doc_type   = lc_doc_type.
        ls_order_header_in1-sales_org  = lc_sales_org.
        ls_order_header_in1-distr_chan = lc_distr_chan.
        ls_order_header_in1-division   = lc_division.
    
        SELECT SINGLE zterm FROM knvv
        INTO ls_order_header_in1-pmnttrms
        WHERE kunnr = lv_debitor.
    
    
    
        LOOP AT gt_position_data INTO ls_rgpos_lft WHERE id = ls_rgkopf_lft-id.
    
          ls_order_items_in1-material = lc_material_nr.
          ls_order_items_in1-gross_wght = ls_rgpos_lft-gewicht.
          ls_order_items_in1-untof_wght = lc_weight_unit.
          ls_order_items_in1-serv_date = ls_rgpos_lft-sendungsdatum.
          ls_order_items_in1-purch_no_s = ls_rgpos_lft-sendungsnummer.
          ls_order_items_in1-plant = lc_sales_org.
          ls_order_items_in1-target_val = ls_rgpos_lft-claim_amount.
          ls_order_items_in1-itm_number = lv_positionsnummer.
          APPEND ls_order_items_in1 TO lt_order_items_in1. 
          ls_order_condetions_in-cond_value = ls_rgpos_lft-claim_amount.
          ls_order_condetions_in-cond_unit = lc_konditionsmengeneinheit.
          ls_order_condetions_in-cond_p_unt = lc_kondition_prieseinheit.
          ls_order_condetions_in-applicatio = lc_kondition_applikation.
          ls_order_condetions_in-condchaman = lc_kondition_manuell.
          ls_order_condetions_in-calctypcon = lc_kondition_rechenregel.
          ls_order_condetions_in-numconvert = lc_kondition_umrechnungzaehler.
          ls_order_condetions_in-denominato = lc_kondition_umrechnungsnenner.
          ls_order_condetions_in-condclass = lc_kondition_klasse.
          ls_order_condetions_in-condvalue = ls_rgpos_lft-claim_amount.
          ls_order_condetions_in-itm_number = lv_positionsnummer.
          ls_order_condetions_in-cond_type = lc_konditionsart.
          ls_order_condetions_in-currency = lc_currency.
          ls_order_condetions_in-cond_updat = abap_true.
          ls_order_condetions_in-condorigin = lc_kondition_herkunft.
          APPEND ls_order_condetions_in TO lt_order_condetions_in.
          ls_order_condetions_inx-itm_number = lv_positionsnummer.
          ls_order_condetions_inx-cond_type = lc_konditionsart.
          ls_order_condetions_inx-cond_value = abap_true.
          ls_order_condetions_inx-currency = abap_true.
          ls_order_condetions_inx-updateflag = lc_kondition_update_flag.
          APPEND ls_order_condetions_inx TO lt_order_condetions_inx.
          ls_order_schedules_in1-req_qty = lc_kunden_auftragsmenge_in_vme.
          ls_order_schedules_in1-sched_line = lv_line_nr.
          ls_order_schedules_in1-itm_number = lv_positionsnummer.
          APPEND ls_order_schedules_in1 TO lt_order_schedules_in1.
          ls_logic_switch-pricing = lc_preisfindungsart.
          ADD 1 TO lv_line_nr.
    
    
    
    *   Create sales order
          CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2'
            EXPORTING
              order_header_in      = ls_order_header_in1
              logic_switch         = ls_logic_switch
            IMPORTING
              salesdocument        = lv_salesdocument
            TABLES
              return               = lt_return1
              order_items_in       = lt_order_items_in1
              order_partners       = lt_order_partners1
              order_schedules_in   = lt_order_schedules_in1
              order_conditions_in  = lt_order_condetions_in
              order_conditions_inx = lt_order_condetions_inx.
          IF NOT lv_salesdocument IS INITIAL. 
            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
              EXPORTING
                wait   = abap_true
              IMPORTING
                return = ls_return2.
    
            FREE ls_logic_switch.
            REFRESH lt_order_items_in1.
            REFRESH lt_order_schedules_in1.
            REFRESH lt_order_condetions_in.
            REFRESH lt_order_condetions_inx.
    
          ELSE.
            zcl_log=>i_message('Write your log message').
            LOOP AT lt_return1 INTO ls_return1.
              MOVE ls_return1-message TO lv_logmessage.
              zcl_log=>i_message( lv_logmessage ).
            ENDLOOP.
            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          ENDIF.
    
        ENDLOOP.
    
        FREE ls_order_header_in1.
        FREE ls_order_partners1.
        CLEAR lv_kreditor.
        CLEAR lv_debitor.
    
      ENDLOOP.
    
    
    ENDMETHOD.
    
    Add comment
    10|10000 characters needed characters exceeded

  • Feb 05 at 02:21 PM

    Your code sample does not show any loop which means nobody can verify what you exactly did.

    From what I see it just seems that you try to create the same sales order again if you have several items. And creating an existing sales order again of course leads to a duplicate record in the database.

    You either need to create one sales order with many items, or for each item an individual sales.

    I wonder that you did not find anything in the internet, just searching with Google in the SAP domain returns already 1240 results for this search term SAPSQL_ARRAY_INSERT_DUPREC site:sap.com

    Add comment
    10|10000 characters needed characters exceeded

  • Feb 05 at 12:50 PM

    Hi Emal Rahman,

    Use abap_true(X) instead of abap_false(' ') in BAPI_TRANSACTION_COMMIT as shown below.

    CALLFUNCTION'BAPI_TRANSACTION_COMMIT'
    EXPORTING
    wait= abap_true
    IMPORTING
    return= ls_return2.

    Also, check whether the BAPI item internal tables(lt_order_items_in1, lt_order_partners1 etc.,) are refreshed before the endloop statement(for preparing(clearing) for the new(next) sales order).

    Regards

    Rajkumar Narasimman

    Add comment
    10|10000 characters needed characters exceeded

    • Hello Rajkumar Narsimman,

      thank you for helpfulness. I have tried with abap_true and abap_false before I write my question in forum. At the end of loop the internal tables are refreshed. But it doesn’t work. Therefor I writ the question here.

  • Feb 05 at 02:16 PM

    Have a look at OSS notes 1498052 and 2077631

    Add comment
    10|10000 characters needed characters exceeded

  • Feb 06 at 06:50 AM

    You should analyze the error with transaction SM13.

    You must insure that work areas/buffered data are cleared between each call in your code and no concurrent lock. You can either use the WAIT option of the commit or (for better performance and safety) execute BAPI_SALESORDER_CREATEFROMDAT2 and BAPI_TRANSACTION_COMMIT/ROLLBACK commit with DESTINATION NONE followed by an explicit call of RFC_CONNECTION_CLOSE.

    Add comment
    10|10000 characters needed characters exceeded

  • Feb 06 at 07:20 AM

    Hi,

    Try, Clear the variable& internal table used in bapi before appending new record.

    Regards,

    venkat.

    Add comment
    10|10000 characters needed characters exceeded