Текущее время: Чт, авг 06 2020, 02:02

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
 Заголовок сообщения: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Сб, авг 01 2020, 13:00 
Начинающий
Начинающий
Аватара пользователя

Зарегистрирован:
Сб, июн 08 2019, 12:01
Сообщения: 18
Всем привет!

Выкладываю свой аналог 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


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Сб, авг 01 2020, 17:15 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Ср, фев 21 2007, 08:50
Сообщения: 1270
Откуда: Москва
Пол: Мужской
Если Вы создали программу, которая обновляет таблицы, при этом есть директива заказчика НЕ обновлять таблицы (и потому Вам закрыли стандартные возможности), то через создание этой программы (которая полностью и так дублирует стандартный функционал) Вы нарушили все ту же директиву заказчика/компании. То есть у него на виду Вы делаете ровно то же самое, а отсутствие какой-то реакции с его стороны - это либо его самодурство, либо повод запросить нормальные полномочия и не городить огород. Это разве не очевидно?

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

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


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Сб, авг 01 2020, 17:47 
Начинающий
Начинающий
Аватара пользователя

Зарегистрирован:
Сб, июн 08 2019, 12:01
Сообщения: 18
Yozhhhhh написал:
Но она полностью дублирует имеющийся стандартный функционал

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


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Сб, авг 01 2020, 18:22 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Ср, фев 21 2007, 08:50
Сообщения: 1270
Откуда: Москва
Пол: Мужской
kernel написал(а):
Научите править таблицы через стандартный функционал. Не используя отладку и SE16N_INTERFACE, разумеется.

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


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Пн, авг 03 2020, 18:53 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4603
Откуда: Москва
Пол: Мужской
Я так понял, kernel работает непосредственно на Заказчика (возможно, в поддержке), а Yozhhhhh смотрит на вещи с позиции внешнего консультанта.
Отсюда разная картина мира.

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

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

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Пн, авг 03 2020, 18:57 
Гуру-модератор
Гуру-модератор
Аватара пользователя

Зарегистрирован:
Вт, май 17 2005, 13:35
Сообщения: 4603
Откуда: Москва
Пол: Мужской
Добавлю: как и Yozhhhhh, я тоже считаю крайне плохой идею правки данных в продуктивной системе, когда Компания-владелец системы это явно запрещает вам делать.

_________________
Удача - результат нашего желания (© А. Нортон)


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Z-программа для редактирования таблиц БД
СообщениеДобавлено: Ср, авг 05 2020, 14:58 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, дек 20 2007, 18:21
Сообщения: 1479
kernel написал(а):
Сайт программы: http://abap4.ru/zse16n.html

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

_________________
я твой сап эфай внедрял
BAdI-позитив


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Ahrefs [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB