SAPфорум.RU
https://www.sapboard.ru/forum/

Z-программа для редактирования таблиц БД
https://www.sapboard.ru/forum/viewtopic.php?f=13&t=98907
Страница 1 из 1

Автор:  kernel [ Сб, авг 01 2020, 13:00 ]
Заголовок сообщения:  Z-программа для редактирования таблиц БД

Всем привет!

Выкладываю свой аналог SE16N. Программой пользуюсь уже на протяжении 7 лет. Может и вам пригодится.
Разработать данную программу побудили ограничения компании где я работал. Были отрезаны всевозможные способы редактирования таблиц. При этом, было много настоечных таблиц, без возможности редактирования их в целевой системе.

Возможности
  • Просмотр данных таблиц БД
  • Добавление/удаление/изменение данных
  • Загрузка данных из Excel-таблицы

Примечание
В коде зашито условие что редактировать можно только Z-таблицы. При необходимости можно это условие убрать. Или наоборот, расширить условия.

Демонстрация
Изображение
Изображение
Изображение

Установка
1. Создаем программу ZSE16N
2. Добавляем GUI-заголовок MAIN
Изображение
3. Добавляем GUI-статус MAIN
Изображение
4. Добавляем GUI-статус SEL
Изображение
5. Вставляем код программы
Code:
*&---------------------------------------------------------------------*
*& Report  ZSE16N
*& Общий просмотр/редактирование таблиц
*&---------------------------------------------------------------------*
*& Программа для просмотра/редактирования таблиц БД
*& http://abap4.ru/?p=220
*&---------------------------------------------------------------------*
REPORT zse16n MESSAGE-ID 00.

TABLES: dd02l.

CONSTANTS:
  gc_text_table_not_found   TYPE string VALUE 'Не найдена таблица',
  gc_text_ddif_not_found    TYPE string VALUE 'Ошибка получения структуры таблицы',
  gc_text_comp_table_error  TYPE string VALUE 'Ошибка получения компонентов таблицы',
  gc_text_ss_frame_text     TYPE string VALUE 'Выбор данных из таблицы',
  gc_text_ss_title          TYPE string VALUE 'экран выбора',
  gc_text_preview           TYPE string VALUE 'просмотр',
  gc_text_edit              TYPE string VALUE 'редактирование',
  gc_text_no_edited_cell    TYPE string VALUE 'Отсутствуют измененные ячейки',
  gc_text_del_rows          TYPE string VALUE 'Удаленны, строки',
  gc_text_ins_rows          TYPE string VALUE 'Вставлен, строки',
  gc_text_mod_rows          TYPE string VALUE 'Измененн, строки',
  gc_text_proceed           TYPE string VALUE 'Продолжить',
  gc_text_attention         TYPE string VALUE 'Внимание',
  gc_text_unknown_db_error  TYPE string VALUE 'Неизвестная ошибка БД',
  gc_text_db_primary_exists TYPE string VALUE 'БД уже содержит запись с таким первичным или уникальным ключом',
  gc_text_db_key_exists     TYPE string VALUE 'БД уже содержит запись с таким уникальным ключом',
  gc_text_db_not_found      TYPE string VALUE 'Не найдена запись с таким ключом',
  gc_text_save_success      TYPE string VALUE 'Данные успешно сохранены',
  gc_text_save_error        TYPE string VALUE 'Данные не были сохранены',
  gc_text_error_log         TYPE string VALUE 'лог ошибок',
  gc_text_select_table      TYPE string VALUE 'Выберите файл с таблицей'.

CONSTANTS:
  gc_msg_text_field(30) TYPE c VALUE 'KERNEL_RX2_CONST__Z_MSG_TEXT__',
  gc_tab_styl_field(30) TYPE c VALUE 'KERNEL_RX2_CONST__Z_TAB_STYL__',
  gc_mod_type_field(30) TYPE c VALUE 'KERNEL_RX2_CONST__Z_MOD_TYPE__',
  gc_mod_insert(1)      TYPE c VALUE 'I',
  gc_mod_update(1)      TYPE c VALUE 'U',
  gc_mod_delete(1)      TYPE c VALUE 'D'.

DATA:
  gv_edit   TYPE flag.

DATA:
  gv_selid TYPE dynselid,
  gv_where TYPE string.

DATA:
  gt_tab_expr   TYPE rsds_texpr,
  gt_tab_where  TYPE rsds_twhere,
  gt_tab_fields TYPE STANDARD TABLE OF rsdsfields,
  gt_dfies      TYPE STANDARD TABLE OF dfies,
  gt_components TYPE cl_abap_structdescr=>component_table.

FIELD-SYMBOLS:
  <gt_table> TYPE STANDARD TABLE,
  <gs_tabln> TYPE any,
  <gs_keys>  TYPE any,
  <gt_modif> TYPE STANDARD TABLE,
  <gs_modif> TYPE any,
  <gt_dblog> TYPE STANDARD TABLE,
  <gs_dfies> TYPE dfies.

PARAMETERS p_tab LIKE dd02l-tabname OBLIGATORY MEMORY ID dtb.
PARAMETERS p_max TYPE i DEFAULT 200 MEMORY ID max_sel.      "#EC EXISTS

START-OF-SELECTION.
  PERFORM main.

*&---------------------------------------------------------------------*
*&      Form  main
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM main.
  PERFORM check_input.
  CHECK sy-subrc EQ 0.

  PERFORM get_table_info.
  CHECK sy-subrc EQ 0.

  PERFORM generate_types.
  CHECK sy-subrc EQ 0.

  PERFORM selection_screen_init.
  CHECK sy-subrc EQ 0.

  WHILE sy-subrc EQ 0.
    PERFORM selection_screen_show.
    CHECK sy-subrc EQ 0.

    PERFORM select_data.
    CHECK sy-subrc EQ 0.

    PERFORM show_data.
    CHECK sy-subrc EQ 0.
  ENDWHILE.
ENDFORM.                    "main

*&---------------------------------------------------------------------*
*&      Form  check_input
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM check_input.
  DATA lv_tabname LIKE dd02l-tabname.

  SELECT SINGLE tabname
    INTO lv_tabname
    FROM dd02l
    WHERE tabname EQ p_tab.                                 "#EC *
  IF sy-subrc NE 0 OR p_tab NP 'Z*'.
    MESSAGE s368 WITH gc_text_table_not_found p_tab.
    MOVE 4 TO sy-subrc.
  ELSE.
    MOVE 0 TO sy-subrc.
  ENDIF.
ENDFORM.                    "check_input

*&---------------------------------------------------------------------*
*&      Form  get_table_info
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_table_info.
  PERFORM get_fieldinfo_tab.
  CHECK sy-subrc EQ 0.

  PERFORM get_components_tab.
  CHECK sy-subrc EQ 0.
ENDFORM.                    "get_table_info

