I faced lately a small issue in one of the process in our company, I needed to re-explode the BOM of subcontracting item in purchase requisition. Normally users goes to ME52N and press "Explode BOM" button, but I needed to do this from ABAP side. 
 
I started with IF_PURCHASE_REQUISITION but although there is a method "explode_bom" for item, then it was calling the screen with the results instead of selecting and updating components in the database. IF_BOM_MM didn't helped as well.
 
I started to dig in the standard transactions and local classes of ME52N and finally I have figure out how to do this in backgroud. The solution was to run FM ME_COMPONENTS_MAINTAIN and ME_COMPONENTS_UPDATE_PREPARE in correct way together with message handler to not interrupt whole process.
Here you can find sample code how to re-explode purchase requisition BOM in few lines.
 

report zabexplprbom.


parametersp_banfn type eban-banfn,
                        p_bnfpo type eban-bnfpo default '00010'.


class lcl_subcontracting definition.
  public section.
    class-methodsexplode_pr_bom importing value(i_requsition)    type eban-banfn
                                      value(i_position)      type eban-bnfpo
                                      value(i_show_messagestype abap_bool default abap_false
                            returning value(r_re_exploded)   type abap_bool.

endclass.


start-of-selection.
  lcl_subcontracting=>explode_pr_bom(
      i_requsition    p_banfn
      i_position      p_bnfpo
      i_show_messages abap_true  ).

class lcl_subcontracting implementation.
  methodexplode_pr_bom.

    cl_message_handler_mm=>get_handler(  importing
                                         ex_handler data(message_handler).
    message_handler->co_handler_start).
    message_handler->set_config_for_bapi).

    call function 'ME_COMPONENTS_REFRESH'.
    dataebkn     type                   ebkn,
          eban     type                   eban,
          mdpa     type                   mdpa,
          mdlb     type                   mdlb,
          mdlb_tab type standard table of mdlb.

    select single into corresponding fields of eban
     from eban
           where  banfn  eq i_requsition
           and    bnfpo  eq i_position.
    select single from  ebkn into ebkn
            where  banfn  eq i_requsition
            and    bnfpo  eq i_position.

    call function 'ME_FILL_MDPA_FROM_EBAN'
      exporting
        im_eban eban
        im_ebkn ebkn
      importing
        ex_mdpa mdpa.

    call function 'ME_COMPONENTS_MAINTAIN'
      exporting
        i_ebeln    eban-banfn
        i_ebelp    eban-bnfpo
        i_fcall    abap_true
        i_mdpa     mdpa
        i_mdpa_old mdpa
        i_txz01    eban-txz01
        i_vorga    'M'.

    call function 'ME_FILL_MDLB_FROM_EBAN'
      exporting
        im_eban eban
        im_ebkn ebkn
      importing
        ex_mdlb mdlb.
    append mdlb to mdlb_tab.

    call function 'ME_COMPONENTS_UPDATE_PREPARE'
      exporting
        i_number eban-banfn
      tables
        t_mdlb   mdlb_tab.

    message_handler->co_handler_stop).
    data(messagesmessage_handler->get_list_for_bapi).
    if line_existsmessages[ msgid 'ME' msgno '638' ).
      r_re_exploded abap_true.
      commit work.
    endif.
    if i_show_messages eq abap_true.
      message_handler->showim_amodal abap_true ).
    endif.
  endmethod.

endclass.

Enjoy!