Inserta línea en un ALV OO

Colapsar
X
 
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • fenix28
    Member
    • may
    • 39

    #1

    Inserta línea en un ALV OO

    Hola a todos tengo un problemilla con un ALV que me trae ya de cabeza....

    Quiero poder insertar líneas en un ALV y poder borrarlas pero usando ALV OO,
    en principio el programa va a ser un Tabstrip con 4 pestañas y con un area que va a contener un ALV orientado a Objetos, he encontrado un programa de sap para ayudar a emprender un poco como va esto que es BCALV_EDIT_04.

    Pero no hay manera cuando inserto la línea "es una línea en blanco" me da un dump...

    Errores tiempo ejec. GETWA_NOT_ASSIGNED
    Fecha y hora 05.10.2009 13:01:17

    Texto breve
    Field symbol has not yet been assigned.

    ¿Qué ha sucedido?
    Error in the ABAP Application Program

    The current ABAP program "CL_GUI_ALV_GRID===============CP" had to be
    terminated because it has
    come across a statement that unfortunately cannot be executed.

    Mi código actualmente es el siguiente:


    *&---------------------------------------------------------------------*
    *& Report ZCAT_MANTENIMIENTO_MAESTRO
    *&
    *&---------------------------------------------------------------------*
    *&
    *&
    *&---------------------------------------------------------------------*
    report zcat_mantenimiento_maestro.

    * La tabla principal contendra todos los valores de todas las pestañas y
    * la tabla secundaria solo contendrá los valores de la pestaña que tiene que visualizar

    data: begin of g_zcat_maes_mat_principal occurs 0.
    include structure zcat_maes_mat.
    data: maktx like makt-maktx.
    data: end of g_zcat_maes_mat_principal.

    data: begin of g_zcat_maes_mat_auxiliar occurs 0.
    include structure zcat_maes_mat .
    data: maktx like makt-maktx.
    data: celltab type lvc_t_styl.
    data: end of g_zcat_maes_mat_auxiliar.

    data: flag_ejecutar_tab(5) type c value 'FALSE',
    flag_inicio(5) type c value 'FALSE',
    flag_1(5) type c value 'FALSE',
    number(4) type n value '2000',
    g_slide(8) type c,
    g_answer type c,
    g_flag_permiso(5) type c value 'TRUE'.

    controls: tabstrip type tabstrip.

    data: go_grid type ref to cl_gui_alv_grid, "ALV GRID
    go_custom_container type ref to cl_gui_custom_container, "Contenedor
    g_fieldcatalog type lvc_t_fcat, "Catálogo de campos
    l_layout type lvc_s_layo, "Layout
    l_exclude type ui_functions,
    lt_fcodes type ui_functions,
    g_et_index_rows type lvc_t_row,
    g_et_row_no type lvc_t_roid.

    **----------------------------------------------------------------------
    class lcl_event_handler definition.
    **----------------------------------------------------------------------
    public section.

    types: begin of stab_key.
    types: matnr type matnr.
    types: maktx type maktx.
    types: end of stab_key.

    types: stab_keys type standard table of stab_key,
    stab_table type standard table of zcat_maes_mat.

    methods: handle_data_changed for event data_changed of cl_gui_alv_grid importing er_data_changed,
    handle_after_user_command for event after_user_command of cl_gui_alv_grid importing e_ucomm,
    handle_user_command for event user_command of cl_gui_alv_grid importing e_ucomm,
    handle_before_user_command for event before_user_command of cl_gui_alv_grid importing e_ucomm,
    handle_menu_button for event menu_button of cl_gui_alv_grid importing e_object e_ucomm,
    handle_toolbar for event toolbar of cl_gui_alv_grid importing e_object e_interactive.

    methods: get_inserted_rows exporting inserted_rows type stab_keys,
    get_deleted_rows exporting deleted_rows type stab_table,
    refresh_delta_tables,
    set_table_is_initial,
    set_table_is_not_initial,
    table_is_initial returning value(initial) type char01.

    private section.

    data: inserted_rows type stab_keys,
    deleted_rows type standard table of zcat_maes_mat.

    * This flag is set if any error occured in one of the
    * following methods:
    data: error_in_data type c.

    * This flag signals that no records were read for the flight
    * table initially:
    data: initial_table type c.

    methods: check_double_entries importing pr_data_changed type ref to cl_alv_changed_data_protocol,
    update_delta_tables importing pr_data_changed type ref to cl_alv_changed_data_protocol,
    get_cell_values importing row_id type int4
    pr_data_changed type ref to cl_alv_changed_data_protocol
    exporting key type stab_key.

    endclass.

    **----------------------------------------------------------------------
    class lcl_event_handler implementation.
    **----------------------------------------------------------------------
    method handle_data_changed.

    *data: lv_changed type lvc_s_modi.
    data: lv_insert type lvc_s_moce,
    l_wa_g_zcat_maes_mat_auxiliar like g_zcat_maes_mat_auxiliar.

    error_in_data = space.

    * check if there exist double entries
    call method check_double_entries( er_data_changed ).

    call method update_delta_tables( er_data_changed ).

    if error_in_data = 'X'.
    call method er_data_changed->display_protocol.
    endif.

    endmethod.

    method handle_before_user_command.
    endmethod.

    method handle_after_user_command.
    endmethod.

    *Handle User Command
    method handle_user_command .
    * PERFORM handle_user_command USING e_ucomm .
    endmethod.


    method handle_menu_button .
    * PERFORM handle_menu_button USING e_object e_ucomm .
    endmethod.

    *Handle Toolbar
    method handle_toolbar.
    * PERFORM handle_toolbar USING e_object e_interactive .
    endmethod .

    method get_inserted_rows.
    inserted_rows = me->inserted_rows.
    endmethod.
    *------------------------------------------------------

    method get_deleted_rows.
    deleted_rows = me->deleted_rows.
    endmethod.
    *------------------------------------------------------
    method refresh_delta_tables.
    clear me->inserted_rows[].
    clear me->deleted_rows[].
    endmethod.
    *------------------------------------------------------
    method set_table_is_initial.
    initial_table = 'X'.
    endmethod.
    *------------------------------------------------------
    method set_table_is_not_initial.
    initial_table = space.
    endmethod.
    *------------------------------------------------------
    method table_is_initial.
    if initial_table = 'X'.
    initial = 'X'.
    else.
    initial = space.
    endif.
    endmethod.

    *-----------------------------------------------------------------------
    method check_double_entries.
    data: lt_good_cells type lvc_t_modi,
    ls_good type lvc_s_modi,
    ls_key type stab_key,
    ls_sflight type stab_table,
    l_flightdate like g_zcat_maes_mat_auxiliar-matnr,
    l_del_row type lvc_s_moce,
    ls_outtab like line of g_zcat_maes_mat_auxiliar,
    l_reentered type c.



    * §5.Check if there exist already other records with equal key fields.

    *.............................................
    * Check if the user has entered two new lines where the key fields
    * are equal.
    *.............................................
    * Since CARRID and CONNID are read only, the check is restrained
    * to field FLDATE.
    *
    * Algorithm: Copy all entries in MT_GOOD_CELLS to a dummy table.
    * During the copying procedure check if there exists
    * already a line with the same Flight date.
    *
    loop at pr_data_changed->mt_good_cells into ls_good.
    case ls_good-fieldname.
    when 'MATNR'.

    call method pr_data_changed->get_cell_value
    exporting
    i_row_id = ls_good-row_id
    i_fieldname = ls_good-fieldname
    importing e_value = l_flightdate.

    read table lt_good_cells with key
    value = l_flightdate
    transporting no fields.
    if sy-subrc = 0.
    * There exists already a line with the same flight date!
    call method pr_data_changed->add_protocol_entry
    exporting
    i_msgid = '0K' i_msgno = '000' i_msgty = 'E'
    i_msgv1 = text-m01
    i_fieldname = ls_good-fieldname
    i_row_id = ls_good-row_id.

    error_in_data = 'X'.
    else.
    ls_good-value = l_flightdate.
    append ls_good to lt_good_cells.
    endif.
    endcase.

    endloop.


    endmethod.

    *-------------------------------------------------------
    method update_delta_tables.
    data: l_ins_row type lvc_s_moce,
    l_del_row type lvc_s_moce,
    ls_key type stab_key,
    ls_sflight type zcat_maes_mat,
    ls_outtab like line of g_zcat_maes_mat_auxiliar.

    * §6.Use protocol attributes MT_DELETED_ROWS and MT_INSERTED_ROWS
    * to remember which lines where deleted or inserted. Save this
    * information in your internal tables.

    *..........
    * deleted rows
    *.............
    loop at pr_data_changed->mt_deleted_rows into l_del_row.
    read table g_zcat_maes_mat_auxiliar into ls_outtab index l_del_row-row_id.
    if sy-subrc ne 0.
    message i000(0k) with text-e01."Fehler beim Löschen
    else.

    move-corresponding ls_outtab to ls_sflight.

    * It should no be possible that the same line is deleted twice,
    * so we just add the new key line to 'deleted_rows'.

    append ls_sflight to deleted_rows.
    * If this line was inserted just before it is deleted:
    delete me->inserted_rows
    where matnr = ls_outtab-matnr.

    endif.
    endloop.

    *..........
    * inserted rows
    * At this point ALV has not added new lines
    * to gt_outtab, so you can not access their values
    * by reading gt_outtab.
    * Table MT_GOOD_CELLS holds new values that can be
    * referenced using the ROW_ID.
    *..........
    if me->table_is_initial( ) eq 'X'.
    * No flights were selected initially. This is the first new line.
    call method get_cell_values
    exporting row_id = 1
    pr_data_changed = pr_data_changed
    importing key = ls_key.

    append ls_key to inserted_rows.
    call method me->set_table_is_not_initial.
    endif.

    loop at pr_data_changed->mt_inserted_rows into l_ins_row.
    call method get_cell_values
    exporting row_id = l_ins_row-row_id
    pr_data_changed = pr_data_changed
    importing key = ls_key.
    * READ TABLE gt_outtab INTO ls_outtab INDEX l_ins_row-row_id.

    * Just insert the new row regardless if the input is wrong
    append ls_key to inserted_rows.
    endloop.

    endmethod.

    method get_cell_values.
    * get values of key cells of row ROW_ID

    * CARRIER
    call method pr_data_changed->get_cell_value
    exporting
    i_row_id = row_id
    i_fieldname = 'MATNR'
    importing
    e_value = key-matnr.

    if sy-subrc ne 0.
    message i000(0k) with text-e02. "Fehler beim Einfügen
    endif.

    endmethod.

    *------------------------------------------------------

    endclass.

    data: g_event_receiver type ref to lcl_event_handler.

    **************************** SELECTION-SCREEN ************************

    selection-screen begin of block blk2 with frame title text-001.
    parameters : pa_vkorg type vkorg obligatory.
    parameters : pa_vtweg type vtweg obligatory.
    selection-screen end of block blk2.

    **************************** START-OF-SELECTION ************************
    start-of-selection.

    perform seleccion_datos.
    call screen 1500.

    end-of-selection.
    **************************** END-OF-SELECTION ************************

    *&---------------------------------------------------------------------*
    *& Form SELECCION_DATOS
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    form seleccion_datos.

    * Damos el formato a la ALV de los diferentes campos que se van a ver.
    perform build_fieldcat.

    endform. " SELECCION_DATOS


    *&---------------------------------------------------------------------*
    *& Form BUILD_FIELDCAT
    *&---------------------------------------------------------------------*
    * Creamos el formato del ALV
    *----------------------------------------------------------------------*
    form build_fieldcat.

    * Importante hay que añadir "WITH HEADER LINE
    data: l_fieldcatalog type lvc_t_fcat with header line.

    clear: l_fieldcatalog, g_fieldcatalog.
    refresh: l_fieldcatalog.

    l_fieldcatalog-fieldname = 'MATNR'. "Código Campaña
    l_fieldcatalog-scrtext_l = 'Material'.
    l_fieldcatalog-col_pos = 2.
    l_fieldcatalog-key = 'X'.
    l_fieldcatalog-outputlen = 18.
    l_fieldcatalog-just = 'X'.
    l_fieldcatalog-edit = 'X'.
    append l_fieldcatalog to g_fieldcatalog.
    clear: l_fieldcatalog.

    l_fieldcatalog-fieldname = 'MAKXT'. "Código Comunicación
    l_fieldcatalog-scrtext_l = 'Comunicación'.
    l_fieldcatalog-col_pos = 3.
    l_fieldcatalog-key = 'X'.
    l_fieldcatalog-outputlen = 40.
    l_fieldcatalog-just = 'X'.
    l_fieldcatalog-edit = 'X'.
    append l_fieldcatalog to g_fieldcatalog.
    clear: l_fieldcatalog.

    endform. " BUILD_FIELDCAT

    *&---------------------------------------------------------------------*
    *& Form load_data_into_grid
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    form load_data_into_grid.

    data: l_num type i.

    describe table g_zcat_maes_mat_auxiliar lines l_num.

    * Excluir los botones de la ALV que no nos interesan.
    perform exclude_tb_functions changing l_exclude.

    * Cargamos la ALV
    call method go_grid->set_table_for_first_display
    exporting
    is_layout = l_layout
    it_toolbar_excluding = l_exclude
    changing
    it_outtab = g_zcat_maes_mat_auxiliar[]
    it_fieldcatalog = g_fieldcatalog[].

    * call method go_grid->set_ready_for_input exporting i_ready_for_input = 1.

    * Para saber si se han marcado la líneas.
    call method go_grid->register_edit_event exporting i_event_id = cl_gui_alv_grid=>mc_evt_enter.

    * Evento que captura los cambios realizados
    call method go_grid->register_edit_event exporting i_event_id = cl_gui_alv_grid=>mc_evt_modified.

    * Instanciando el objeto que enlaza eventos y el grid
    create object g_event_receiver.
    set handler g_event_receiver->handle_data_changed for go_grid.

    * SET HANDLER g_event_receiver->handle_user_command FOR go_grid.
    * SET HANDLER g_event_receiver->handle_after_user_command FOR go_grid.
    * SET HANDLER g_event_receiver->handle_before_user_command FOR go_grid.
    * SET HANDLER g_event_receiver->handle_menu_button FOR go_grid.
    * SET HANDLER g_event_receiver->handle_toolbar FOR go_grid.

    endform. " load_data_into_grid

    *&---------------------------------------------------------------------*
    *& Module SCREEN_ATRIBUTTES OUTPUT
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    module screen_atributtes output.

    data: button01(30) type c value 'COCINA',
    button02(30) type c value 'BEBIDA',
    button03(30) type c value 'MENAJE',
    button04(30) type c value 'ESTRUCTURA'.

    endmodule. " SCREEN_ATRIBUTTES OUTPUT

    *&---------------------------------------------------------------------*
    *& Module STATUS_1500 OUTPUT
    *&---------------------------------------------------------------------*
    * Status que vamos a usar en la TabStrib
    *----------------------------------------------------------------------*
    module status_1500 output.
    set pf-status 'STATUS_1500'.
    endmodule. " STATUS_1500 OUTPUT

    *&---------------------------------------------------------------------*
    *& Module SAVE_DATA INPUT
    *&---------------------------------------------------------------------*
    * Guardamos los datos en la base de datos.
    *----------------------------------------------------------------------*
    module save_data input.

    endmodule. " SAVE_DATA INPUT

    *&---------------------------------------------------------------------*
    *& Module USER_COMMAND_1500 INPUT
    *&---------------------------------------------------------------------*
    * Acciones a realizar cuando el usuario pulse algún botón.
    *----------------------------------------------------------------------*
    module user_command_1500 input.

    case sy-dynnr.

    when 1500.

    if sy-ucomm cs 'BUTTON'.
    number = 2000.
    tabstrip-activetab = sy-ucomm.
    g_slide = sy-ucomm.
    endif.

    if sy-ucomm eq 'BACK' or sy-ucomm eq 'CANCEL' or
    sy-ucomm eq 'EXIT'.

    flag_ejecutar_tab = 'FALSE'.

    * Lo dejo en la primera pestaña. Sino si volvemos atrás y
    * seleccionamos otro tipo nos dará problema entre pestaña
    * y campo correspondiente.

    number = 2000.
    tabstrip-activetab = ''.
    g_slide = ''.

    call function 'POPUP_TO_CONFIRM_STEP'
    exporting
    textline1 = '¿Desea guardar los datos?'
    titel = 'Guardar Datos'
    cancel_display = ''
    importing
    answer = g_answer.

    * Volvemos a la pantalla de inicio programa.

    if g_answer eq 'J'.
    sy-ucomm = 'SAVE'.
    elseif g_answer eq 'N'.

    set screen 0.
    flag_inicio = 'FALSE'.
    flag_1 = 'FALSE'.
    endif.

    endif.

    if sy-ucomm eq 'SAVE' and g_flag_permiso eq 'TRUE'.

    * Dejo el control en la primera pestaña.
    number = 2000.
    tabstrip-activetab = ''.
    g_slide = ''.

    * Grabo los datos del sistema.
    perform graba_datos_sistema.
    flag_inicio = 'FALSE'.
    flag_1 = 'FALSE'.
    set screen 0.

    elseif sy-ucomm eq 'SAVE'.
    message s088(sf) with text-132.
    endif.

    endcase.

    endmodule. " USER_COMMAND_1500 INPUT

    *&---------------------------------------------------------------------*
    *& Form GRABA_DATOS_SISTEMA
    *&---------------------------------------------------------------------*
    * Grabamos los datos en las tablas correspondientes.
    *----------------------------------------------------------------------*
    form graba_datos_sistema.



    endform. " GRABA_DATOS_SISTEMA

    *&---------------------------------------------------------------------*
    *& Module STATUS_2000 OUTPUT
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    module status_2000 output.
    * SET PF-STATUS 'xxxxxxxx'.
    * SET TITLEBAR 'xxx'.

    * Creamos el contenedor del ALV y llamamos al ALV
    if go_custom_container is initial.

    create object go_custom_container
    exporting container_name = 'ZTABLA'.

    create object go_grid
    exporting
    i_parent = go_custom_container.

    * Layout
    l_layout-no_rowmark = 'X'.
    l_layout-zebra = 'X'.
    l_layout-cwidth_opt = ''.
    perform load_data_into_grid.

    else.
    l_layout-no_rowmark = 'X'.
    l_layout-zebra = 'X'.
    l_layout-cwidth_opt = ''.

    call method go_grid->refresh_table_display.
    perform load_data_into_grid.

    endif.

    case sy-ucomm.
    *
    when 'BACK'. "perform clear_variables.
    "clear g_datos. refresh g_datos.
    leave to screen 0. exit.
    *
    * when 'CANC'. perform clear_variables.
    * clear g_datos. refresh g_datos.
    * leave to screen 0. exit.
    *
    * when 'EXIT'. perform clear_variables.
    * clear g_datos. refresh g_datos.
    * leave to screen 0. exit.
    *
    * when 'SELECT'. perform select_all_entries using 'X'.
    *
    * when 'DESELECT'. perform select_all_entries using space.
    *
    * when 'CHANGE'. perform graba_datos.
    * clear g_datos. refresh g_datos.
    * leave to screen 0. exit.
    *
    endcase.

    endmodule. " STATUS_2000 OUTPUT

    *&---------------------------------------------------------------------*
    *& Module USER_COMMAND_2000 INPUT
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    module user_command_2000 input.



    endmodule. " USER_COMMAND_2000 INPUT

    *&---------------------------------------------------------------------*
    *& Form CLEAR_VARIABLES
    *&---------------------------------------------------------------------*
    * text
    *----------------------------------------------------------------------*
    form clear_variables.

    if not go_custom_container is initial.

    * Limpiar referencia al objeto

    call method go_grid->free.
    call method go_custom_container->free.

    * Limpiar variables

    clear g_event_receiver.
    clear go_grid.
    clear go_custom_container.

    endif.

    endform. " CLEAR_VARIABLES

    *&---------------------------------------------------------------------*
    *& Form EXCLUDE_TB_FUNCTIONS
    *&---------------------------------------------------------------------*
    * Excluir botones de la ALV
    *---------------------------------------------------------------------*
    form exclude_tb_functions changing pt_exclude type ui_functions.

    data ls_exclude type ui_func.

    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy_row.
    append ls_exclude to pt_exclude.
    * ls_exclude = cl_gui_alv_grid=>mc_fc_loc_delete_row.
    * append ls_exclude to pt_exclude.
    * ls_exclude = cl_gui_alv_grid=>mc_fc_loc_append_row.
    * append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_insert_row.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_move_row.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_copy.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_cut.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_paste_new_row.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_loc_undo.
    append ls_exclude to pt_exclude.
    ls_exclude = cl_gui_alv_grid=>mc_fc_check.
    append ls_exclude to pt_exclude.

    endform. " EXCLUDE_TB_FUNCTIONS " deselect_all_entries

    form handle_user_command using i_ucomm type syucomm .

    endform .

    form handle_menu_button using i_object type ref to cl_ctmenu
    i_ucomm type syucomm .


    endform. " handle_menu_button

    form handle_toolbar using i_object type ref to cl_alv_event_toolbar_set .

    endform .
Trabajando...