*&---------------------------------------------------------------------*
*&      Form  get_fieldinfo_tab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_fieldinfo_tab.
  CALL FUNCTION 'DDIF_FIELDINFO_GET'
    EXPORTING
      tabname   = p_tab
    TABLES
      dfies_tab = gt_dfies
    EXCEPTIONS
      OTHERS    = 1.
  IF sy-subrc NE 0.
    MESSAGE s208 WITH gc_text_ddif_not_found.
    MOVE 1001 TO sy-subrc.
  ENDIF.
ENDFORM.                    "get_fieldinfo_tab

*&---------------------------------------------------------------------*
*&      Form  get_components_tab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_components_tab.
  DATA:
    lo_tab_structdescr TYPE REF TO cl_abap_structdescr,
    lt_components      TYPE cl_abap_structdescr=>component_table,
    lv_tabix           LIKE sy-tabix.

  FIELD-SYMBOLS <ls_comp> LIKE LINE OF gt_components.

  REFRESH gt_components.

  lo_tab_structdescr ?= cl_abap_typedescr=>describe_by_name( p_tab ).
  gt_components = lo_tab_structdescr->get_components( ).

  LOOP AT gt_components ASSIGNING <ls_comp> WHERE as_include EQ 'X'.
    MOVE sy-tabix TO lv_tabix.

    lo_tab_structdescr ?= <ls_comp>-type.
    lt_components = lo_tab_structdescr->get_components( ).

    DELETE gt_components INDEX lv_tabix.
    INSERT LINES OF lt_components INTO gt_components INDEX lv_tabix.
  ENDLOOP.

  IF lines( gt_components[] ) GT 0.
    MOVE 0 TO sy-subrc.
  ELSE.
    MESSAGE s208 WITH gc_text_comp_table_error.
    MOVE 1001 TO sy-subrc.
  ENDIF.
ENDFORM.                    "get_components_tab

*&---------------------------------------------------------------------*
*&      Form  generate_types
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_types.
  PERFORM generate_keys_struct.
  PERFORM generate_tabln_struct.
  PERFORM generate_main_tab.
  PERFORM generate_modif_tab.
  PERFORM generate_db_log_tab.
ENDFORM.                    "generate_types

*&---------------------------------------------------------------------*
*&      Form  generate_keys_struct
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_keys_struct.
  DATA:
    lt_comp             TYPE cl_abap_structdescr=>component_table,
    lo_structdescr_keys TYPE REF TO cl_abap_structdescr,
    lo_keys_ref         TYPE REF TO data.

  lt_comp[] = gt_components[].

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype EQ 'CLNT' OR keyflag IS INITIAL.
    DELETE lt_comp WHERE name EQ <gs_dfies>-fieldname.
  ENDLOOP.

  lo_structdescr_keys = cl_abap_structdescr=>create( lt_comp ).

  CREATE DATA lo_keys_ref TYPE HANDLE lo_structdescr_keys.
  ASSIGN lo_keys_ref->* TO <gs_keys>.
ENDFORM.                    "generate_keys_struct

*&---------------------------------------------------------------------*
*&      Form  generate_tabln_struct
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_tabln_struct.
  DATA lo_tabln_ref TYPE REF TO data.

  CREATE DATA lo_tabln_ref TYPE (p_tab).
  ASSIGN lo_tabln_ref->* TO <gs_tabln>.
ENDFORM.                    "generate_tabln_struct

*&---------------------------------------------------------------------*
*&      Form  generate_main_tab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_main_tab.
  DATA:
    lt_key       TYPE abap_keydescr_tab,
    lt_comp      TYPE cl_abap_structdescr=>component_table,
    lo_main_type TYPE REF TO cl_abap_structdescr,
    lo_main_tab  TYPE REF TO cl_abap_tabledescr,
    lo_table_ref TYPE REF TO data.

  FIELD-SYMBOLS:
    <ls_comp_tab> TYPE LINE OF cl_abap_structdescr=>component_table.

  REFRESH lt_key.

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype NE 'CLNT' AND keyflag EQ 'X'.
    APPEND <gs_dfies>-fieldname TO lt_key.
  ENDLOOP.

  lt_comp[] = gt_components[].

  APPEND INITIAL LINE TO lt_comp ASSIGNING <ls_comp_tab>.
  <ls_comp_tab>-name = gc_tab_styl_field.
  <ls_comp_tab>-type ?= cl_abap_elemdescr=>describe_by_name( 'LVC_T_STYL' ).

  lo_main_type = cl_abap_structdescr=>create( lt_comp ).

  lo_main_tab = cl_abap_tabledescr=>create(
                  p_line_type   = lo_main_type
                  p_key         = lt_key
                  p_table_kind  = cl_abap_tabledescr=>tablekind_std
                  p_unique      = abap_false ).

  CREATE DATA lo_table_ref TYPE HANDLE lo_main_tab.
  ASSIGN lo_table_ref->* TO <gt_table>.
ENDFORM.                    "generate_main_tab

*&---------------------------------------------------------------------*
*&      Form  generate_modif_tab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_modif_tab.
  DATA:
    lt_key           TYPE abap_keydescr_tab,
    lt_comp          TYPE cl_abap_structdescr=>component_table,
    lo_mod_type      TYPE REF TO cl_abap_structdescr,
    lo_mod_tab       TYPE REF TO cl_abap_tabledescr,
    lo_modif_ref     TYPE REF TO data,
    lo_modif_tab_ref TYPE REF TO data.

  FIELD-SYMBOLS:
    <ls_comp_tab> TYPE LINE OF cl_abap_structdescr=>component_table.

  REFRESH lt_key.
  UNASSIGN: <gs_modif>, <gt_modif>.

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype NE 'CLNT' AND keyflag EQ 'X'.
    APPEND <gs_dfies>-fieldname TO lt_key.
  ENDLOOP.

  lt_comp[] = gt_components[].

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype EQ 'CLNT' OR keyflag IS INITIAL.
    DELETE lt_comp WHERE name EQ <gs_dfies>-fieldname.
  ENDLOOP.

  APPEND INITIAL LINE TO lt_comp ASSIGNING <ls_comp_tab>.
  <ls_comp_tab>-name = gc_mod_type_field.
  <ls_comp_tab>-type = cl_abap_elemdescr=>get_c( p_length = 1 ).

  lo_mod_type = cl_abap_structdescr=>create( lt_comp ).

  lo_mod_tab = cl_abap_tabledescr=>create(
                  p_line_type   = lo_mod_type
                  p_key         = lt_key
                  p_table_kind  = cl_abap_tabledescr=>tablekind_std
                  p_unique      = abap_false ).

  CREATE DATA lo_modif_ref TYPE HANDLE lo_mod_type.
  ASSIGN lo_modif_ref->* TO <gs_modif>.

  CREATE DATA lo_modif_tab_ref TYPE HANDLE lo_mod_tab.
  ASSIGN lo_modif_tab_ref->* TO <gt_modif>.
