viernes, 6 de junio de 2014

Programa de Carga de Datos Maestros [General]

Si bien existen muchas formas de generar este tipo de programas, considero que esta es la forma más simple de hacerlo.
Además que considera tanto archivos Txt como Excel
Este posee las siguientes opciones:
1.       Generar un juego de Datos .
2.       Ir a la SM35 para ejecutar el Juego de datos generado .
3.       Ejecutar en modo DirectInput.
4.       Y ver log de la ejecucion DirectInput.
*&---------------------------------------------------------------------*
REPORT zhrint0005 MESSAGE-ID sy.
TYPE-POOLS slis.

*----------------------------------------------------------------------*
*Componentes de ALV                                                    *
*----------------------------------------------------------------------*
TYPE-POOLS: slis.
CONSTANTS:
  c_fm_top_of_page  TYPE slis_formname VALUE 'TOP_OF_PAGE', "#EC NEEDED
  c_fm_list_modify  TYPE slis_formname VALUE 'LIST_MODIFY', "#EC NEEDED
  c_fm_data_changed TYPE slis_formname VALUE 'DATA_CHANGED', "#EC NEEDED
  c_probclass_very_high TYPE bal_s_msg-probclass VALUE '1', "#EC NEEDED
  c_probclass_high      TYPE bal_s_msg-probclass VALUE '2', "#EC NEEDED
  c_probclass_medium    TYPE bal_s_msg-probclass VALUE '3', "#EC NEEDED
  c_probclass_low       TYPE bal_s_msg-probclass VALUE '4', "#EC NEEDED
  c_probclass_none      TYPE bal_s_msg-probclass VALUE ' ', "#EC NEEDED
  c_group               LIKE  apqi-groupid VALUE 'BI_0022'. "#EC NEEDED
* ALV
DATA: v_fieldtab     TYPE slis_t_fieldcat_alv.              "#EC NEEDED
DATA: v_sortinfo     TYPE slis_t_sortinfo_alv. "Sort Table  "#EC NEEDED
DATA: v_sp_group     TYPE slis_t_sp_group_alv. "List Groups "#EC NEEDED
DATA: v_alv_keyinfo  TYPE slis_keyinfo_alv.                 "#EC NEEDED
DATA: v_alv_layout   TYPE slis_layout_alv.                  "#EC NEEDED
DATA: v_alv_print    TYPE slis_print_alv.                   "#EC NEEDED
DATA: v_alv_repid    LIKE sy-repid.                         "#EC NEEDED
DATA: v_events       TYPE slis_t_event.                     "#EC NEEDED
DATA: v_heading      TYPE slis_t_listheader.                "#EC NEEDED
DATA: v_layout       TYPE slis_layout_alv.                  "#EC NEEDED
DATA: v_alv_variant  TYPE disvariant.                       "#EC NEEDED
DATA: v_repname      LIKE sy-repid.                         "#EC NEEDED
DATA: v_alv_colourize_fields   LIKE  mmim_rep_print-color.  "#EC NEEDED
DATA: v_alv_detail_func(30).                                "#EC NEEDED
*----------------------------------------------------------------------*
* Definición de variables publicas para validacion de botones
*----------------------------------------------------------------------*
DATA: BEGIN OF i_tab OCCURS 100,                            "#EC NEEDED
      sw(1) ,     "valor switch 1
      sw2(1) ,    "valor switch 2
END OF i_tab.
*----------------------------------------------------------------------*
TYPES: BEGIN OF i_line,
      linea TYPE so_text255,
END OF i_line.

TYPES :
BEGIN OF e_pa,            "Tipo  L  D Descripción
  pernr LIKE p0022-pernr, "NUMC  8  0 Número de personal
  subty LIKE p0022-subty, "CHAR  4  0 Subtipo
  begda LIKE p0022-begda, "DATS  8  0 Inicio de la validez
  endda LIKE p0022-endda, "DATS  8  0 Fin de la validez
  sland LIKE p0022-sland, "CHAR  3  0 Clave de país
  slart LIKE p0022-slart, "CHAR  2  0 Clase de instituto de enseñanza
  insti LIKE Q0022-INSTI, "CHAR 80  0 Instit./Lugar de formación
  sltp1 LIKE p0022-sltp1, "NUMC  5  0 Especialidad
  slabs LIKE p0022-slabs, "CHAR  2  0 Título
  anzkl LIKE p0022-anzkl, "DEC   3  0 Duración de la formación
  anzeh LIKE q0022-anzeh, "CHAR 20  0 Texto de unidades tiempo/medida
