Showing posts with label SEARCH HELP. Show all posts
Showing posts with label SEARCH HELP. Show all posts

Thursday, November 1, 2018

Search and value help for custom fields - tx. SM_CRM - Seach: Change documents

As I am still newbie the Solution manager seems to me still as miracle black box. There are nice techniques like e.g. dynamic mapping of searched database table fields and class methods within table CRMC_REPDY.

Version


My task was to make alive search of already made custom fields. The thing is the version of Solution manager heavily matters here. In my case it was Solman 7.1.

I found two precious tutorials to follow:


  1. Basically all the stuff should work according to perfect manual of Peter Weigel.
    http://www.hybrid-eichhörnchen.de/business-transaction-search-enhancement/
  2. Second valuable article is describing how to work with web UI written by Robyn Osby
    https://blogs.sap.com/2015/02/06/how-to-update-smcrm-search-criteria-to-report-based-on-the-value-of-a-custom-field/

The corner stone is appending of custom fields to structures CRMST_QUERY_SRV_REQ_BTIL and CRMST_QUERY_R_SRV_REQ_BTIL. It has made the search abilities alive. Then there is a need to play with web UI and create a new Custom configuration area.

Unfortunately value help within list-box on search page for custom field did not work at all. I have touched all the ATX_* tables like e.g. ATX_RUN_FIELDDEF according to Peter's manual. Still no gain. I have spend bunch of time by creating various custom search helps and their proper associations, by playing with data dictionary. Nothing led to the goal in this Solman version.

Custom value help


I had already working search with custom fields on search and result page, but still no possible value lists.

Finally I found bellow steps to make it work. I had fixed value list within domain of data dictionary.


  • Open Changed document search page
  • Locate the custom field - select it to have the focus on it
  • Press key F2, you should see something like:








  • Take here Application component name: AIC_CMCD_S 
  • Run tx. BSP_WD_CMPWB and use the component name click display
  • Within the tree locate the proper View - see the picture. 







The view leads you to a main implementation class CL_AIC_CMCD_SEARCHQUERYVI_IMPL. Now it becomes easy. Just enhance the class in a standard way with new methods for each custom field. The naming convention is what matters here to correctly trigger the method for field on the web page. So each value help method must start with prefix GET_V_ + field key name. In my case GET_V_ZZFLD00000K.

Content of the method could look like:

METHOD GET_V_ZZFLD00000K .

  DATA: lt_domain_entries TYPE STANDARD TABLE OF dd07v,
        lt_sel_table TYPE crmt_thtmlb_search_ddlb_nvp,
        ls_sel_table LIKE LINE OF lt_sel_table.

  FIELD-SYMBOLS : <fs_domain> TYPE dd07v.

  CALL FUNCTION 'DD_DOMVALUES_GET'
  EXPORTING
    domname        = 'CRM_BOOLEAN' " any dictionary domain... 
    TEXT           = 'X'
    langu          = sy-langu
  TABLES
    dd07v_tab      = lt_domain_entries
  EXCEPTIONS
    wrong_textflag = 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.
  ELSE.

    LOOP AT lt_domain_entries ASSIGNING <fs_domain>.
      ls_sel_table-KEY = <fs_domain>-domvalue_l.
      ls_sel_table-VALUE = <fs_domain>-ddtext.
      APPEND ls_sel_table TO lt_sel_table.
      CLEAR ls_sel_table.
    ENDLOOP.

    cs_result-ddlb_options = lt_sel_table.
  ENDIF.

ENDMETHOD.



Have fun with Solman ;-)


Other sources:
https://stackoverflow.com/questions/37372466/changing-default-dropdown-value-in-sap-crm-web-ui
http://saptechnical.com/Tutorials/CRM/Dropdown/Index.htm

















Sunday, November 5, 2017

Calendar week - dynpro field with tuned search help

As always, I hope this article can save someones time as I wasted time by googling and debugging. Here I want to describe two different approaches how to work with calendar week input field on dynpro, especially two search help options.

Simple dynpro field with given search help