ENDFORM.                    "generate_modif_tab

*&---------------------------------------------------------------------*
*&      Form  generate_db_log_tab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM generate_db_log_tab.
  DATA:
    lt_key            TYPE abap_keydescr_tab,
    lt_comp           TYPE cl_abap_structdescr=>component_table,
    lo_db_log_type    TYPE REF TO cl_abap_structdescr,
    lo_db_log_tab     TYPE REF TO cl_abap_tabledescr,
    lo_db_log_tab_ref TYPE REF TO data.

  FIELD-SYMBOLS:
    <ls_comp_tab> TYPE LINE OF cl_abap_structdescr=>component_table.

  REFRESH lt_key.
  UNASSIGN: <gt_dblog>.

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype NE 'CLNT' AND keyflag EQ 'X'.
    APPEND <gs_dfies>-fieldname TO lt_key.
  ENDLOOP.

  lt_comp[] = gt_components[].

  LOOP AT gt_dfies ASSIGNING <gs_dfies> WHERE datatype EQ 'CLNT' OR keyflag IS INITIAL.
    DELETE lt_comp WHERE name EQ <gs_dfies>-fieldname.
  ENDLOOP.

  APPEND INITIAL LINE TO lt_comp ASSIGNING <ls_comp_tab>.
  <ls_comp_tab>-name = gc_msg_text_field.
  <ls_comp_tab>-type = cl_abap_elemdescr=>get_c( p_length = 128 ).

  lo_db_log_type = cl_abap_structdescr=>create( lt_comp ).

  lo_db_log_tab = cl_abap_tabledescr=>create(
                  p_line_type   = lo_db_log_type
                  p_key         = lt_key
                  p_table_kind  = cl_abap_tabledescr=>tablekind_std
                  p_unique      = abap_false ).

  CREATE DATA lo_db_log_tab_ref TYPE HANDLE lo_db_log_tab.
  ASSIGN lo_db_log_tab_ref->* TO <gt_dblog>.
ENDFORM.                    "generate_db_log_tab

*&---------------------------------------------------------------------*
*&      Form  selection_screen_init
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM selection_screen_init .
  CONSTANTS lc_max_fields TYPE i VALUE 75.

  DATA:
    lt_tab_tables   TYPE STANDARD TABLE OF rsdstabs.

  DATA:
    ls_tables LIKE LINE OF lt_tab_tables,
    ls_fields LIKE LINE OF gt_tab_fields,
    ls_dfies  TYPE dfies.

  REFRESH: gt_tab_expr, gt_tab_where, gt_tab_fields.
  REFRESH: lt_tab_tables.

  CLEAR: ls_tables, ls_fields, ls_dfies,
         gv_selid, gv_where.

  ls_tables-prim_tab = p_tab.
  APPEND ls_tables TO lt_tab_tables.

  LOOP AT gt_dfies INTO ls_dfies."#EC CI_LOOP_INTO_WA
    CHECK ls_dfies-datatype NE 'CLNT'.
    CHECK ls_dfies-inttype CO 'CNDTXIbsPF'.
    CHECK lines( gt_tab_fields ) LT lc_max_fields.

    ls_fields-tablename = p_tab.
    ls_fields-fieldname = ls_dfies-fieldname.
    APPEND ls_fields TO gt_tab_fields.
  ENDLOOP.

  CALL FUNCTION 'FREE_SELECTIONS_INIT'
    EXPORTING
      expressions              = gt_tab_expr
    IMPORTING
      selection_id             = gv_selid
      where_clauses            = gt_tab_where
      expressions              = gt_tab_expr
    TABLES
      tables_tab               = lt_tab_tables
      fields_tab               = gt_tab_fields
    EXCEPTIONS
      fields_incomplete        = 1
      fields_no_join           = 2
      field_not_found          = 3
      no_tables                = 4
      table_not_found          = 5
      expression_not_supported = 6
      incorrect_expression     = 7
      illegal_kind             = 8
      area_not_found           = 9
      inconsistent_area        = 10
      kind_f_no_fields_left    = 11
      kind_f_no_fields         = 12
      too_many_fields          = 13
      dup_field                = 14
      field_no_type            = 15
      field_ill_type           = 16
      dup_event_field          = 17
      node_not_in_ldb          = 18
      area_no_field            = 19
      OTHERS                   = 20.
  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.                    " selection_screen_init

*&---------------------------------------------------------------------*
*&      Form  selection_screen_show
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM selection_screen_show .
  DATA ls_where LIKE LINE OF gt_tab_where.
  DATA ls_pfkey TYPE rsdspfkey.
  DATA lv_title LIKE sy-title.
  DATA lv_frame LIKE sy-title.

  lv_title = |{ p_tab }: { gc_text_ss_title }|.
  lv_frame = gc_text_ss_frame_text.

  ls_pfkey-pfkey = 'SEL'.
  ls_pfkey-program = sy-repid.

  CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
    EXPORTING
      selection_id    = gv_selid
      title           = lv_title
      tree_visible    = space
      pfkey           = ls_pfkey
      frame_text      = lv_frame
    IMPORTING
      where_clauses   = gt_tab_where
      expressions     = gt_tab_expr
    TABLES
      fields_tab      = gt_tab_fields
    EXCEPTIONS
      no_action       = 1
      internal_error  = 2
      selid_not_found = 3
      illegal_status  = 4
      OTHERS          = 5.
  CASE sy-subrc.
    WHEN 0.
      " Good
    WHEN 1.
      EXIT.
    WHEN OTHERS.
      MESSAGE ID sy-msgid
            TYPE sy-msgty
          NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      EXIT.
  ENDCASE.

  READ TABLE gt_tab_where INTO ls_where WITH KEY tablename = p_tab.
  IF sy-subrc EQ 0.
    CONCATENATE LINES OF ls_where-where_tab
      INTO gv_where SEPARATED BY space.
  ELSE.
    CLEAR gv_where.
  ENDIF.

  MOVE 0 TO sy-subrc.
ENDFORM.                    " selection_screen_show

*&---------------------------------------------------------------------*
*&      Form  select_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM select_data .
  REFRESH: <gt_table>, <gt_modif>.
  CLEAR: <gs_tabln>.

  SELECT *
    FROM (p_tab)
    UP TO p_max ROWS
    INTO CORRESPONDING FIELDS OF TABLE <gt_table>
    WHERE (gv_where).

  IF p_max GT 0 AND
     p_max EQ sy-dbcnt.
    MESSAGE s016(es) WITH sy-dbcnt.
  ELSE.
    MESSAGE s006(sv) WITH sy-dbcnt.
  ENDIF.

  MOVE 0 TO sy-subrc.
ENDFORM.                    " select_data