END OF e_pa.
*
DATA: BEGIN OF i_output_list OCCURS 0,
  cmak(1) TYPE c,"ALV
  pernr LIKE p0022-pernr, "NUMC  8  0 Número de personal
  subty LIKE p0022-subty, "CHAR  4  0 Subtipo
  begda LIKE p0022-begda, "DATS  8  0 Inicio de la validez
  endda LIKE p0022-endda, "DATS  8  0 Fin de la validez
  sland LIKE p0022-sland, "CHAR  3  0 Clave de país
  slart LIKE p0022-slart, "CHAR  2  0 Clase de instituto de enseñanza
  insti LIKE Q0022-INSTI, "CHAR 80  0 Instit./Lugar de formación
  sltp1 LIKE p0022-sltp1, "NUMC  5  0 Especialidad
  slabs LIKE p0022-slabs, "CHAR  2  0 Título
  anzkl LIKE p0022-anzkl, "DEC   3  0 Duración de la formación
  anzeh LIKE q0022-anzeh, "CHAR 20  0 Texto de unidades tiempo/medida
 END OF i_output_list.
* tabla ALV
DATA: i_file TYPE e_pa OCCURS 0 WITH HEADER LINE.
DATA: v_filename TYPE string.
DATA: i_data_tab TYPE i_line OCCURS 0 WITH HEADER LINE.     "#EC NEEDED
* LOG
DATA: log        TYPE bal_s_log,
      log_handle TYPE balloghndl.
DATA: dummy TYPE c.                                         "#EC NEEDED
DATA: BEGIN OF message OCCURS 0.
DATA:   pernr LIKE pernr-pernr.
        INCLUDE STRUCTURE bdcmsgcoll.
DATA:   mensaje(80) TYPE c.
DATA: END   OF message.

DATA : BEGIN OF tab_mensajes OCCURS 0.
        INCLUDE STRUCTURE bdcmsgcoll .
DATA : pernr(10) TYPE c.
DATA : END OF tab_mensajes.
*----------------------------------------------------------------------*
*   data definition para el batch input
*----------------------------------------------------------------------*
*     Batchinputdata of single transaction
DATA: BEGIN OF bdcdata OCCURS 0.
        INCLUDE STRUCTURE bdcdata.
DATA: END OF bdcdata.

DATA: v_nodata(1) VALUE ' '."# '/'. "LOWER CASE
DATA: v_smalllog(1).        "# ' '. "log all transactions
DATA: v_holddate TYPE d.
*
INCLUDE zhrincufile."Include Exclusivo para Programa de Carga
*---------------------------------------------------------------------*
*Definicion de Pantalla Inicial
*---------------------------------------------------------------------*
*PARAMETERS: p_file TYPE localfile
*           DEFAULT 'C:\TextoDelimitadoTab.txt'.
*---------------------------------------------------------------------*
*initialization.
*---------------------------------------------------------------------*
INITIALIZATION.
*---------------------------------------------------------------------*
* selection-screen
*---------------------------------------------------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
    EXPORTING
      static    = 'X'
    CHANGING
      file_name = p_file.
*---------------------------------------------------------------------*
*START-OF-SELECTION.
*---------------------------------------------------------------------*
START-OF-SELECTION.
  IF NOT ( p_file IS INITIAL ).
    v_filename = p_file.
    PERFORM load_file_to."#Por Include
    PERFORM load_file.
    PERFORM muestra_alv.
  ENDIF.
*----------------------------------------------------------------------*
*END-OF-SELECTION. after Close BDL
*----------------------------------------------------------------------*
END-OF-SELECTION.
*
*=====================================================================*
* FORMS                                                               *
*=====================================================================*
FORM load_file.
  DATA: lt_tab TYPE TABLE OF string.
  IF ( r_xls EQ 'X' ).
    LOOP AT i_planilla.
      AT NEW row.
        CLEAR i_output_list.
      ENDAT.
      CASE i_planilla-col.
        WHEN 01. i_output_list-pernr = i_planilla-value.
        WHEN 02. i_output_list-subty = i_planilla-value.
        WHEN 03. i_output_list-begda = i_planilla-value.
        WHEN 04. i_output_list-endda = i_planilla-value.
        WHEN 05. i_output_list-sland = i_planilla-value.
        WHEN 06. i_output_list-slart = i_planilla-value.
        WHEN 07. i_output_list-insti = i_planilla-value.
        WHEN 08. i_output_list-sltp1 = i_planilla-value.
        WHEN 09. i_output_list-slabs = i_planilla-value.
        WHEN 10. i_output_list-anzkl = i_planilla-value.
        WHEN 11. i_output_list-anzeh = i_planilla-value.
        WHEN OTHERS.
      ENDCASE.
      AT END OF row.
        APPEND i_output_list.
      ENDAT.
    ENDLOOP.
  ENDIF.
  IF ( r_csv EQ 'X' ).
    LOOP AT i_upload.
      IF ( p_char EQ 'T' ).
        SPLIT i_upload-linea AT c_tab INTO: TABLE lt_tab.
      ELSE.
        SPLIT i_upload-linea AT p_char INTO: TABLE lt_tab.
      ENDIF.
      READ TABLE lt_tab INDEX 01 INTO i_output_list-pernr.
      READ TABLE lt_tab INDEX 02 INTO i_output_list-subty.
      READ TABLE lt_tab INDEX 03 INTO i_output_list-begda.
      READ TABLE lt_tab INDEX 04 INTO i_output_list-endda.
      READ TABLE lt_tab INDEX 05 INTO i_output_list-sland.
      READ TABLE lt_tab INDEX 06 INTO i_output_list-slart.
      READ TABLE lt_tab INDEX 07 INTO i_output_list-insti.
      READ TABLE lt_tab INDEX 08 INTO i_output_list-sltp1.
      READ TABLE lt_tab INDEX 09 INTO i_output_list-slabs.
      READ TABLE lt_tab INDEX 10 INTO i_output_list-anzkl.
      READ TABLE lt_tab INDEX 11 INTO i_output_list-anzeh.
      APPEND i_output_list.
    ENDLOOP.
  ENDIF.