Calendar week itself has NUMC(6) data format. When you are working with dynpro field you need type input as CHAR(7), remember standard search help returns separating dot in between. I found suitable in my case to use standard search help /BI0/OCALWEEK. You have to add just conversion exit, here it is PERI6. Now we have nice working stuff.

Dynpro settings:




Dynpro result:


Everything is simple enough and works just as you would expected, but....  There is one big but for me. The search helps starts somewhere in the deep past. Today I have year 2017, the default value is 6 year ago. The user is forced to scroll down too much to reach current year.




Search help with prefilled input parameters


So we have nice character (7) input field, conversion routines works Ok. So what is painkiller of above example? The answer is search help input parameters, by these you can influence given range of values. I decided to work with DATEFROM, because sy-datum is easily reachable.

Search help input parameters:




How to provide the input parameters? In my case I used ABAP and own F4 screen module. I wanted to have a list of weeks starting just few weeks ago, but not years.


So the result now looks like:





This is what I was exactly looking for. Search help starts from week I wanted.

Here is the solution:


On the screen "Flow logic" tab define module event trigger for F4 as e.g. below.

PROCESS ON VALUE-REQUEST. "F4
  FIELD gs_task_schd-cw MODULE f4_cw.

Screen settings:


Just conversion exit is still present within field properties - see below, but no search help any more. It is replaced by F4 module. Conversion exit works to convert data from screen to program (from CHAR7 to NUMC6), but not from F4 module to screen, that is why I have added manual call of conversion routine to the F4 module to display data in a correct way on the screen.




The module can looks like:


*&---------------------------------------------------------------------*
*&      Module  F4_CW  INPUT
*&---------------------------------------------------------------------*
*       Calendar week search help with preset (change week list)
*----------------------------------------------------------------------*
MODULE f4_cw INPUT.

  lcl_main=>self->o_ctrl_screen->screen_300_f4_cw(
    iv_screen_field = 'GS_TASK_SCHD-CW'
  ).

ENDMODULE.                 " F4_CW  INPUT


So the miracle here is the method screen_300_f4_cw.


Method definition:


             screen_300_f4_cw
              IMPORTING
                iv_screen_field          TYPE  dynfnam.

Method implementation:


  METHOD screen_300_f4_cw.

    DATA: lt_dynpfields         TYPE STANDARD TABLE OF dynpread,
          ls_dynpfields         LIKE LINE OF lt_dynpfields,
          ls_shlp_descr         TYPE shlp_descr,
          lt_shlp_return_values TYPE STANDARD TABLE OF ddshretval,
          lt_shlp_selopt        TYPE STANDARD TABLE OF ddshselopt,
          ls_shlp_selopt        LIKE LINE OF lt_shlp_selopt,
          lv_date               TYPE sydatum.

    " Get search help description
    CALL FUNCTION 'F4IF_GET_SHLP_DESCR'
      EXPORTING
        shlpname = '/BI0/OCALWEEK' " Standard search help name
        shlptype = 'SH'
      IMPORTING
        shlp     = ls_shlp_descr.

    " Ask FM F4IF_START_VALUE_REQUEST for return values - set the sign
    FIELD-SYMBOLS: <fs_interface> LIKE LINE OF ls_shlp_descr-interface.
    LOOP AT ls_shlp_descr-interface ASSIGNING <fs_interface>.
      <fs_interface>-valfield = 'X'.
    ENDLOOP.

    " Note: There is internaly used build in function DATE_CONV_EXT_TO_INT that is later used, it accepts DDMMYYYY,
    " not other e.g. YYYYMMDD - it causes dumps. So sy-datum can not be used directly
    lv_date = sy-datum - 21. " start some weeks ago
    CONCATENATE lv_date+6(2) lv_date+4(2) lv_date+0(4) INTO ls_shlp_selopt-low.

    " Preset default week interval of initial search help screen (not to start in stone age)
    ls_shlp_selopt-shlpname  = '/BI0/OCALWEEK'.
    ls_shlp_selopt-shlpfield = 'DATEFROM'.
    ls_shlp_selopt-sign      = 'I'.
    ls_shlp_selopt-option    = 'GT'.
    " ls_shlp_selopt-high     = ''.
    APPEND ls_shlp_selopt TO lt_shlp_selopt.
    ls_shlp_descr-selopt = lt_shlp_selopt.

    " Trigger search help popup screen
    CALL FUNCTION 'F4IF_START_VALUE_REQUEST'
      EXPORTING
        shlp          = ls_shlp_descr
      TABLES
        return_values = lt_shlp_return_values.

    FIELD-SYMBOLS: <fs_return_value> LIKE LINE OF lt_shlp_return_values.
    LOOP AT lt_shlp_return_values ASSIGNING <fs_return_value>.

      " Run manually value conversion exit
      CALL FUNCTION 'CONVERSION_EXIT_PERI6_OUTPUT'
        EXPORTING
          input  = <fs_return_value>-fieldval
        IMPORTING
          output = <fs_return_value>-fieldval.

      " Fill screen field
      ls_dynpfields-fieldname  = iv_screen_field.
      ls_dynpfields-fieldvalue = <fs_return_value>-fieldval.
      APPEND ls_dynpfields TO lt_dynpfields.
      EXIT. " process just one item

    ENDLOOP.

    " Update screen
    CALL FUNCTION 'DYNP_VALUES_UPDATE'
      EXPORTING
        dyname     = '/FDSEU/HCPC'    "Program name
        dynumb     = '0220'           "Screen number
      TABLES
        dynpfields = lt_dynpfields
      EXCEPTIONS
        OTHERS     = 0.

  ENDMETHOD.                    "screen_300_f4_cw