*&---------------------------------------------------------------------*
*&      Form  show_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM show_data .
  DATA:
    lt_events TYPE slis_t_event,
    lt_fcat   TYPE slis_t_fieldcat_alv,
    ls_layout TYPE slis_layout_alv.

  FIELD-SYMBOLS:
    <ls_event> TYPE slis_alv_event,
    <ls_fcat>  TYPE slis_fieldcat_alv.

  REFRESH: lt_fcat, lt_events.

  LOOP AT gt_dfies ASSIGNING <gs_dfies>.
    APPEND INITIAL LINE TO lt_fcat ASSIGNING <ls_fcat>.
    PERFORM fill_fcat_using_fname USING <gs_dfies>-fieldname CHANGING <ls_fcat>.

    IF <ls_fcat>-key IS INITIAL.
      <ls_fcat>-edit = gv_edit.
    ENDIF.
  ENDLOOP.

  APPEND INITIAL LINE TO lt_events ASSIGNING <ls_event>.
  <ls_event>-name = 'DATA_CHANGED'.
  <ls_event>-form = 'ON_DATA_CHANGED'.

  APPEND INITIAL LINE TO lt_events ASSIGNING <ls_event>.
  <ls_event>-name = 'END_OF_PAGE'.
  <ls_event>-form = 'ON_END_OF_PAGE'.

  CLEAR ls_layout.
  ls_layout-zebra  = 'X'.
  ls_layout-colwidth_optimize = 'X'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'PF_STATUS_SET_MAIN'
      i_callback_user_command  = 'USER_COMMAND_MAIN'
      it_fieldcat              = lt_fcat[]
      is_layout                = ls_layout
      it_events                = lt_events
    TABLES
      t_outtab                 = <gt_table>.
ENDFORM.                    " show_data

*&---------------------------------------------------------------------*
*&      Form  fill_fcat_using_fname
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->FIELDNAME  text
*      -->FIELDCAT   text
*----------------------------------------------------------------------*
FORM fill_fcat_using_fname USING iv_fieldname TYPE csequence
                           CHANGING cs_fieldcat TYPE slis_fieldcat_alv.
  FIELD-SYMBOLS <ls_dfies> LIKE LINE OF gt_dfies.

  READ TABLE gt_dfies ASSIGNING <ls_dfies> WITH KEY fieldname = iv_fieldname.
  CHECK sy-subrc EQ 0.

  cs_fieldcat-key = <ls_dfies>-keyflag.
  cs_fieldcat-fieldname = <ls_dfies>-fieldname.
  cs_fieldcat-seltext_s = <ls_dfies>-scrtext_s.
  cs_fieldcat-seltext_m = <ls_dfies>-scrtext_m.
  cs_fieldcat-seltext_l = <ls_dfies>-scrtext_l.
  cs_fieldcat-reptext_ddic = <ls_dfies>-fieldname.
  cs_fieldcat-ddictxt = 'R'.  " Указываем поле заголовка REPTEXT_DDIC
  cs_fieldcat-datatype = <ls_dfies>-datatype.
  cs_fieldcat-outputlen = <ls_dfies>-outputlen.
  cs_fieldcat-lowercase = <ls_dfies>-lowercase.
  cs_fieldcat-rollname = <ls_dfies>-rollname.
  cs_fieldcat-ref_tabname = p_tab.
  cs_fieldcat-ref_fieldname = <ls_dfies>-fieldname.

  IF cs_fieldcat-seltext_s IS INITIAL.
    cs_fieldcat-seltext_s = <ls_dfies>-fieldtext.
  ENDIF.
  IF cs_fieldcat-seltext_m IS INITIAL.
    cs_fieldcat-seltext_m = <ls_dfies>-fieldtext.
  ENDIF.
  IF cs_fieldcat-seltext_l IS INITIAL.
    cs_fieldcat-seltext_l = <ls_dfies>-fieldtext.
  ENDIF.
ENDFORM.                    "fill_fcat_using_fname

*&---------------------------------------------------------------------*
*&      Form  on_data_changed
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM on_data_changed USING io_data_changed TYPE REF TO cl_alv_changed_data_protocol. "#EC CALLED
  FIELD-SYMBOLS: <ls_mod_cell> TYPE lvc_s_modi.

  LOOP AT io_data_changed->mt_good_cells ASSIGNING <ls_mod_cell>.
    READ TABLE <gt_table> INDEX <ls_mod_cell>-row_id TRANSPORTING NO FIELDS.
    CHECK sy-subrc EQ 0.

    PERFORM append_modif_log USING <ls_mod_cell>-row_id gc_mod_update.
  ENDLOOP.
ENDFORM.                    "on_data_changed

*&---------------------------------------------------------------------*
*&      Form  on_end_of_page
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM on_end_of_page.                                        "#EC CALLED
  DATA lo_alv_grid TYPE REF TO cl_gui_alv_grid.
  DATA ls_layout TYPE lvc_s_layo.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv_grid.

  CHECK lo_alv_grid IS BOUND.

  lo_alv_grid->get_frontend_layout(
    IMPORTING
      es_layout = ls_layout ).

  IF ls_layout-stylefname IS INITIAL.
    ls_layout-stylefname = gc_tab_styl_field.
    lo_alv_grid->set_frontend_layout( is_layout = ls_layout ).
    lo_alv_grid->refresh_table_display( ).
  ENDIF.
ENDFORM.                    "on_end_of_page

*&---------------------------------------------------------------------*
*&      Form  PF_STATUS_SET_MAIN
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM pf_status_set_main USING it_extab TYPE STANDARD TABLE. "#EC CALLED
  DATA lv_tab TYPE string.
  REFRESH it_extab.

  IF gv_edit IS INITIAL.
    APPEND 'INSERT' TO it_extab.
    APPEND 'DELETE' TO it_extab.
    APPEND 'IMPORT_XLS' TO it_extab.
  ENDIF.

  SET PF-STATUS 'MAIN' EXCLUDING it_extab.

  lv_tab = |{ p_tab }:|.
  IF gv_edit IS INITIAL.
    SET TITLEBAR 'MAIN' WITH lv_tab gc_text_preview.
  ELSE.
    SET TITLEBAR 'MAIN' WITH lv_tab gc_text_edit.
  ENDIF.
ENDFORM.                                            " PF_STATUS_SET_MAIN

*&---------------------------------------------------------------------*
*&      Form  USER_COMMAND_MAIN
*&---------------------------------------------------------------------*
*       Обработка действий пользователя
*----------------------------------------------------------------------*
*      -->UCOMM      text
*      -->FIELD      text
*----------------------------------------------------------------------*
FORM user_command_main USING iv_ucomm LIKE sy-ucomm         "#EC CALLED
                             is_field TYPE slis_selfield.   "#EC NEEDED

  CASE iv_ucomm.
    WHEN 'INSERT'.
      PERFORM insert_row.
      PERFORM refresh.
    WHEN 'DELETE'.
      PERFORM delete_row.
      PERFORM refresh.
    WHEN 'SAVE'.
      PERFORM save.
      PERFORM refresh.
    WHEN 'REFRESH'.
      PERFORM select_data.
      PERFORM refresh.
    WHEN 'DISP_EDIT'.
      PERFORM disp_edit_toggle.
    WHEN 'IMPORT_XLS'.
      PERFORM import_from_excel.
      PERFORM refresh.
  ENDCASE.
