Reputation: 250
I have implemented the event 01 - Before saving the data in the database
for a table in the Table Maintenance Generator TMG.
In the implementation code I am looping over the total
table, checking for a certain field to satisfy some condition.
In case of the failed check be the field should be marked as wrong and the error message is given out using:
MESSAGE 'Please correct this field' TYPE 'S' DISPLAY LIKE 'E'.
vim_abort_saving = abap_true.
This works, but if there are, for example, 10 records given at once, I would like the program to mark all wrong lines, or fields, if that is possible.
I have searched for many solutions, but none have worked.
One idea was to use VIEW_SET_PF_STATUS
which gives a similar effect that I want to achieve. But it does not work when I use this event in FORM
.
Upvotes: 0
Views: 2220
Reputation: 69703
The usual way to do error handling on a per-field level and direct the user specifically to the field where they made an invalid entry is by using a module that is executed specifically for a field. This is handled by the dynpro logic. In that case, you will see something like this in the PAI of the dynpro:
LOOP AT itab INTO wa.
FIELD dynp_field MODULE mod ON INPUT.
ENDLOOP.
This means that if the user entered something in a field dynp_field
of the table bound to itab
, then the module mod
gets executed. wa
will contain the current line of the table during the execution of the module. When you now create a MESSAGE ... TYPE 'E'
during that module (TYPE 'E'
, not just DISPLAY LIKE 'E'
!), then SAPGui will react to that by directing the user to that exact cell of the table while displaying the error message.
You can find the LOOP
that goes trough the EXTRACT
(entries visible on the SM30 screen) table, by going to the generated screen in SE80
, or Table->Table Maintenance Genarator
and then click on your screen number
.
Upvotes: 2
Reputation: 1722
I created a test scenario to show the solution. Simple table for which a maintenance view would be created is:
The semantic meaning of this table does not matter in this case - it is just a simple table with two text fields which we would like to be able to maintain via SM30
.
We create a simple maintenance view for the table and add an event:
Added FORM routine CHECK_OBJECT_EVENT_01 (choose any include you like, it does not matter) for the event 01 - Before saving the data in the database
:
FORM check_object_event_01.
First create a structure type, which includes the table which we maintain and additionally the VIMTBFLAGS structure: Flag structure for view maint. tool: Flags for tables
. It would give us the possibility to access these flag fields:
TYPES BEGIN OF ty_s_table.
INCLUDE STRUCTURE zqm_cu_audobj_aa.
INCLUDE STRUCTURE vimtbflags.
TYPES END OF ty_s_table.
Afterwards in case something needs to be updated (<status>-upd_flag
= 'X') and not deleted (<action>
<> 'D') we are looping over the total
table:
DATA: ls_table TYPE ty_s_table,
lv_index LIKE sy-tabix,
lv_valid TYPE abap_bool VALUE abap_false,
lv_error TYPE abap_bool VALUE abap_false.
IF <status>-upd_flag = 'X' AND <action> <> 'D'.
LOOP AT total.
READ TABLE extract WITH KEY <vim_xtotal_key>.
IF sy-subrc EQ 0.
lv_index = sy-tabix.
ENDIF.
MOVE total TO ls_table.
PERFORM validate_object_string
USING ls_table-object_string
CHANGING lv_valid.
IF lv_valid = abap_false.
lv_error = abap_true.
ls_table-vim_mark = 'M'.
ELSE.
ls_table-vim_mark = ' '.
ENDIF.
MOVE ls_table TO total.
MODIFY total.
IF lv_index > 0.
extract = total.
MODIFY extract INDEX lv_index.
ENDIF.
ENDLOOP.
ENDIF.
IF lv_error = abap_true.
vim_abort_saving = 'X'.
MESSAGE 'Please correct this field' TYPE 'S' DISPLAY LIKE 'E'.
ENDIF.
ENDFORM.
Inside the loop we check the entered value for object_string
field of the table in a separate validate_object_string
form routine against the allowed values. For this simple test case I check if the value equals to 'Test', in which case we should mark (highlight) this line - this is done by assigning the value of vim_mark
field to M
. In case multiple entries are invalid they all will be marked (highlighted).
FORM validate_object_string USING iv_value TYPE plmt_audit_object_value_text
CHANGING cv_valid TYPE abap_bool.
cv_valid = abap_true.
IF iv_value = 'Test'.
cv_valid = abap_false.
ENDIF.
ENDFORM.
Afterwards if some of the entries were not successfully validated, we abort the saving by setting the vim_abort_saving
to 'X' and giving out an error message:
Next issue is to set the cursor on the invalid entry. To do it we have to modify PBO
for the screen generated by TMG. We can find the flow logic for the screen in SE80
inside the function group, double-clicking on the Maint.Screen No.
inside TMG or go from TMG to Environment -> Modification -> Maintenance Screens
-> select the screen:
I have added the MODULE check_object_pbo
, there is a code:
MODULE check_object_pbo OUTPUT.
LOOP AT SCREEN.
IF screen-intensified = 1.
SET CURSOR FIELD 'ZQM_CU_AUDOBJ_AA-OBJECT_STRING' LINE <vim_tctrl>-current_line.
EXIT.
ENDIF.
ENDLOOP.
ENDMODULE.
We look for the intensified screen element (it was set to intensified by routine in PBO generated by TMG based on the vim_mark
flag) and set the cursor to this field.
Please note that changes made to the screen flow logic would be overwritten if the maintenance view is regenerated - do not forget to add this change again (you can also copy the dynpro to some other number as a backup and afterwards copy it back again).
Upvotes: 3