Всё-таки нужен код. Привожу ниже для демонстрации явления.
На начальном экране выбора указывается таблица. После открытия грида можно постирать "Мандант" в нескольких строках и затем выполнить проверку, например, нажатием на "дискету" Save. Возникнет "Журнал ошибок". Закройте "крестиком" его и опять нажмите на Save. Повторите несколько раз - журнал нормально открывается и закрывается.
Восстановите стертые значения или удалите эти строки с пустыми "мандантами". Снова нажмите на Save. Теперь, когда данные в ячейках нормальные, проверка идёт дальше и включается проверка "между строками" (ошибка данного типа в программе просто имитируется записью соответствующего сообщения в протокол). Итак, после нажатия на Save в первый раз появляется журнал с "вертикальной" ошибкой. Закройте его "крестиком" и еще раз (второй) нажмите на Save... Теперь попробуйте вернуться к гриду...

Самый же быстрый способ получения эффекта (ничего не стирая) - после открытия грида нажать на Save, закрыть журнал ошибок и опять нажать на Save. Выйти из "зависания" - по F3.
Code:
REPORT zzjob_kku_126_grid_protocol.
* Шаги по внедрению этой программы в Вашу систему:
*
* 1. SE38 или SE80: создать данную программу
*
* 2. SE80: создать экран 0100
*
* 3. Screen Painter: на экране 0100 создать 'Спец.упр.элемент'
* CONT_AREA
*
* 4. SE80: для экрана 0100 установить переменную OK_CODE для элемента OK
*
* 5. SE80: коду на закладке 'ЛогикаВыполн' экрана 0100 придать вид:
*
* PROCESS BEFORE OUTPUT.
* MODULE pbo_0100.
* PROCESS AFTER INPUT.
* MODULE pai_0100.
*
* 6. SE80: создать GUI-статус STATUS100, назначить функции BACK, EXIT, SAVE
* стандартным иконкам (либо создайте свои собственные кнопки)
* ("Шаги" заимствованы отсюда: http://www.kerum.pl/infodepot/00034
* - ОЧ.понравилось как оформлено!)
TYPE-POOLS: slis.
PARAMETERS: p_dbtab TYPE tabname DEFAULT 'T001'.
CLASS lcl_event_receiver DEFINITION DEFERRED.
DATA:
gs_layout TYPE lvc_s_layo,
grid TYPE REF TO cl_gui_alv_grid,
custom_container TYPE REF TO cl_gui_custom_container,
event_receiver TYPE REF TO lcl_event_receiver,
gr_data_changed TYPE REF TO cl_alv_changed_data_protocol,
g_repid TYPE sy-repid,
ok_code TYPE sy-ucomm,
it_ref TYPE REF TO data,
wa_ref TYPE REF TO data,
lflagedit(1) TYPE c,
gt_fieldcat TYPE lvc_t_fcat.
FIELD-SYMBOLS:
<it_grid> TYPE STANDARD TABLE,
<wa_grid> TYPE ANY.
START-OF-SELECTION.
lflagedit = 'X'.
PERFORM read_data.
CALL SCREEN 100.
*----------------------------------------------------------------------*
* CLASS lcl_event_receiver DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_event_receiver DEFINITION.
PUBLIC SECTION.
METHODS:
handle_data_changed
FOR EVENT data_changed OF cl_gui_alv_grid
IMPORTING e_onf4
e_onf4_before
e_onf4_after
er_data_changed
sender.
PRIVATE SECTION.
METHODS:
perform_semantic_checks
IMPORTING
er_data_changed TYPE REF TO cl_alv_changed_data_protocol.
ENDCLASS. "lcl_event_receiver DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_event_receiver IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_event_receiver IMPLEMENTATION.
METHOD handle_data_changed.
CALL METHOD perform_semantic_checks( er_data_changed ).
gr_data_changed = er_data_changed.
ENDMETHOD. " handle_data_changed
*-------------------------------------------------------
METHOD perform_semantic_checks.
FIELD-SYMBOLS: <tab> TYPE STANDARD TABLE,
<mandt> TYPE mandt.
DATA: ls_good TYPE lvc_s_modi.
TYPES: BEGIN OF type_row,
row_id TYPE lvc_s_modi-row_id,
tabix TYPE lvc_s_modi-tabix,
END OF type_row.
DATA: it_row TYPE SORTED TABLE OF type_row
WITH UNIQUE KEY table_line,
wa_row LIKE LINE OF it_row.
LOOP AT er_data_changed->mt_good_cells INTO ls_good.
MOVE-CORRESPONDING ls_good TO wa_row.
COLLECT wa_row INTO it_row.
ENDLOOP.
ASSIGN er_data_changed->mp_mod_rows->* TO <tab>.
LOOP AT it_row INTO wa_row.
READ TABLE <tab> INTO <wa_grid> INDEX wa_row-tabix.
"проверка на заполненность поля мандант
ASSIGN COMPONENT 'MANDT' OF STRUCTURE <wa_grid> TO <mandt>.
IF <mandt> IS INITIAL.
PERFORM add_protocol
USING er_data_changed
wa_row-row_id
wa_row-tabix
'MANDT'
'Поле обязательного ввода'
'' '' ''.
ENDIF.
ENDLOOP.
ENDMETHOD. " perform_semantic_checks
ENDCLASS. "lcl_event_receiver IMPLEMENTATION
*&---------------------------------------------------------------------*
*& Form init_fieldcat
*&---------------------------------------------------------------------*
FORM init_fieldcat.
DATA oref_structure TYPE REF TO cl_abap_structdescr.
DATA wa_comp TYPE abap_compdescr.
"получение структуры таблицы
oref_structure ?=
cl_abap_typedescr=>describe_by_name( p_dbtab ).
* создать описание колонок грида
CLEAR: gt_fieldcat.
LOOP AT oref_structure->components INTO wa_comp.
PERFORM addcat1
USING wa_comp-name p_dbtab wa_comp-name 'X' ''.
ENDLOOP.
ENDFORM. "init_fieldcat
*&---------------------------------------------------------------------*
*& Form read_data
*&---------------------------------------------------------------------*
FORM read_data.
CREATE DATA it_ref TYPE STANDARD TABLE OF (p_dbtab).
ASSIGN it_ref->* TO <it_grid>.
CREATE DATA wa_ref LIKE LINE OF <it_grid>.
ASSIGN wa_ref->* TO <wa_grid>.
CLEAR: <it_grid>.
SELECT *
INTO CORRESPONDING FIELDS OF TABLE <it_grid>
FROM (p_dbtab).
ENDFORM. "read_data
*&---------------------------------------------------------------------*
*& Form addcat1
*&---------------------------------------------------------------------*
FORM addcat1 USING fieldname ref_table ref_field cedit ctext.
DATA: ls_fieldcat LIKE LINE OF gt_fieldcat.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = fieldname.
ls_fieldcat-ref_table = ref_table.
ls_fieldcat-ref_field = ref_field.
IF lflagedit = 'X'.
ls_fieldcat-edit = cedit.
ENDIF.
IF NOT ctext IS INITIAL.
ls_fieldcat-coltext = ctext.
ls_fieldcat-seltext = ctext.
ENDIF.
ls_fieldcat-col_opt = 'X'. "Подгонка по ширине
APPEND ls_fieldcat TO gt_fieldcat.
ENDFORM. "AddCat1
*----------------------------------------------------------------------*
* MODULE pai_100 INPUT
*----------------------------------------------------------------------*
MODULE pai_100 INPUT.
CASE ok_code.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'EXIT'.
LEAVE PROGRAM.
"LEAVE TO SCREEN 100.
WHEN 'SAVE'.
PERFORM check_unique. "некоторая вертикальная проверка между записями
ENDCASE.
CLEAR ok_code.
ENDMODULE. "pai_100 INPUT
*----------------------------------------------------------------------*
* MODULE pbo_100 OUTPUT
*----------------------------------------------------------------------*
MODULE pbo_100 OUTPUT.
DATA: lt_exclude TYPE ui_functions,
i_save TYPE char01,
l_variant LIKE disvariant.
DATA: extab TYPE slis_t_extab WITH HEADER LINE.
CHECK custom_container IS INITIAL.
IF lflagedit = ''.
extab-fcode = 'SAVE'.
APPEND extab.
ENDIF.
SET PF-STATUS 'STATUS100' EXCLUDING extab.
g_repid = sy-repid.
* create a custom container control for our ALV Control
CREATE OBJECT custom_container
EXPORTING
container_name = 'CONT_AREA'.
IF sy-subrc NE 0.
* add your handling, for example
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = g_repid
txt2 = sy-subrc
txt1 = 'The control could not be created'(510).
ENDIF.
* create an instance of alv control
CREATE OBJECT grid
EXPORTING
i_parent = custom_container.
* Создание списка колонок
PERFORM init_fieldcat.
* Both user-defined and global layouts can be saved.
i_save = 'A'.
l_variant-report = sy-repid.
CALL METHOD grid->set_table_for_first_display
EXPORTING
is_layout = gs_layout
it_toolbar_excluding = lt_exclude
i_save = i_save
is_variant = l_variant
CHANGING
it_outtab = <it_grid>
it_fieldcatalog = gt_fieldcat.
* ->Create Object to receive events and link them to handler methods.
* When the ALV Control raises the event for the specified instance
* the corresponding method is automatically called.
CREATE OBJECT event_receiver.
SET HANDLER event_receiver->handle_data_changed FOR grid.
ENDMODULE. "pbo_100 OUTPUT
*&---------------------------------------------------------------------*
*& Form add_protocol
*&---------------------------------------------------------------------*
FORM add_protocol
USING er_data_changed TYPE REF TO cl_alv_changed_data_protocol
nrowid TYPE lvc_s_modi-row_id
ntabix TYPE lvc_s_modi-tabix
i_fieldname TYPE lvc_fname
i_msgv1 TYPE any
i_msgv2 TYPE any
i_msgv3 TYPE any
i_msgv4 TYPE any.
DATA: cfield LIKE i_fieldname.
cfield = i_fieldname.
TRANSLATE cfield TO UPPER CASE.
CALL METHOD er_data_changed->add_protocol_entry
EXPORTING
i_msgid = '0K'
i_msgno = '000'
i_msgty = 'E'
i_msgv1 = i_msgv1
i_msgv2 = i_msgv2
i_msgv3 = i_msgv3
i_msgv4 = i_msgv4
i_fieldname = cfield
i_row_id = nrowid.
ENDFORM. "add_protocol
*&---------------------------------------------------------------------*
*& Form check_unique
*&---------------------------------------------------------------------*
FORM check_unique.
DATA: protocol_is_visible TYPE int4,
l_valid TYPE c.
CALL METHOD grid->check_changed_data
IMPORTING
e_valid = l_valid.
IF gr_data_changed IS NOT BOUND.
CREATE OBJECT gr_data_changed
EXPORTING
i_calling_alv = grid.
ELSE.
CALL METHOD gr_data_changed->refresh_protocol.
ENDIF.
"какая-то проверка (бла-бла-бла)
"перебираем основной грид,
"следя уникальностью проверяемых полей
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"-----------------------------
"как бы по результатам проверки добавляем запись в протокол
PERFORM add_protocol
USING gr_data_changed
1 "nrowid
0 "ntabix - не используется
'MANDT'
'Дублирование КЛЮЧА таблицы из одной'
'из вышележащих строк'
''
''.
CALL METHOD gr_data_changed->protocol_is_visible
IMPORTING
visible = protocol_is_visible.
IF protocol_is_visible IS INITIAL.
CALL METHOD gr_data_changed->display_protocol.
ENDIF.
ENDFORM. "Check_Unique