ENDFORM.                                            " USER_COMMAND_MAIN

*&---------------------------------------------------------------------*
*&      Form  disp_edit_toggle
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM disp_edit_toggle .
  DATA lo_alv_grid TYPE REF TO cl_gui_alv_grid.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv_grid.

  CHECK lo_alv_grid IS BOUND.

  TRANSLATE gv_edit USING 'X  X'.

  DATA lt_fcat  TYPE lvc_t_fcat.
  FIELD-SYMBOLS <ls_fcat> TYPE lvc_s_fcat.

  lo_alv_grid->get_frontend_fieldcatalog( IMPORTING et_fieldcatalog   = lt_fcat ).

  LOOP AT lt_fcat ASSIGNING <ls_fcat> WHERE key IS INITIAL.
    <ls_fcat>-edit = gv_edit.
  ENDLOOP.

  lo_alv_grid->set_frontend_fieldcatalog( lt_fcat ).

  IF gv_edit EQ 'X'.
    lo_alv_grid->set_ready_for_input( 1 ).
  ELSE.
    lo_alv_grid->set_ready_for_input( 0 ).
  ENDIF.
ENDFORM.                    " disp_edit_toggle

*&---------------------------------------------------------------------*
*&      Form  check_changed_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM check_changed_data.
  DATA lo_alv_grid TYPE REF TO cl_gui_alv_grid.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv_grid.

  CHECK lo_alv_grid IS BOUND.

  lo_alv_grid->check_changed_data( ).

  MOVE 0 TO sy-subrc.
ENDFORM.                    "check_changed_data

*&---------------------------------------------------------------------*
*&      Form  insert_row
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM insert_row .
  DATA:
    lo_alv_grid   TYPE REF TO cl_gui_alv_grid,
    lt_index_rows   TYPE lvc_t_row,
    lt_row_no       TYPE lvc_t_roid.

  FIELD-SYMBOLS:
    <ls_row_no> TYPE LINE OF lvc_t_roid,
    <ls_row>    TYPE any.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv_grid.

  CHECK lo_alv_grid IS BOUND.

  PERFORM check_changed_data.

  CALL METHOD lo_alv_grid->get_selected_rows
    IMPORTING
      et_index_rows = lt_index_rows
      et_row_no     = lt_row_no.

  SORT lt_row_no BY row_id ASCENDING.

  IF lt_row_no[] IS INITIAL.
    APPEND INITIAL LINE TO <gt_table> ASSIGNING <ls_row>.
    PERFORM set_full_editable_row CHANGING <ls_row>.
  ELSE.
    LOOP AT lt_row_no ASSIGNING <ls_row_no>.
      INSERT INITIAL LINE INTO <gt_table> ASSIGNING <ls_row> INDEX <ls_row_no>-row_id.
      PERFORM set_full_editable_row CHANGING <ls_row>.
    ENDLOOP.
  ENDIF.

  REFRESH: lt_index_rows, lt_row_no.

  CALL METHOD lo_alv_grid->set_selected_rows
    EXPORTING
      it_index_rows = lt_index_rows
      it_row_no     = lt_row_no.
ENDFORM.                    "insert_row

*&---------------------------------------------------------------------*
*&      Form  delete_row
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM delete_row .
  DATA lo_alv_grid TYPE REF TO cl_gui_alv_grid.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv_grid.

  CHECK lo_alv_grid IS BOUND.

  PERFORM check_changed_data.

  DATA:
    lt_index_rows   TYPE lvc_t_row,
    lt_row_no       TYPE lvc_t_roid.

  CALL METHOD lo_alv_grid->get_selected_rows
    IMPORTING
      et_index_rows = lt_index_rows
      et_row_no     = lt_row_no.

  FIELD-SYMBOLS:
    <ls_row_no>       TYPE LINE OF lvc_t_roid.

  SORT lt_row_no BY row_id DESCENDING.

  LOOP AT lt_row_no ASSIGNING <ls_row_no>.
    PERFORM append_modif_log USING <ls_row_no>-row_id gc_mod_delete.
    DELETE <gt_table> INDEX <ls_row_no>-row_id.
  ENDLOOP.

  REFRESH: lt_index_rows, lt_row_no.

  CALL METHOD lo_alv_grid->set_selected_rows
    EXPORTING
      it_index_rows = lt_index_rows
      it_row_no     = lt_row_no.
ENDFORM.                    "delete_row

*&---------------------------------------------------------------------*
*&      Form  append_modif_log
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM append_modif_log USING iv_row_id TYPE i
                            iv_type TYPE csequence.
  FIELD-SYMBOLS:
    <ls_row>      TYPE any,
    <lv_mod_type> TYPE any,
    <lv_tab_styl> TYPE any.

  READ TABLE <gt_table> ASSIGNING <ls_row> INDEX iv_row_id.
  CHECK sy-subrc EQ 0.

  ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE <ls_row> TO <lv_tab_styl>.
  CHECK sy-subrc EQ 0.

  CHECK <lv_tab_styl> IS INITIAL.

  CLEAR <gs_modif>.
  MOVE-CORRESPONDING <ls_row> TO <gs_modif>.
  ASSIGN COMPONENT gc_mod_type_field OF STRUCTURE <gs_modif> TO <lv_mod_type>.
  <lv_mod_type> = iv_type.

  LOOP AT <gt_modif> ASSIGNING <ls_row>.
    CHECK <ls_row> EQ <gs_modif>.
    RETURN.
  ENDLOOP.

  APPEND <gs_modif> TO <gt_modif>.
ENDFORM.                    "append_modif_log

*&---------------------------------------------------------------------*
*&      Form  set_full_editable_row
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM set_full_editable_row CHANGING c_row TYPE any.
  DATA: ls_style TYPE lvc_s_styl,
        lt_style TYPE TABLE OF lvc_s_styl.

  FIELD-SYMBOLS <lv_style> TYPE any.

  CLEAR ls_style.
  ls_style-style = cl_gui_alv_grid=>mc_style_enabled.
  APPEND ls_style TO lt_style.

  SORT lt_style BY fieldname.

  ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE c_row TO <lv_style>.
  MOVE lt_style TO <lv_style>.
ENDFORM.                    "set_full_editable_row

*&---------------------------------------------------------------------*
*&      Form  save
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM save.
  REFRESH <gt_dblog>.

  PERFORM check_changed_data.
  CHECK sy-subrc EQ 0.

  PERFORM confirm_save.
  CHECK sy-subrc EQ 0.

  PERFORM save_mod_rows.
  CHECK sy-subrc EQ 0.

  PERFORM save_del_rows.
  CHECK sy-subrc EQ 0.

  PERFORM save_ins_rows.
  CHECK sy-subrc EQ 0.

  IF <gt_dblog>[] IS INITIAL.
    COMMIT WORK.
    PERFORM successfully_saved.
  ELSE.
    ROLLBACK WORK.
    PERFORM unsuccessfully_saved.
  ENDIF.