ENDFORM.                    "load_file
*=====================================================================*
* ALV                                                                 *
*=====================================================================*
FORM muestra_alv.
  DESCRIBE TABLE i_output_list LINES sy-tfill.
  PERFORM alv_init.
  IF ( sy-tfill > 0 ).
    PERFORM initialize_fieldcat USING v_fieldtab[].
    PERFORM ordenamiento        USING v_sortinfo[].
    PERFORM build_eventtab      USING v_events[].
    PERFORM build_comment       USING v_heading[].
    PERFORM build_layout        USING v_layout.
    PERFORM write_output.
  ELSE.
    MESSAGE i499 WITH text-001.
  ENDIF.
ENDFORM.                    "Muestra_Resultados
*&---------------------------------------------------------------------*
FORM alv_init.
  DATA : l_s_mmim_rep_print  TYPE  mmim_rep_print.
  CLEAR: v_alv_keyinfo, v_alv_variant, v_alv_layout, v_alv_print.
  v_alv_repid = sy-repid.
  CLEAR v_alv_variant.
  v_alv_variant-report           = v_alv_repid.
* Printing settings
  v_alv_layout-get_selinfos      = 'X'.
  v_alv_layout-group_change_edit = 'X'.

  SELECT SINGLE *
    FROM mmim_rep_print
    INTO l_s_mmim_rep_print
   WHERE report = sy-repid.

  IF ( sy-subrc = 0 ).
    IF ( l_s_mmim_rep_print-selinfo EQ 'X' ).
      v_alv_print-no_print_selinfos = ' '.
    ELSE.
      v_alv_print-no_print_selinfos = 'X'.
    ENDIF.
*
    IF ( l_s_mmim_rep_print-coverpage EQ 'X' ).
      v_alv_print-no_coverpage = ' '.
    ELSE.
      v_alv_print-no_coverpage = 'X'.
    ENDIF.
*
    IF ( l_s_mmim_rep_print-listinfo EQ 'X' ).
      v_alv_print-no_print_listinfos = ' '.
    ELSE.
      v_alv_print-no_print_listinfos = 'X'.
    ENDIF.
*
    IF ( l_s_mmim_rep_print-gridcontrol EQ 'X' ).
      v_alv_detail_func = 'REUSE_ALV_GRID_DISPLAY'.
    ELSE.
      v_alv_detail_func = 'REUSE_ALV_LIST_DISPLAY'.
    ENDIF.
*   consider customizing settings regarding the
*   colourization of numeric fields
    IF ( l_s_mmim_rep_print-color EQ 'X' ).
*     the customizing says : use no colors
      CLEAR v_alv_colourize_fields.
    ELSE.
*     no restrictions -> work with colours
      MOVE  'X' TO v_alv_colourize_fields.
    ENDIF.
  ELSE.
*   MMIM_REP_PRINT entry missing / work with colours
    MOVE  'X' TO v_alv_colourize_fields.
    v_alv_print-no_print_selinfos  = 'X'.
    v_alv_print-no_coverpage       = ' '.
    v_alv_print-no_print_listinfos = 'X'.
    v_alv_detail_func = 'REUSE_ALV_LIST_DISPLAY'.
  ENDIF.
*
ENDFORM.                    "alv_init
*&---------------------------------------------------------------------*
FORM initialize_fieldcat USING p_fieldtab TYPE slis_t_fieldcat_alv.
  DATA: li_fieldtab TYPE slis_t_fieldcat_alv.
  DATA: wa_fieldtab TYPE LINE OF slis_t_fieldcat_alv.
  v_repname = sy-repid.
  FREE: li_fieldtab,  wa_fieldtab.
*
  CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
    EXPORTING
      i_program_name         = sy-repid
      i_internal_tabname     = 'I_OUTPUT_LIST'
      i_inclname             = sy-repid
    CHANGING
      ct_fieldcat            = li_fieldtab
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 2
      OTHERS                 = 3.
  IF ( sy-subrc NE 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ELSE.
    LOOP AT li_fieldtab INTO wa_fieldtab.
      CASE wa_fieldtab-fieldname.
        WHEN 'CMAK'.
          wa_fieldtab-no_out = 'X'.
          APPEND wa_fieldtab TO p_fieldtab.
        WHEN OTHERS.
          APPEND wa_fieldtab TO p_fieldtab.
      ENDCASE.
    ENDLOOP.
  ENDIF.
*
ENDFORM.                    "initialize_fieldcat
*&---------------------------------------------------------------------*
FORM ordenamiento  USING sortinfo TYPE slis_t_sortinfo_alv.
  DATA : ls_sort TYPE slis_sortinfo_alv.
  CLEAR ls_sort.
  ls_sort-fieldname   = 'PERNR'.
  ls_sort-up          = 'X'.
  ls_sort-group       = '0'.
  APPEND ls_sort TO sortinfo.
*
ENDFORM.                    "ordenamiento
*&---------------------------------------------------------------------*
FORM build_eventtab USING p_events TYPE slis_t_event.
  DATA: ls_event TYPE slis_alv_event.
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
      i_list_type = 0
    IMPORTING
      et_events   = p_events.
  READ TABLE p_events WITH KEY name = slis_ev_top_of_page
                          INTO ls_event.
  IF ( sy-subrc = 0 ).
    MOVE c_fm_top_of_page TO ls_event-form.
    APPEND ls_event TO p_events.
  ENDIF.
ENDFORM.                    "build_eventtab
*&---------------------------------------------------------------------*
FORM build_comment USING  p_heading TYPE slis_t_listheader.
  DATA: hline TYPE slis_listheader.
  CLEAR p_heading. REFRESH p_heading.
*Cabecera
  hline-typ = 'H'.
  hline-info = text-t01.
  APPEND hline TO p_heading.

  hline-typ = 'S'.
  hline-key  = 'Infotipo'. "text-t02.
  hline-info = '0022'.
  APPEND hline TO p_heading.
*
*  hline-key = text-t04.
*  hline-info .
*  append hline to p_heading.

ENDFORM.                    "build_comment
*&---------------------------------------------------------------------*
FORM build_layout USING p_layout TYPE slis_layout_alv.
*  p_layout-f2code        = f2code.
  p_layout-zebra         = 'X'.
  p_layout-box_fieldname = 'CMAK'."Campo de Marcage
  p_layout-box_tabname   = 'i_output_list'.
ENDFORM.                    "build_layout
*&---------------------------------------------------------------------*
FORM write_output.
  DATA: agrupa_alv TYPE slis_sortinfo_alv OCCURS 5 WITH HEADER LINE.
                                                            "#EC NEEDED

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_background_id          = ''
      i_interface_check        = ''"'X'
      i_callback_program       = v_repname
      i_callback_pf_status_set = 'SET_PF_STATUS'
      i_callback_user_command  = 'USER_COMMAND'
      i_callback_top_of_page   = 'TOP_OF_PAGE'
      i_structure_name         = 'I_OUTPUT_LIST'
      is_layout                = v_layout
      it_fieldcat              = v_fieldtab
      it_special_groups        = v_sp_group[]
      i_save                   = 'A'
      i_default                = 'X'
      it_sort                  = v_sortinfo
      it_events                = v_events[]
      is_variant               = v_alv_variant
    TABLES
      t_outtab                 = i_output_list
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
    WRITE: 'SY-SUBRC: ', sy-subrc, 'REUSE_ALV_LIST_DISPLAY'.
  ENDIF.
ENDFORM.                    "write_output
*&---------------------------------------------------------------------*
FORM user_command USING r_ucomm LIKE sy-ucomm               "#EC CALLED
                        rs_selfield TYPE slis_selfield.     "#EC CALLED
*Batch  input table
  DATA: BEGIN OF bdcdata OCCURS 0.                          "#EC NEEDED
          INCLUDE STRUCTURE bdcdata.                        "#EC NEEDED
  DATA: END OF bdcdata.                                     "#EC NEEDED
*
  CASE r_ucomm.
    WHEN 'GEN'.
      PERFORM crear_juego_datos USING r_ucomm.
    WHEN 'SM35'.
      IF ( i_tab-sw2  EQ 2 ).
        CALL TRANSACTION 'SM35' AND SKIP FIRST SCREEN.
      ELSE.
        MESSAGE i499 WITH  text-001.
      ENDIF.
    WHEN 'DIMP'. " Hace el direct input
      PERFORM crear_juego_datos USING r_ucomm.
    WHEN 'LOG'.
      PERFORM create_log.
      LOOP AT message.
        IF ( message-msgtyp EQ 'S' ).
          MESSAGE e499
             WITH message-pernr message-mensaje(42)
                                message-mensaje+42(38)
             INTO dummy.
          PERFORM add_message USING c_probclass_low.
        ENDIF.
        IF ( message-msgtyp EQ 'W' ).
          MESSAGE e499
             WITH message-pernr message-mensaje(42)
                                message-mensaje+42(38)
             INTO dummy.
          PERFORM add_message USING c_probclass_medium.
        ENDIF.
        IF ( message-msgtyp EQ 'E' ).
          MESSAGE e499
             WITH message-pernr message-mensaje(42)
                                message-mensaje+42(38)
             INTO dummy.
          PERFORM add_message USING c_probclass_high.
        ENDIF.
      ENDLOOP.
      PERFORM save_log.
      PERFORM display_log.
      PERFORM delete_log.
  ENDCASE.
  CLEAR: r_ucomm.
ENDFORM.                    "user_command
*&---------------------------------------------------------------------*
FORM set_pf_status USING rt_extab TYPE slis_t_extab.        "#EC CALLED
  SET PF-STATUS 'D1000_STATUS'.
ENDFORM.                    "set_pf_status
*&---------------------------------------------------------------------*
FORM top_of_page.                                           "#EC CALLED
  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      it_list_commentary = v_heading.
ENDFORM.                    "top_of_page
*&---------------------------------------------------------------------*
FORM crear_juego_datos USING p_tip.
* DATA: l_datum TYPE datum.
  DATA: l_datum(8) TYPE c.
  IF ( p_tip = 'GEN' ).
    PERFORM open_group USING c_group.
  ENDIF.
* Ordena y borra duplicados
  SORT i_output_list.
  DELETE ADJACENT DUPLICATES FROM i_output_list.
  LOOP AT i_output_list.
*
    IF NOT ( i_output_list IS INITIAL ).
      REFRESH bdcdata.
* Armado de Juego de datos
*......Template
*      PERFORM bdc_dynpro USING '' ''.
*      PERFORM bdc_field  USING '' ''.
*......Pantalla inicial PA30
      PERFORM bdc_dynpro USING 'SAPMP50A'    '1000'.
      PERFORM bdc_field  USING 'BDC_OKCODE'  '=INS'.
      PERFORM bdc_field  USING 'RP50G-PERNR' i_output_list-pernr.
      PERFORM bdc_field  USING 'RP50G-TIMR6' 'X'.
      PERFORM bdc_field  USING 'BDC_CURSOR'   'RP50G-CHOIC'.
      PERFORM bdc_field  USING 'RP50G-CHOIC' '0022'.
      PERFORM bdc_field  USING 'RP50G-SUBTY' i_output_list-subty.
*......Pantalla I Infotipo
      PERFORM bdc_dynpro USING 'MP002200' '2022'.
      PERFORM bdc_field  USING 'BDC_OKCODE'  '=UPD'.
      PERFORM conv_fech  USING i_output_list-begda l_datum.
      PERFORM bdc_field  USING 'P0022-BEGDA' l_datum.
      PERFORM conv_fech  USING i_output_list-endda l_datum.
      PERFORM bdc_field  USING 'P0022-ENDDA' l_datum.
      PERFORM bdc_field  USING 'P0022-SLAND' i_output_list-sland.
      PERFORM bdc_field  USING 'P0022-SLART' i_output_list-slart.
      PERFORM bdc_field  USING 'Q0022-INSTI' i_output_list-insti.
      PERFORM bdc_field  USING 'P0022-SLTP1' i_output_list-sltp1.
      PERFORM bdc_field  USING 'P0022-SLABS' i_output_list-slabs.
      PERFORM bdc_field  USING 'P0022-ANZKL' i_output_list-anzkl.
      PERFORM bdc_field  USING 'Q0022-ANZEH' i_output_list-anzeh.
*......Fin set de datos
      IF ( p_tip = 'GEN' ).
        PERFORM bdc_transaction USING 'PA30'.
      ELSE.
        FREE tab_mensajes.
        CALL TRANSACTION 'PA30' USING bdcdata
                                MODE   'A' "A PARA VISUAL
                                UPDATE 'S'
                                MESSAGES INTO tab_mensajes.
*
        LOOP AT tab_mensajes.
          MOVE-CORRESPONDING tab_mensajes TO message.
          message-pernr = i_output_list-pernr.
*
          PERFORM message_transform USING message-msgspra message-msgid
                                          message-msgnr  message-msgtyp
                                          message-msgv1   message-msgv2
                                          message-msgv3   message-msgv4
                                 CHANGING message-mensaje.
          APPEND message.
          CLEAR: message.
        ENDLOOP.
      ENDIF.
    ENDIF.
  ENDLOOP.

*¨Si es batch input cierro el juego de datos
  IF ( p_tip = 'GEN' ).
    PERFORM close_group.
    MESSAGE s499 WITH
    'Juego de Datos Generado Nombre :[' c_group '].'.
  ENDIF.
  i_tab-sw = 2.
  i_tab-sw2 = 2.

ENDFORM.                    "crear_Juego_datos
*----------------------------------------------------------------------*
FORM open_group USING group.
  SKIP.
  WRITE: /(20) 'Create group'(i01), group.
  SKIP.
* open batchinput group
  CALL FUNCTION 'BDC_OPEN_GROUP'
    EXPORTING
      client   = sy-mandt
      group    = group
      user     = sy-uname
      keep     = ' ' "keep
      holddate = v_holddate.
  WRITE: /(30) 'BDC_OPEN_GROUP'(i02),
          (12) 'returncode:'(i05),
               sy-subrc.
ENDFORM.                    "OPEN_GROUP
*----------------------------------------------------------------------*
FORM close_group. "Close batchinput group
  CALL FUNCTION 'BDC_CLOSE_GROUP'.
  WRITE: /(30) 'BDC_CLOSE_GROUP'(i04),
          (12) 'returncode:'(i05),
               sy-subrc.
ENDFORM.                    "CLOSE_GROUP
*&---------------------------------------------------------------------*
FORM create_log .
*  log-object     = text-l01.
*  log-subobject  = text-l02.
*  log-extnumber  = text-l03.
  log-aluser     = sy-uname.
  log-alprog     = sy-repid.
  log-aldate     = sy-datum.
  log-altime     = sy-uzeit.
  log-aluser     = sy-uname.
  log-altcode    = sy-tcode.
  log-aldate_del = sy-datum + 25.
*
  CALL FUNCTION 'BAL_LOG_CREATE'
    EXPORTING
      i_s_log      = log
    IMPORTING
      e_log_handle = log_handle
    EXCEPTIONS
      OTHERS       = 1.
  IF ( sy-subrc <> 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
          WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    "create_log
*&---------------------------------------------------------------------*
FORM add_message  USING    p_probclass.
  DATA: messages TYPE bal_s_msg.

  IF ( p_probclass NE 4 ).
    messages-msgty     = sy-msgty.
  ELSE.
    messages-msgty     = 'S'.
  ENDIF.
*
  messages-msgid     = sy-msgid.
  messages-msgno     = sy-msgno.
  messages-msgv1     = sy-msgv1.
  messages-msgv2     = sy-msgv2.
  messages-msgv3     = sy-msgv3.
  messages-msgv4     = sy-msgv4.
  messages-probclass = p_probclass.
*
  CALL FUNCTION 'BAL_LOG_MSG_ADD'
    EXPORTING
      i_log_handle  = log_handle
      i_s_msg       = messages
    EXCEPTIONS
      log_not_found = 0
      OTHERS        = 1.
  IF ( sy-subrc <> 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    "add_message
*&---------------------------------------------------------------------*
FORM save_log .
  DATA: ti_log_handle TYPE bal_t_logh,
        te_log_handle TYPE balloghndl.

  CLEAR: te_log_handle.
  REFRESH: ti_log_handle.

  te_log_handle = log_handle.
  APPEND te_log_handle TO ti_log_handle.

  CALL FUNCTION 'BAL_DB_SAVE'
    EXPORTING
      i_save_all       = 'X'
      i_t_log_handle   = ti_log_handle
    EXCEPTIONS
      log_not_found    = 1
      save_not_allowed = 2
      numbering_error  = 3
      OTHERS           = 4.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

ENDFORM.                    "save_log
*&---------------------------------------------------------------------*
FORM display_log .
  DATA: ti_log_handle TYPE bal_t_logh,
        te_log_handle TYPE balloghndl.
  CLEAR:   te_log_handle.
  REFRESH: ti_log_handle.

  te_log_handle = log_handle.
  APPEND te_log_handle TO ti_log_handle.

  CALL FUNCTION 'BAL_DSP_LOG_DISPLAY'
    EXPORTING
      i_t_log_handle       = ti_log_handle
    EXCEPTIONS
      profile_inconsistent = 1
      internal_error       = 2
      no_data_available    = 3
      no_authority         = 4
      OTHERS               = 5.
  IF ( sy-subrc <> 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*
ENDFORM.                    "display_log
*&---------------------------------------------------------------------*
FORM delete_log.
  CALL FUNCTION 'BAL_LOG_MSG_DELETE_ALL'
    EXPORTING
      i_log_handle  = log_handle
    EXCEPTIONS
      log_not_found = 1
      OTHERS        = 2.
  IF ( sy-subrc <> 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
*
  CALL FUNCTION 'BAL_LOG_DELETE'
    EXPORTING
      i_log_handle  = log_handle
    EXCEPTIONS
      log_not_found = 1
      OTHERS        = 2.
  IF ( sy-subrc <> 0 ).
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    "delete_log
*---------------------------------------------------------------------*
FORM message_transform USING    p_par_langu
                                p_par_msgid
                                p_par_msgno
                                p_par_msgty
                                p_par_msgv1
                                p_par_msgv2
                                p_par_msgv3
                                p_par_msgv4
                       CHANGING p_mensaje.
  DATA: l_msgnr LIKE sy-msgno,
        l_msgv1 LIKE sy-msgv1,
        l_msgv2 LIKE sy-msgv2,
        l_msgv3 LIKE sy-msgv3,
        l_msgv4 LIKE sy-msgv4.


  l_msgnr = p_par_msgno.
  l_msgv1 = p_par_msgv1.
  l_msgv2 = p_par_msgv2.
  l_msgv3 = p_par_msgv3.
  l_msgv4 = p_par_msgv4.

  CLEAR: p_mensaje.

  CALL FUNCTION 'K_MESSAGE_TRANSFORM'
    EXPORTING
      par_langu         = p_par_langu
      par_msgid         = p_par_msgid
      par_msgno         = l_msgnr
      par_msgty         = p_par_msgty
      par_msgv1         = l_msgv1
      par_msgv2         = l_msgv2
      par_msgv3         = l_msgv3
      par_msgv4         = l_msgv4
    IMPORTING
      par_msgtx         = p_mensaje
    EXCEPTIONS
      no_message_found  = 1
      par_msgid_missing = 2
      par_msgno_missing = 3
      par_msgty_missing = 4
      OTHERS            = 5.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.                               " MESSAGE_TRANSFORM
*----------------------------------------------------------------------*
FORM bdc_transaction USING tcode.
  CALL FUNCTION 'BDC_INSERT'
    EXPORTING
      tcode     = tcode
    TABLES
      dynprotab = bdcdata.
  IF ( v_smalllog <> 'X' ).
    WRITE: /(25) 'BDC_INSERT'(i03),
                 tcode,
            (12) 'returncode:'(i05),
                 sy-subrc,
                 'RECORD:',
                 sy-index.
  ENDIF.
  REFRESH bdcdata.
ENDFORM.                    "bdc_transaction
*----------------------------------------------------------------------*
FORM bdc_dynpro USING program dynpro.                       "#EC CALLED
  CLEAR bdcdata.
  bdcdata-program  = program.
  bdcdata-dynpro   = dynpro.
  bdcdata-dynbegin = 'X'.
  APPEND bdcdata.
ENDFORM.                    "bdc_dynpro
*----------------------------------------------------------------------*
FORM bdc_field USING fnam fval.                             "#EC CALLED
  IF ( fval <> v_nodata ).
    CLEAR bdcdata.
    bdcdata-fnam = fnam.
    bdcdata-fval = fval.
    CONDENSE bdcdata-fval.
    APPEND bdcdata.
  ENDIF.
ENDFORM.                    "bdc_field
*----------------------------------------------------------------------*
FORM conv_fech USING p_fecha o_datum.
  CLEAR o_datum.
  CHECK p_fecha IS NOT INITIAL.
  o_datum+0(2) = p_fecha+6(2).
  o_datum+2(2) = p_fecha+4(2).
  o_datum+4(4) = p_fecha+0(4).
ENDFORM.                    "conv_fecha
  

Include Reutilizable
*&---------------------------------------------------------------------*
*&  Include           ZHRINCUFILE
*&---------------------------------------------------------------------*
CONSTANTS:
  c_tab TYPE c VALUE cl_abap_char_utilities=>horizontal_tab.
*Declaración de Estructuras y Variables para Leer Texto Plano
DATA: BEGIN OF i_upload OCCURS 0,
         linea TYPE string,
      END OF i_upload.
* Estructura para las cabeceras desde Archivo Plano
DATA: BEGIN OF i_upload_header OCCURS 0,
         linea TYPE string,
      END OF i_upload_header.
DATA: lv_file TYPE string.
* Declaración de Estructuras y Variables para Leer Archivo Excel
DATA: i_planilla        LIKE alsmex_tabline OCCURS 0 WITH HEADER LINE.
* Estructura para las cabeceras al leer desde Excel
DATA: i_planilla_header LIKE alsmex_tabline OCCURS 0 WITH HEADER LINE.

*---------------------------------------------------------------------*
*Definicion de Pantalla Inicial
*---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-b01.
PARAMETERS: p_file LIKE rlgrap-filename ."Archivo de Carga
SELECTION-SCREEN SKIP.
* Radio que indica que se cargará desde un Excel
PARAMETER: r_xls RADIOBUTTON GROUP grp1 MODIF ID xls
                 USER-COMMAND uc1 DEFAULT 'X'.
* Parametros para carga de Archivo Excel
PARAMETERS:
p_lin_i(4) TYPE n   DEFAULT 2     MODIF ID xl1,   "Fila de Inico
p_lin_f(4) TYPE n   DEFAULT 9999  MODIF ID xl1,   "Fila de Fin
p_col_i(2) TYPE c   DEFAULT 'A'   MODIF ID xl1,   "Columna de Inicio
p_col_f(2) TYPE c   DEFAULT 'Z'   MODIF ID xl1.   "Columna de Fin

SELECTION-SCREEN SKIP.
* Radio que indica que se cargará desde Texto Plano
PARAMETERS: r_csv RADIOBUTTON GROUP grp1 MODIF ID csv.
* Caracter de separación Utilizado
PARAMETERS: p_char    TYPE c DEFAULT ';' MODIF ID cs1.
* Fila en la que comienzan los registros en el Archivo Plano
PARAMETERS: p_fil_i(4) TYPE n DEFAULT '2' MODIF ID cs1.
SELECTION-SCREEN END OF BLOCK b1.
* HABILITAR Y DESHABILITAAR PARAMETROS DE PANTALLA
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    IF ( r_xls EQ 'X' ).
      CASE screen-group1.
        WHEN 'CS1'.
          screen-input = '0'.
        WHEN 'XL1'.
          screen-input = '1'.
        WHEN OTHERS.
      ENDCASE.
      MODIFY SCREEN.
    ELSE.
      CASE screen-group1.
        WHEN 'CS1'.
          screen-input = '1'.
        WHEN 'XL1'.
          screen-input = '0'.
        WHEN OTHERS.
      ENDCASE.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.
*======================================================================*
* FORMS                                                                *
*======================================================================*
FORM load_file_to.
  IF ( r_xls EQ 'X' ).
    PERFORM load_xls.
  ENDIF.
  IF ( r_csv EQ 'X' ).
    PERFORM load_csv.
  ENDIF.
ENDFORM.                    "Load_file_to
*----------------------------------------------------------------------*

*----------------------------------------------------------------------*
FORM load_xls.
  DATA:  begin_col(4) TYPE i,
         begin_row    TYPE i,
         end_col(4)   TYPE i,
         end_row      TYPE i,
         lv_tabix       TYPE sy-tabix..

  FREE  i_planilla.
  CLEAR i_planilla.
  CLEAR lv_tabix.

  CLEAR   i_planilla.
  FREE i_planilla.
  DATA abc TYPE string VALUE '_ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
  DATA factor TYPE i.

*  Transforma las letras a Números para Columna de Inicio.
  IF ( strlen( p_col_i ) = 1 ).
    SEARCH abc FOR p_col_i.
    begin_col = sy-fdpos.
  ELSEIF ( strlen( p_col_i ) = 2 ).
    SEARCH abc FOR p_col_i(1).
    factor = sy-fdpos.
    SEARCH abc FOR p_col_i+1.
    begin_col = sy-fdpos + ( factor * 26 ).
  ENDIF.
*  Transforma las letras a Números para Columna de Fin.
  IF ( strlen( p_col_f ) = 1 ).
    SEARCH abc FOR p_col_f.
    end_col = sy-fdpos.
  ELSEIF ( strlen( p_col_f ) = 2 ).
    SEARCH abc FOR p_col_f(1).
    factor = sy-fdpos.
    SEARCH abc FOR p_col_f+1.
    end_col = sy-fdpos + ( factor * 26 ).
  ENDIF.

  begin_row = 1.
  end_row   = p_lin_f.

*  Lee el archivo Excel y guarda el Contenido en una Tabla Interna
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = p_file
      i_begin_col             = begin_col
      i_begin_row             = begin_row
      i_end_col               = end_col
      i_end_row               = end_row
    TABLES
      intern                  = i_planilla
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.

  IF sy-subrc <> 0.
    MESSAGE 'No se ha podido leer la Planilla de Carga' TYPE 'E'.
    STOP.
  ELSE.
*---Mueve los Registros previos al inicio de los datos a la tabla de
*   cabecera
    LOOP AT i_planilla.
      IF ( i_planilla-row < p_lin_i ).
        APPEND i_planilla TO i_planilla_header.
        DELETE i_planilla INDEX 1.
      ELSE.
        EXIT.
      ENDIF.
    ENDLOOP.
    SORT i_planilla         BY row col ASCENDING.
    SORT i_planilla_header  BY row col ASCENDING.
  ENDIF.
ENDFORM.                    "carga_xls
*----------------------------------------------------------------------*
FORM load_csv .
  DATA lv_tabix       TYPE sy-tabix.
  FREE i_upload.
  FREE i_upload_header.
  CLEAR lv_tabix.
  DATA v_subrc TYPE sy-subrc.
  MOVE p_file TO lv_file.
*
  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename                = lv_file
*     filetype                = 'ASC'"'DAT'
    TABLES
      data_tab                = i_upload
    EXCEPTIONS
      file_open_error         = 1
      file_read_error         = 2
      no_batch                = 3
      gui_refuse_filetransfer = 4
      invalid_type            = 5
      no_authority            = 6
      unknown_error           = 7
      bad_data_format         = 8
      header_not_allowed      = 9
      separator_not_allowed   = 10
      header_too_long         = 11
      unknown_dp_error        = 12
      access_denied           = 13
      dp_out_of_memory        = 14
      disk_full               = 15
      dp_timeout              = 16
      OTHERS                  = 17.

  IF ( sy-subrc <> 0 ).
    MESSAGE 'No se ha podido leer la Planilla de Carga' TYPE 'E'.
    STOP.
  ELSE.
*...Mueve los Registros previos al inicio de los datos a la tabla de
*   cabecera
    LOOP AT i_upload.
      ADD 1 TO lv_tabix.
      IF ( lv_tabix < p_fil_i ).
        APPEND i_upload TO i_upload_header.
        DELETE i_upload INDEX 1.
      ELSE.
        EXIT.
      ENDIF.

    ENDLOOP.
  ENDIF.
ENDFORM.                    " CARGA_CSV

Y como siempre les digo, si hay una forma más fácil me cuentan.
saludos.