An addition - database data type


the data type storing calendar week within database could be e.g. KWEEK or /BI0/OICALWEEK, all have type NUMC(6).




Internally the stored value looks like:





May be there are easier ways, I found this. I hope it helps someone ;-)



Sunday, October 22, 2017

Trigger standard search help and fill more dynpro fields

Yes, the easist way how to get search help functionality is just to provide its name within Screen painter beside the field name.

But what about a bit more complicated case, imagine, you would need to fill more dynpro fields based on search help result. Here you are out of standard techniques. Below example solves exactly this case.

It triggers manually standard SAP search help - in this case USER_COMP. This search help offers various selection methods how to pick a desired person, in the end it returns username.






Below F4 module gets username, reads user full name and fills both values on dynpro. Comments should be self explanatory enough ;-)


Dynpro coding:

PROCESS ON VALUE-REQUEST. " F4 action
  FIELD gs_task_pool-responsible_pers MODULE f4_responsible.


Source code:


*&---------------------------------------------------------------------*
*&      Module  F4_RESPONSIBLE  INPUT
*&---------------------------------------------------------------------*
*       Transport values to dynpro/screen
*----------------------------------------------------------------------*
MODULE f4_responsible INPUT.

  DATA: lt_dynpfields         TYPE STANDARD TABLE OF dynpread,
        ls_dynpfields         LIKE LINE OF lt_dynpfields,
        ls_shlp_descr         TYPE shlp_descr,
        lt_shlp_return_values TYPE STANDARD TABLE OF ddshretval,
        lv_username           TYPE xubname.

  " Get search help description
  CALL FUNCTION 'F4IF_GET_SHLP_DESCR'
    EXPORTING
      shlpname = 'USER_COMP' " Standard SAP search help name
      shlptype = 'SH'
    IMPORTING
      shlp     = ls_shlp_descr.

  " Ask FM F4IF_START_VALUE_REQUEST for return values - set the sign
  FIELD-SYMBOLS: <fs_interface> LIKE LINE OF ls_shlp_descr-interface.
  LOOP AT ls_shlp_descr-interface ASSIGNING <fs_interface>.
    <fs_interface>-valfield = 'X'.
  ENDLOOP.

  " Trigger search help popup screen
  CALL FUNCTION 'F4IF_START_VALUE_REQUEST'
    EXPORTING
      shlp          = ls_shlp_descr
    TABLES
      return_values = lt_shlp_return_values.

  CLEAR lt_dynpfields.
  CLEAR ls_dynpfields.
  CLEAR lv_username.
  CLEAR gs_user_address.

  FIELD-SYMBOLS: <fs_return_value> LIKE LINE OF lt_shlp_return_values.
  LOOP AT lt_shlp_return_values ASSIGNING <fs_return_value>.

    " Fill 1th screen field
    ls_dynpfields-fieldname  = 'GS_TASK_POOL-RESPONSIBLE_USR'.
    ls_dynpfields-fieldvalue = <fs_return_value>-fieldval.
    APPEND ls_dynpfields TO lt_dynpfields.

    " Fill 2nd screen field
    lv_username = <fs_return_value>-fieldval.
    gs_user_address = lcl_main=>self->get_user_detail( iv_username = lv_username ).
    ls_dynpfields-fieldname  = 'GS_TASK_POOL-RESPONSIBLE_PERS'.
    ls_dynpfields-fieldvalue = gs_user_address-fullname.
    CONDENSE  ls_dynpfields-fieldvalue.
    APPEND ls_dynpfields TO lt_dynpfields.

    EXIT. " process just one item/person
  ENDLOOP.

  " Update screen fields
  CALL FUNCTION 'DYNP_VALUES_UPDATE'
    EXPORTING
      dyname     = '/FDSEU/HCPC'    "Program name
      dynumb     = '0220'           "Screen number
    TABLES
      dynpfields = lt_dynpfields
    EXCEPTIONS
      OTHERS     = 0.