ENDFORM.                    "save

*&---------------------------------------------------------------------*
*&      Form  confirm_save
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM confirm_save.
  CONSTANTS:
    lc_dots TYPE string VALUE '..................'.

  DATA:
    lv_lines_ins(10) TYPE c,
    lv_lines_del(10) TYPE c,
    lv_lines_mod(10) TYPE c,
    lv_count         TYPE i,
    lv_msg(250)      TYPE c,
    lv_ansver(1)     TYPE c.

  PERFORM get_ins_rows_count CHANGING lv_lines_ins.
  PERFORM get_del_rows_count CHANGING lv_lines_del.
  PERFORM get_mod_rows_count CHANGING lv_lines_mod.

  lv_count = lv_lines_mod + lv_lines_del + lv_lines_ins.

  IF lv_count EQ 0.
    MESSAGE gc_text_no_edited_cell TYPE rs_c_success.
    MOVE 4 TO sy-subrc.
    EXIT.
  ENDIF.

  CONCATENATE:
  gc_text_del_rows space lc_dots space lv_lines_del INTO lv_msg+0(50),
  gc_text_ins_rows space lc_dots space lv_lines_ins INTO lv_msg+50(50),
  gc_text_mod_rows space lc_dots space lv_lines_mod INTO lv_msg+100(50).
  lv_msg+150(50) = |{ gc_text_proceed }?|.

  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
      titlebar              = gc_text_attention
      text_question         = lv_msg
      icon_button_1         = 'ICON_OKAY'
      icon_button_2         = 'ICON_CANCEL'
      default_button        = '1'
      display_cancel_button = ' '
    IMPORTING
      answer                = lv_ansver.
  IF lv_ansver EQ '1'.
    MOVE 0 TO sy-subrc.
  ELSE.
    MOVE 1 TO sy-subrc.
  ENDIF.
ENDFORM.                    "confirm_save

*&---------------------------------------------------------------------*
*&      Form  get_ins_rows_count
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_ins_rows_count CHANGING cv_count TYPE any.
  FIELD-SYMBOLS:
    <ls_row>      TYPE any,
    <lv_tab_styl> TYPE any.

  cv_count = 0.

  LOOP AT <gt_table> ASSIGNING <ls_row>.
    ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE <ls_row> TO <lv_tab_styl>.
    CHECK sy-subrc EQ 0.

    CHECK <lv_tab_styl> IS NOT INITIAL.
    ADD 1 TO cv_count.
  ENDLOOP.
ENDFORM.                    "get_ins_rows_count

*&---------------------------------------------------------------------*
*&      Form  get_del_rows_count
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_del_rows_count CHANGING cv_count TYPE any.
  FIELD-SYMBOLS:
    <ls_modif>    TYPE any,
    <ls_mod_type> TYPE any.

  cv_count = 0.

  LOOP AT <gt_modif> ASSIGNING <ls_modif>.
    ASSIGN COMPONENT gc_mod_type_field OF STRUCTURE <ls_modif> TO <ls_mod_type>.
    CHECK sy-subrc EQ 0.

    CHECK <ls_mod_type> EQ gc_mod_delete.
    ADD 1 TO cv_count.
  ENDLOOP.
ENDFORM.                    "get_del_rows_count

*&---------------------------------------------------------------------*
*&      Form  get_mod_rows_count
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_mod_rows_count CHANGING cv_count TYPE any.
  FIELD-SYMBOLS:
    <ls_modif>    TYPE any,
    <ls_mod_type> TYPE any.

  cv_count = 0.

  LOOP AT <gt_modif> ASSIGNING <ls_modif>.
    ASSIGN COMPONENT gc_mod_type_field OF STRUCTURE <ls_modif> TO <ls_mod_type>.
    CHECK sy-subrc EQ 0.

    CHECK <ls_mod_type> EQ gc_mod_update.
    ADD 1 TO cv_count.
  ENDLOOP.
ENDFORM.                    "get_mod_rows_count

*&---------------------------------------------------------------------*
*&      Form  save_mod_rows
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM save_mod_rows.
  DATA:
    lo_keys_mod TYPE REF TO data.

  FIELD-SYMBOLS:
    <ls_row>      TYPE any,
    <ls_modif>    TYPE any,
    <ls_mod_type> TYPE any,
    <lv_tab_styl> TYPE any,
    <ls_keys_mod> TYPE any.

  CREATE DATA lo_keys_mod LIKE <gs_keys>.
  ASSIGN lo_keys_mod->* TO <ls_keys_mod>.

  LOOP AT <gt_modif> ASSIGNING <ls_modif>.
    ASSIGN COMPONENT gc_mod_type_field OF STRUCTURE <ls_modif> TO <ls_mod_type>.
    CHECK sy-subrc EQ 0.

    CHECK <ls_mod_type> EQ gc_mod_update.

    MOVE-CORRESPONDING <ls_modif> TO <ls_keys_mod>.

    LOOP AT <gt_table> ASSIGNING <ls_row>.
      ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE <ls_row> TO <lv_tab_styl>.
      CHECK <lv_tab_styl> IS INITIAL.

      MOVE-CORRESPONDING <ls_row> TO <gs_keys>.
      CHECK <ls_keys_mod> EQ <gs_keys>.

      MOVE-CORRESPONDING <ls_row> TO <gs_tabln>.
      MODIFY (p_tab) FROM <gs_tabln>.

      PERFORM append_save_log USING <ls_modif> gc_mod_update sy-subrc.
      EXIT.
    ENDLOOP.
  ENDLOOP.

  MOVE 0 TO sy-subrc.
ENDFORM.                    "save_mod_rows

*&---------------------------------------------------------------------*
*&      Form  save_del_rows
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM save_del_rows.
  DATA:
    lv_where TYPE string.

  FIELD-SYMBOLS:
    <ls_modif>    TYPE any,
    <ls_mod_type> TYPE any.

  LOOP AT <gt_modif> ASSIGNING <ls_modif>.
    ASSIGN COMPONENT gc_mod_type_field OF STRUCTURE <ls_modif> TO <ls_mod_type>.
    CHECK sy-subrc EQ 0.

    CHECK <ls_mod_type> EQ gc_mod_delete.

    PERFORM key_to_where_expr USING <ls_modif> CHANGING lv_where.
    DELETE FROM (p_tab) WHERE (lv_where).

    PERFORM append_save_log USING <ls_modif> gc_mod_delete sy-subrc.
  ENDLOOP.

  MOVE 0 TO sy-subrc.
ENDFORM.                    "save_del_rows

