Frontmaniaac
Frontmaniaac

Reputation: 250

Highlight specific line when making before save validation in a maintenance view?

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

Answers (2)

Philipp
Philipp

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

AlexSchell
AlexSchell

Reputation: 1722

I created a test scenario to show the solution. Simple table for which a maintenance view would be created is:

TMG Sample table

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: TMG 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:

TMG Form routine

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:

TMG Highlighting

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:

TMG - Flow logic

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

Related Questions