ENDMODULE.                 " F4_RESPONSIBLE  INPUT




Sources on net:




Saturday, September 24, 2016

SELECTION SCREEN and events like ONFOCUS ONBLUR for Search help?

Are you coming to ABAP from web development folks? Welcome! :) Maybe you would become a bit confused with limited set of events for ABAP Selection screens.

If you previously used to work with web form's events like onBlur, onFocus you will be here a bit disappointed. I will not promise any miracle, these events simply do not exists here at all.

But the situation how to react between form inputs is not so hopeless.

AT first there is a list of real supported events:



What we can do if we want to make a search help based on the value of previous input?

We have very limited possibilities, but luckily for this case there exists a magic workaround.

Imagine a situation on the picture below. You have a simple input for database table name. And you want to offer to user directly the list of its fields for sort. This is not possible to reach with existing events. Ok, you can call something like: "AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_sort" and then call some your nice logic with table name as a parameter. But during this call table name (previous above input) would be still empty, no table name is filled at this time, sorry :(




What to do??


You can use existing event "AT SELECTION SCREEN" event. Ok, it works partially, because it would demand some user action like hit the ENTER key or click on somewhat on the toolbar. It is not the best choice.

Or?


We can use just "AT SELECTION-SCREEN ON VALUE" but with a bit tuned coding using FM the name RS_SELECTIONSCREEN_READ. See the below code.  I removed some checks and logic to keep the coding simple.

The miracle came. We obtain a search help directly by clicking on its icon based on the value of the field above.


Code snippets:

Screen:


  SELECTION-SCREEN BEGIN OF BLOCK frame1.
    " Name of SQL table
    SELECTION-SCREEN BEGIN OF LINE.
      SELECTION-SCREEN COMMENT 1(25) TEXT-001.
      SELECTION-SCREEN POSITION 26. "POS_LOW
      PARAMETERS: p_tab LIKE dd02l-tabname.
    SELECTION-SCREEN END OF LINE.
    " Sort by table column
    SELECTION-SCREEN BEGIN OF LINE.
      SELECTION-SCREEN COMMENT 1(25) TEXT-005.
      SELECTION-SCREEN POSITION 26.
      PARAMETERS: p_sort TYPE slis_fieldname.
    SELECTION-SCREEN END OF LINE.
    " Filter one column
    SELECTION-SCREEN BEGIN OF LINE.
      SELECTION-SCREEN COMMENT 1(25) TEXT-006.
      SELECTION-SCREEN POSITION 26.
      PARAMETERS: p_filtr TYPE slis_fieldname.
      SELECTION-SCREEN COMMENT 60(10) TEXT-007.
      SELECTION-SCREEN POSITION 71.
      PARAMETERS: p_c_val TYPE string.
    SELECTION-SCREEN END OF LINE.
  SELECTION-SCREEN END OF BLOCK frame1.

Events:

Its a simple call of class method for both inputs (sorting + filtering) in this case.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_sort.
  gr_table->f4_for_colname( iv_scr_field_name = 'P_SORT' ).

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_filtr.
  gr_table->f4_for_colname( iv_scr_field_name = 'P_FILTR' ).



Search help code:


Method declaration

  PRIVATE SECTION.

    TYPES: BEGIN OF sty_col,
      fieldname TYPE dd03l-fieldname,
    END OF sty_col.
    TYPES: tty_cols TYPE STANDARD TABLE OF sty_col.
    METHODS:
      f4_for_colname
        IMPORTING iv_scr_field_name TYPE help_info-dynprofld.

Method implementation


  METHOD f4_for_colname.

    DATA: it_cols      TYPE STANDARD TABLE OF sty_col,
          it_scr_field TYPE STANDARD TABLE OF rsselread,
          ls_scr_field LIKE LINE OF it_scr_field.

    MOVE 'P_TAB' TO ls_scr_field-name.
    MOVE 'P' TO ls_scr_field-kind. " P for parameter, S for select option
    APPEND ls_scr_field TO it_scr_field.

    CALL FUNCTION 'RS_SELECTIONSCREEN_READ'
      EXPORTING
        program     = sy-repid
        dynnr       = sy-dynnr
      TABLES
        fieldvalues = it_scr_field.

    READ TABLE it_scr_field INTO ls_scr_field INDEX 1.

    IF ls_scr_field-fieldvalue IS NOT INITIAL.
      TRANSLATE ls_scr_field-fieldvalue TO UPPER CASE. " table name
      SELECT fieldname
        FROM dd03l
        INTO CORRESPONDING FIELDS OF TABLE it_cols
        WHERE tabname = ls_scr_field-fieldvalue.
    ENDIF.

    CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
      EXPORTING
        retfield    = 'fieldname' " from itab
        dynpprog    = sy-repid
        dynpnr      = sy-dynnr
        dynprofield = iv_scr_field_name " e.g. 'P_SORT'
        value_org   = 'S' " structure
      TABLES
        value_tab   = it_cols.

  ENDMETHOD.                    "f4_for_colname


Sources:


Tuesday, March 4, 2014

Vendor filtering - The Collective search help exit for KRED

Intro

This article describes one really common task, how to filter vendors of too much generous search help based on authorization object. The solution is search help exit. Ok, here we focus on the solution for SAP collective search help the name KRED, which is widely used in many transactions e.g. FK03, XK03, MK03 and so on. The main idea for below solution is catched from Brad Bohn suggestion, see SAP forum at  http://scn.sap.com/thread/1831345.

Filtered LIFNR and it's search help exit



The collective search help KRED

contains quite a lot of elementary search helps. We can assign to every sub search help it is own search help exit. Ok, it would work, but lose central management point and it brings furthermore some more work.




The nice way seems to be usage of search help exit directly on the KRED search help itself.

When you try to establish your own function module for search help exit, you will be asked for Access key for your installation. Here ask your BC team.



The elementary search help exit injection 

If you do that you will discover one unpleasant thing. The return data are not processed through your custom search help exit on collective level. So, what to do? Fortunately we are given the list of elementary search helps inside the collective one. See internal table SHLP_TAB[]. Each search help contains structure intdescr and it has the field selmexit, what is the name of the search help exit. We can programmatically inject our own search help exit for each one search help in a loop.




See the code below:

  constants: cv_root_shlp_name type shlpname value 'KRED',
             cv_shlp_exit_name type string value '/YourNamespace/H_FI_F4UT_KRED'.
  
field-symbols: <fs_shlp> type line of shlp_desct.

  
if ( shlp-shlpname eq cv_root_shlp_name ) and ( shlp_tab[] is not initial ).
    
loop at shlp_tab[] assigning <fs_shlp>.
      
if not <fs_shlp>-intdescr is initial.
        <fs_shlp>
-intdescr-selmexit = cv_shlp_exit_name.
      
endif.
    
endloop.
  
endif.

The post selection filtering

Now comes the task of filtering the data. We used here the same func. module for collective search help and it is elementary search helps. So filtering has to be active just for elementary helps.

There is more events triggering our search help exit. We need to focus on just one, the POSTSEL. The post selection is the right place to filter data returned to user before displaying.

Here is just worthy to mention that looping over authorization object check is quite slow solution. The better and faster way is to load all fields of authorization object into internal table and process it by yourself.

Authorization object



Just action number 3 the displaying is what we are looking for.



Classic slow/simple code example

    DATA: i TYPE i.
    LOOP AT results_tab.
      i = sy-tabix.
      AUTHORITY-CHECK OBJECT 'F_LFA1_GRP'
               ID 'KTOKK' FIELD results_tab-ktokk
               ID 'ACTVT' FIELD '03'. "For Display
      IF sy-subrc <> 0.
*       Delete the corresponding entry in RECORD_TAB.
        DELETE record_tab INDEX i.
*       Keep SY-TABIX of record_tab and results_tab synchronous
        DELETE results_tab.
      ENDIF.
    ENDLOOP.


Here we need to find a bit faster solution over classic check above.

Read authorization object at once

      CONSTANTS     cv_auth_object TYPE ust12-objct VALUE 'F_LFA1_GRP'.
      FIELD-SYMBOLS <fs_usvalues> TYPE usvalues.
      DATA: lt_usvalues TYPE STANDARD TABLE OF usvalues.

      CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
        EXPORTING
          user_name  = sy-uname
          sel_object = cv_auth_object
        TABLES
          values     = lt_usvalues.



Action based filtering at first

        constants cv_allowed_actvt type i value 3.
        loop at lt_usvalues assigning <fs_usvalues>.
          " Check ACTVT ( later filter KTOKK by ACTVT)
          if <fs_usvalues>-field eq 'ACTVT'.
            if <fs_usvalues>-von eq '*'.
              lv_actvt_ok = abap_true.
              exit.
            elseif ( <fs_usvalues>-von is not initial ) and ( <fs_usvalues>-bis is not initial ).
              move <fs_usvalues>-von to lv_actvt.
              if cv_allowed_actvt eq lv_actvt.
                lv_actvt_ok = abap_true.
                exit.
              elseif cv_allowed_actvt ge lv_actvt.
                move <fs_usvalues>-bis to lv_actvt.
                if cv_allowed_actvt le lv_actvt.
                  lv_actvt_ok = abap_true.
                  exit.
                endif.
              endif.
            elseif ( <fs_usvalues>-von is not initial ).
              move <fs_usvalues>-von to lv_actvt.
              if cv_allowed_actvt eq lv_actvt.
                lv_actvt_ok = abap_true.
                exit.
              endif.
            endif.
          endif.
        endloop.

Next step is to fill out custom select option table and used it in further SQL selection with table LFA1.

Selection of allowed vendors as the second step

The result itab lt_usvalues is later converted into select-option based itab for SQL select.

        DATA: lt_ktokk_selopt TYPE STANDARD TABLE OF ers_range_option,
              ls_ktokk_selopt LIKE LINE OF lt_ktokk_selopt.

        IF lv_actvt_ok EQ abap_true.
          LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
            " Pickup KTOKK patterns in case of positive ACTVT
            " Prepare select option intab for SQL query
            IF <fs_usvalues>-field EQ 'KTOKK'.
              CLEAR ls_ktokk_selopt.
              ls_ktokk_selopt-sign = 'I'.
              ls_ktokk_selopt-low = <fs_usvalues>-von.
              IF <fs_usvalues>-bis IS NOT INITIAL.
                ls_ktokk_selopt-high = <fs_usvalues>-bis.
                ls_ktokk_selopt-option = 'BT'.
              ELSEIF  ( <fs_usvalues>-von CS '*' ) OR  ( <fs_usvalues>-von CS '?' ).
                ls_ktokk_selopt-option = 'CP'.
              ELSE.
                ls_ktokk_selopt-option = 'EQ'.
              ENDIF.
              APPEND ls_ktokk_selopt TO lt_ktokk_selopt.
            ENDIF.
          ENDLOOP.
        ENDIF.


The data of select-option table would look like




        " Get allowed LIFNR based on KTOKK patterns
        data lt_lifnr_ok type standard table of lfa1-lifnr.

        if lt_ktokk_selopt is not initial.
          select lifnr from lfa1
            into table lt_lifnr_ok
            where ktokk in lt_ktokk_selopt
            order by ktokk.
        endif.

Now we have all possible LIFNRs which can be offered to user based on authorization object. The last point is just to exclude all unauthorized vendors before displaying.

Exclude unallowed LIFNRs from result

    data: lv_i type i,
          ls_lifnr_ok like line of lt_lifnr_ok.

    loop at results_tab.
      lv_i = sy-tabix.
      read table lt_lifnr_ok into ls_lifnr_ok with key results_tab-lifnr.
      if sy-subrc <> 0.
*       Delete the corresponding entry in RECORD_TAB.
        delete record_tab index lv_i.
*       Keep SY-TABIX of record_tab and results_tab synchronous
        delete results_tab.
      endif.
    endloop.

Now all vendors of any sub-elementary search help are going to be filtered via our exit function module.



See the whole FM's code for convenience


FUNCTION /YourNameSpace/h_fi_f4ut_kred.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  TABLES
*"      SHLP_TAB TYPE  SHLP_DESCT
*"      RECORD_TAB STRUCTURE  SEAHLPRES
*"  CHANGING
*"     VALUE(SHLP) TYPE  SHLP_DESCR
*"     VALUE(CALLCONTROL) LIKE  DDSHF4CTRL STRUCTURE  DDSHF4CTRL
*"----------------------------------------------------------------------

  TYPES:
    abap_bool TYPE c LENGTH 1.

* constants for abap_bool
  CONSTANTS:
    abap_true      TYPE abap_bool VALUE 'X',
    abap_false     TYPE abap_bool VALUE ' ',
    abap_undefined TYPE abap_bool VALUE '-'.

  DATA: BEGIN OF results_tab OCCURS 0,
          lifnr TYPE lifnr,
        END OF results_tab.

* Enable the postprocessing of selected values
  CALL FUNCTION 'F4UT_POST_SELECTION_PROCESSING'
    TABLES
      shlp_tab    = shlp_tab
      record_tab  = record_tab
    CHANGING
      shlp        = shlp
      callcontrol = callcontrol.

* Assign search help exit func. module injection to every child
* elementary sub search helps of main collective search help the name KRED
  CONSTANTS: cv_root_shlp_name TYPE shlpname VALUE 'KRED',
             cv_shlp_exit_name TYPE string VALUE '/YourNameSpace/H_FI_F4UT_KRED'.
  FIELD-SYMBOLS: <fs_shlp> TYPE LINE OF shlp_desct.

  IF ( shlp-shlpname EQ cv_root_shlp_name ) AND ( shlp_tab[] IS NOT INITIAL ).
    LOOP AT shlp_tab[] ASSIGNING <fs_shlp>.
      IF NOT <fs_shlp>-intdescr IS INITIAL.
        <fs_shlp>-intdescr-selmexit = cv_shlp_exit_name.
      ENDIF.
    ENDLOOP.
  ENDIF.

* Do selection before displaying the results to user
* (It is triggered on elementary child search helps)
  IF callcontrol-step = 'POSTSEL'.

    " Get result data to be filtered
    CALL FUNCTION 'F4UT_PARAMETER_VALUE_GET'
      EXPORTING
        parameter   = 'LIFNR' "Searchhelp-Parameter
        fieldname   = 'LIFNR' "Fieldname in RESULTS_TAB
      TABLES
        shlp_tab    = shlp_tab
        record_tab  = record_tab
        results_tab = results_tab
      CHANGING
        shlp        = shlp
        callcontrol = callcontrol.

    IF results_tab[] IS NOT INITIAL.
      " We have some data to be filtered
      CONSTANTS     cv_auth_object TYPE ust12-objct VALUE 'F_LFA1_GRP'.
      FIELD-SYMBOLS <fs_usvalues> TYPE usvalues.
      DATA: lt_usvalues TYPE STANDARD TABLE OF usvalues.

      CALL FUNCTION 'SUSR_USER_AUTH_FOR_OBJ_GET'
        EXPORTING
          user_name  = sy-uname
          sel_object = cv_auth_object
        TABLES
          values     = lt_usvalues.

      IF lt_usvalues IS INITIAL.
        " 1) No auth object at all --> no result
        REFRESH results_tab[].
      ELSE.
        " 2) Filtering part

        DATA: lv_actvt TYPE i,
              lv_actvt_ok TYPE abap_bool VALUE abap_false.

        CONSTANTS cv_allowed_actvt TYPE i VALUE 3.
        LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
          " 2 A) Check ACTVT ( later filter KTOKK by ACTVT)
          IF <fs_usvalues>-field EQ 'ACTVT'.
            IF <fs_usvalues>-von EQ '*'.
              lv_actvt_ok = abap_true.
              EXIT.
            ELSEIF ( <fs_usvalues>-von IS NOT INITIAL ) AND ( <fs_usvalues>-bis IS NOT INITIAL ).
              MOVE <fs_usvalues>-von TO lv_actvt.
              IF cv_allowed_actvt EQ lv_actvt.
                lv_actvt_ok = abap_true.
                EXIT.
              ELSEIF cv_allowed_actvt GE lv_actvt.
                MOVE <fs_usvalues>-bis TO lv_actvt.
                IF cv_allowed_actvt LE lv_actvt.
                  lv_actvt_ok = abap_true.
                  EXIT.
                ENDIF.
              ENDIF.
            ELSEIF ( <fs_usvalues>-von IS NOT INITIAL ).
              MOVE <fs_usvalues>-von TO lv_actvt.
              IF cv_allowed_actvt EQ lv_actvt.
                lv_actvt_ok = abap_true.
                EXIT.
              ENDIF.
            ENDIF.
          ENDIF.
        ENDLOOP.

        DATA: lt_ktokk_selopt TYPE STANDARD TABLE OF ers_range_option,
              ls_ktokk_selopt LIKE LINE OF lt_ktokk_selopt.

        IF lv_actvt_ok EQ abap_true.
          LOOP AT lt_usvalues ASSIGNING <fs_usvalues>.
            " Pickup KTOKK patterns in case of positive ACTVT
            " Prepare select option intab for SQL query
            IF <fs_usvalues>-field EQ 'KTOKK'.
              CLEAR ls_ktokk_selopt.
              ls_ktokk_selopt-sign = 'I'.
              ls_ktokk_selopt-low = <fs_usvalues>-von.
              IF <fs_usvalues>-bis IS NOT INITIAL.
                ls_ktokk_selopt-high = <fs_usvalues>-bis.
                ls_ktokk_selopt-option = 'BT'.
              ELSEIF  ( <fs_usvalues>-von CS '*' ) OR  ( <fs_usvalues>-von CS '?' ).
                ls_ktokk_selopt-option = 'CP'.
              ELSE.
                ls_ktokk_selopt-option = 'EQ'.
              ENDIF.
              APPEND ls_ktokk_selopt TO lt_ktokk_selopt.
            ENDIF.
          ENDLOOP.
        ENDIF.

        " 2 B) Get allowed LIFNR based on KTOKK patterns
        DATA lt_lifnr_ok TYPE STANDARD TABLE OF lfa1-lifnr.

        IF lt_ktokk_selopt IS NOT INITIAL.
          SELECT lifnr FROM lfa1
            INTO TABLE lt_lifnr_ok
            WHERE ktokk IN lt_ktokk_selopt
            ORDER BY ktokk.
        ENDIF.
      ENDIF.
    ENDIF.

    " 3) Exclude unallowed LIFNRs from result
    DATA: lv_i TYPE i,
          ls_lifnr_ok LIKE LINE OF lt_lifnr_ok.

    LOOP AT results_tab.
      lv_i = sy-tabix.
      READ TABLE lt_lifnr_ok INTO ls_lifnr_ok WITH KEY results_tab-lifnr.
      IF sy-subrc <> 0.
*       Delete the corresponding entry in RECORD_TAB.
        DELETE record_tab INDEX lv_i.
*       Keep SY-TABIX of record_tab and results_tab synchronous
        DELETE results_tab.
      ENDIF.
    ENDLOOP.

  ENDIF.

ENDFUNCTION.