*&---------------------------------------------------------------------*
*&      Form  save_ins_rows
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM save_ins_rows.
  FIELD-SYMBOLS:
    <ls_row>      TYPE any,
    <lv_tab_styl> TYPE any.

  LOOP AT <gt_table> ASSIGNING <ls_row>.
    ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE <ls_row> TO <lv_tab_styl>.
    CHECK <lv_tab_styl> IS NOT INITIAL.

    MOVE-CORRESPONDING <ls_row> TO <gs_tabln>.
    INSERT (p_tab) FROM <gs_tabln>.

    PERFORM append_save_log USING <ls_row> gc_mod_insert sy-subrc.
  ENDLOOP.

  MOVE 0 TO sy-subrc.
ENDFORM.                    "save_ins_rows

*&---------------------------------------------------------------------*
*&      Form  key_to_where_expr
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM key_to_where_expr USING i_row TYPE any
                       CHANGING cv_where TYPE csequence.
  DATA:
    lt_tab_where TYPE rsds_twhere,
    lt_tab_range TYPE rsds_trange.

  FIELD-SYMBOLS:
    <lv_value>     TYPE any,
    <ls_frange_t>  TYPE LINE OF rsds_frange_t,
    <ls_selopt_t>  TYPE LINE OF rsds_selopt_t,
    <ls_tab_range> TYPE LINE OF rsds_trange,
    <ls_tab_where> TYPE LINE OF rsds_twhere.

  REFRESH: lt_tab_where, lt_tab_range.
  CLEAR: cv_where.

  LOOP AT gt_dfies ASSIGNING <gs_dfies>.
    CHECK: <gs_dfies>-datatype  NE 'CLNT',
           <gs_dfies>-keyflag   EQ 'X'.

    ASSIGN COMPONENT <gs_dfies>-fieldname OF STRUCTURE i_row TO <lv_value>.
    CHECK sy-subrc EQ 0.

    APPEND INITIAL LINE TO lt_tab_range ASSIGNING <ls_tab_range>.
    <ls_tab_range>-tablename = p_tab.

    APPEND INITIAL LINE TO <ls_tab_range>-frange_t ASSIGNING <ls_frange_t>.
    <ls_frange_t>-fieldname = <gs_dfies>-fieldname.

    APPEND INITIAL LINE TO <ls_frange_t>-selopt_t ASSIGNING <ls_selopt_t>.
    <ls_selopt_t>-sign = 'I'.
    <ls_selopt_t>-option = 'EQ'.
    <ls_selopt_t>-low = <lv_value>.
  ENDLOOP.

  CALL FUNCTION 'FREE_SELECTIONS_RANGE_2_WHERE'
    EXPORTING
      field_ranges  = lt_tab_range
    IMPORTING
      where_clauses = lt_tab_where.

  READ TABLE lt_tab_where WITH KEY tablename = p_tab ASSIGNING <ls_tab_where>.
  CHECK sy-subrc EQ 0.

  CONCATENATE LINES OF <ls_tab_where>-where_tab
    INTO cv_where SEPARATED BY space.
ENDFORM.                    "key_to_where_expr

*&---------------------------------------------------------------------*
*&      Form  append_save_log
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM append_save_log USING i_row TYPE any
                           iv_mod_type TYPE csequence
                           iv_subrc TYPE i.
  FIELD-SYMBOLS <ls_dblog> TYPE any.
  FIELD-SYMBOLS <lv_msg_text> TYPE any.

  CHECK iv_subrc NE 0.

  IF iv_subrc NE 4.
    MESSAGE gc_text_unknown_db_error TYPE rs_c_error.
  ENDIF.

  APPEND INITIAL LINE TO <gt_dblog> ASSIGNING <ls_dblog>.
  MOVE-CORRESPONDING i_row TO <ls_dblog>.

  ASSIGN COMPONENT gc_msg_text_field OF STRUCTURE <ls_dblog> TO <lv_msg_text>.
  CHECK sy-subrc EQ 0.

  CASE iv_mod_type.
    WHEN gc_mod_insert.
      <lv_msg_text> = gc_text_db_primary_exists.
    WHEN gc_mod_update.
      <lv_msg_text> = gc_text_db_key_exists.
    WHEN gc_mod_delete.
      <lv_msg_text> = gc_text_db_not_found.
    WHEN OTHERS.
      MESSAGE gc_text_unknown_db_error TYPE rs_c_error.
  ENDCASE.
ENDFORM.                    "append_save_log

*&---------------------------------------------------------------------*
*&      Form  successfully_saved
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM successfully_saved.
  FIELD-SYMBOLS:
    <ls_row>      TYPE any,
    <lv_tab_styl> TYPE any.

  REFRESH: <gt_dblog>, <gt_modif>.

  LOOP AT <gt_table> ASSIGNING <ls_row>.
    ASSIGN COMPONENT gc_tab_styl_field OF STRUCTURE <ls_row> TO <lv_tab_styl>.
    CLEAR <lv_tab_styl>.
  ENDLOOP.

  MESSAGE s208 WITH gc_text_save_success.
  MOVE 0 TO sy-subrc.
ENDFORM.                    "successfully_saved

*&---------------------------------------------------------------------*
*&      Form  unsuccessfully_saved
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM unsuccessfully_saved.
  DATA:
    lt_fcat   TYPE slis_t_fieldcat_alv,
    ls_layout TYPE slis_layout_alv.

  FIELD-SYMBOLS:
    <ls_fcat>  TYPE slis_fieldcat_alv,
    <ls_row>   TYPE any,
    <lv_field> TYPE any.

  READ TABLE <gt_dblog> INDEX 1 ASSIGNING <ls_row>.
  CHECK sy-subrc EQ 0.

  REFRESH: lt_fcat.

  LOOP AT gt_dfies ASSIGNING <gs_dfies>.
    ASSIGN COMPONENT <gs_dfies>-fieldname OF STRUCTURE <ls_row> TO <lv_field>.
    CHECK sy-subrc EQ 0.

    APPEND INITIAL LINE TO lt_fcat ASSIGNING <ls_fcat>.
    PERFORM fill_fcat_using_fname USING <gs_dfies>-fieldname CHANGING <ls_fcat>.

    CLEAR <ls_fcat>-key.
    <ls_fcat>-emphasize = 'C110'.
  ENDLOOP.

  APPEND INITIAL LINE TO lt_fcat ASSIGNING <ls_fcat>.
  <ls_fcat>-fieldname = gc_msg_text_field.
  <ls_fcat>-emphasize = 'C700'.

  CLEAR ls_layout.
  ls_layout-zebra  = 'X'.
  ls_layout-colwidth_optimize = 'X'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'PF_STATUS_SET_DB_LOG'
      it_fieldcat              = lt_fcat[]
      is_layout                = ls_layout
    TABLES
      t_outtab                 = <gt_dblog>.

  MESSAGE s208 WITH gc_text_save_error.
  MOVE 0 TO sy-subrc.
ENDFORM.                    "unsuccessfully_saved

*&---------------------------------------------------------------------*
*&      Form  PF_STATUS_SET_DB_LOG
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM pf_status_set_db_log USING it_extab TYPE STANDARD TABLE. "#EC CALLED
  APPEND '&EB9' TO it_extab.

  SET TITLEBAR 'MAIN' WITH p_tab gc_text_error_log.
  SET PF-STATUS 'STDPOPUP_FULLSCREEN' OF PROGRAM 'SAPLSLVC_FULLSCREEN' EXCLUDING it_extab.
ENDFORM.                                            " PF_STATUS_SET_DB_LOG

*&---------------------------------------------------------------------*
*&      Form  IMPORT_FROM_EXCEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM import_from_excel.
  DATA: lv_filename TYPE localfile.

  CALL FUNCTION 'WS_FILENAME_GET'
    EXPORTING
      mask     = ',Excel,*.xls;*.xlsx;*.xlsm;'
      mode     = 'O'
      title    = gc_text_select_table
    IMPORTING
      filename = lv_filename
    EXCEPTIONS
      OTHERS   = 1.
  CHECK sy-subrc EQ 0.

  DATA lt_raw_tab(4096) TYPE c OCCURS 0.
  DATA lo_table TYPE REF TO data.
  FIELD-SYMBOLS <lt_table> TYPE STANDARD TABLE.

  CREATE DATA lo_table TYPE STANDARD TABLE OF (p_tab).
  ASSIGN lo_table->* TO <lt_table>.

  CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
    EXPORTING
      i_line_header        = 'X'
      i_tab_raw_data       = lt_raw_tab
      i_filename           = lv_filename
    TABLES
      i_tab_converted_data = <lt_table>.

  FIELD-SYMBOLS <ls_row_src> TYPE any.
  FIELD-SYMBOLS <ls_row_dest> TYPE any.

  LOOP AT <lt_table> ASSIGNING <ls_row_src>.
    APPEND INITIAL LINE TO <gt_table> ASSIGNING <ls_row_dest>.
    MOVE-CORRESPONDING <ls_row_src> TO <ls_row_dest>.
    PERFORM set_full_editable_row CHANGING <ls_row_dest>.
  ENDLOOP.
ENDFORM.      " IMPORT_FROM_EXCEL

*&---------------------------------------------------------------------*
*&      Form  REFRESH
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM refresh.
  DATA lo_alv TYPE REF TO cl_gui_alv_grid.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lo_alv.

  CALL METHOD lo_alv->refresh_table_display
    EXPORTING
      is_stable = CONV #( 'XX' )
    EXCEPTIONS
      finished  = 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.      " REFRESH


Сайт программы: http://abap4.ru/zse16n.html

Автор:  Yozhhhhh [ Сб, авг 01 2020, 17:15 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

Если Вы создали программу, которая обновляет таблицы, при этом есть директива заказчика НЕ обновлять таблицы (и потому Вам закрыли стандартные возможности), то через создание этой программы (которая полностью и так дублирует стандартный функционал) Вы нарушили все ту же директиву заказчика/компании. То есть у него на виду Вы делаете ровно то же самое, а отсутствие какой-то реакции с его стороны - это либо его самодурство, либо повод запросить нормальные полномочия и не городить огород. Это разве не очевидно?

Я уже молчу про "можно обновлять и не Z таблицы". Это какие, стесняюсь спросить? Лупить настроечные таблицы в продуктиве (или что еще хуже) таблицы переменных данных?

Извините за излишнюю прямоту. Как способ интересного досуга и развития abap скила это, несомненно, интересная Вам задача. Но она полностью дублирует имеющийся стандартный функционал, да еще и нарушает принятую у компании концепцию полномочий. На нормальном проекте это не вызовет никакого интереса.

Автор:  kernel [ Сб, авг 01 2020, 17:47 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

Yozhhhhh написал:
Но она полностью дублирует имеющийся стандартный функционал

Научите править таблицы через стандартный функционал. Не используя отладку и SE16N_INTERFACE, разумеется.

Автор:  Yozhhhhh [ Сб, авг 01 2020, 18:22 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

kernel написал(а):
Научите править таблицы через стандартный функционал. Не используя отладку и SE16N_INTERFACE, разумеется.

Вы меня, видимо, не очень внимательно читаете.
На каком основании Вы собрались править таблицы в продуктиве?
Если это пользовательские настроечные Z-таблицы, то создавайте к ним диалог ведения и правьте в SM30.
Если это Z-таблицы переменных данных, заполняемые в конкретных ad-hoc транзакциях, то в этих транзакциях закладывайте возможность правки этих таблиц.
Если это стандартные настроечные таблицы и ракурсы, то обеспечивайте их заполнение в диалогах в системах разработки, а потом транспорт.
Если это стандартные таблицы переменных данных, то Вы вообще не имеете права их изменять.
4 простейших кейса, других не дано.

Автор:  LKU [ Пн, авг 03 2020, 18:53 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

Я так понял, kernel работает непосредственно на Заказчика (возможно, в поддержке), а Yozhhhhh смотрит на вещи с позиции внешнего консультанта.
Отсюда разная картина мира.

Объективно, у сотрудников поддержки компании, использующей SAP ERP, бывают ситуации, когда имеется производственная необходимость поправить данные в продуктиве. Бывает, что даже в стандартных таблицах для стандартных документов (скажем, ekpo).

Но для этого вполне достаточно SE16n + полномочий на отладчик + внутренних организационно-распорядительных документов, разрешающих сотруднику такую деятельность.
Знаю компанию, где для таких случаев используются так называемые FireFighter пользователи, логины/пароли к которым разово выдаются сотрудникам под каждый случай в GRC с регистрацией причины (ссылки на инцидент)

Автор:  LKU [ Пн, авг 03 2020, 18:57 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

Добавлю: как и Yozhhhhh, я тоже считаю крайне плохой идею правки данных в продуктивной системе, когда Компания-владелец системы это явно запрещает вам делать.

Автор:  Kengur [ Ср, авг 05 2020, 14:58 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

kernel написал(а):
Сайт программы: http://abap4.ru/zse16n.html

kernel полезная программа. часто хотят ракурс ведения с извращениями с блокировками. выложи ее через abapGit и на гитхаб положи можешь сразу в сообщество sap-russia это сделать

Автор:  pberezin [ Пт, авг 07 2020, 15:42 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

Что хочу, то наколочу в таблицу.
Табличный эксель за цену сап-коробки получается :D

Если ещё Z-аналог DBACOCKPIT-a есть, то совсем супер.

Автор:  bdmalex [ Пт, авг 07 2020, 17:19 ]
Заголовок сообщения:  Re: Z-программа для редактирования таблиц БД

pberezin написал:
Если ещё Z-аналог DBACOCKPIT-a есть, то совсем супер.


А чем вас стандартный не устраивает ?

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/