Автор Тема: Y_TSH_F4IF_START_VALUE_REQUEST - ФМ для простой работы со средствами поиска  (Прочитано 16184 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 762
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Y_TSH_F4IF_START_VALUE_REQUEST - ФМ для простой работы со средствами поиска на своих экранах.  В большинстве случаев конечно система сама вызывает средство поиска для поля, но бывают ситуации когда нужно передать в средство поиска какие-то значения, которые не могут быть переданы через SET/GET параметры или же как спросили в этой теме: You are not allowed to view links. Register or Login, нужно было для значения передать значение многократного выбора не как "равно", а как например "больше равно", конечно можно для каждого случая рисовать свой ФМ по работе со средствами поиска, что и было сделано в выше приведенной теме, однако можно написать свою универсальную обертку, которая будет работать так как надо с любыми средствами поиска. Лучше всего такую разработку оформить как глобальный функциональный модуль, который можно вызвать из любой программы в рамках системы. И так что надо. Сначала надо объявить глобальную структуру в рамках словаря данных, транзакция SE11, создаем структуру: YTSH_F4IF_SHLP_PREPARE - Структура связи для TSH_F4IF_START_VALUE_REQUEST, ниже поля и их типы, все типы уже есть в системе версии 6.0 или выше, а возможно что и в более ранних
версиях.
Код: You are not allowed to view links. Register or Login
SHLP_FIELD DDSHLPSFLD
SCRN_FIELD SCRFNAME
VALUE DDSHVALUE
SIGN TVARV_SIGN
OPTION TVARV_OPTI
INIT_VALUE XFELD
Пример как это выглядит на рисунке YTSH_F4IF_SHLP_PREPARE.png ниже, я единственно что там сделал, это поля SIGN и OPTION объявил через APPEND к основной структуре, но вы можете этого не делать а все объявить в одной структуре. Далее пишем такой вот текст ФМ:
Код: You are not allowed to view links. Register or Login
FUNCTION z_utn_ca_004_f4if_start_value.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*"  IMPORTING
*"     REFERENCE(PI_SHLP_NAME) TYPE  SHLPNAME
*"     VALUE(PI_DYNAME) TYPE  SYCPROG DEFAULT SY-CPROG
*"     VALUE(PI_DYNUMB) TYPE  SYDYNNR DEFAULT SY-DYNNR
*"     REFERENCE(PI_DIALOGTYPE) TYPE  DDSHDIATYP DEFAULT SPACE
*"  TABLES
*"      PT_SHLP_VALUE STRUCTURE  ZUTN_CA_004_F4IF_SHLP_PREP_ST
*"      PT_RETURN STRUCTURE  DDSHRETVAL OPTIONAL
*"  EXCEPTIONS
*"      SHLP_NOT_FOUND
*"      CANCEL_SELECT
*"----------------------------------------------------------------------
  DATA: l_rc          LIKE sy-subrc,
        gs_shlp       TYPE shlp_descr_t,
        interface_wa  TYPE LINE OF shlp_descr_t-interface,
        selopt_wa     TYPE LINE OF shlp_descr_t-selopt,
        fieldprop_wa  TYPE LINE OF shlp_descr_t-fieldprop,
        gt_dynpfields LIKE dynpread OCCURS 1 WITH HEADER LINE.
  DATA: l_field TYPE scrfname,
        l_stepl TYPE systepl,
        l_value TYPE char50.

  IF pi_dyname = space. pi_dyname = sy-cprog. ENDIF.
  IF pi_dynumb = space. pi_dynumb = sy-dynnr. ENDIF.

* Получить данные средства поиска стратегий
  CLEAR: gs_shlp, gt_dynpfields[].
  CALL FUNCTION 'F4IF_GET_SHLP_DESCR'
    EXPORTING
      shlpname = pi_shlp_name
    IMPORTING
      shlp     = gs_shlp
    EXCEPTIONS
      OTHERS   = 1.
  IF sy-subrc <> 0. RAISE shlp_not_found. ENDIF.

  LOOP AT gs_shlp-fieldprop INTO fieldprop_wa.
    READ TABLE gs_shlp-interface INTO interface_wa WITH KEY shlpfield = fieldprop_wa-fieldname.
    IF sy-subrc <> 0. CONTINUE. ENDIF.
    interface_wa-f4field = fieldprop_wa-shlpoutput.
    IF interface_wa-valfield IS INITIAL. interface_wa-valfield = interface_wa-shlpfield. ENDIF.
    MODIFY gs_shlp-interface FROM interface_wa INDEX sy-tabix.
  ENDLOOP.

  GET CURSOR FIELD l_field LINE l_stepl VALUE l_value.
  PERFORM dynp_values_read TABLES gt_dynpfields
                           USING pi_dyname pi_dynumb.

  LOOP AT pt_shlp_value.
    READ TABLE gs_shlp-fieldprop INTO fieldprop_wa WITH KEY fieldname = pt_shlp_value-shlp_field.
    IF sy-subrc = 0 AND fieldprop_wa-defaultval <> space.
      fieldprop_wa-defaultval = space.
      MODIFY gs_shlp-fieldprop FROM fieldprop_wa
      TRANSPORTING defaultval
      WHERE fieldname = pt_shlp_value-shlp_field.
    ENDIF.

    CLEAR: interface_wa.
    interface_wa-valfield = pt_shlp_value-scrn_field.
*   Данные экрана, для получения типа упаковки
    IF pt_shlp_value-scrn_field = space.
      interface_wa-value = pt_shlp_value-value.
    ELSE.
      READ TABLE gt_dynpfields WITH KEY fieldname = pt_shlp_value-scrn_field
                                        stepl = l_stepl.
      IF sy-subrc <> 0. CONTINUE. ENDIF.
*     Определить поля из начения которые будут возвращаться.
      IF pt_shlp_value-scrn_field <> l_field.
*       Если нет переданного значения тогда значение взять с жкрана
        IF pt_shlp_value-init_value = space.
          IF pt_shlp_value-value = space.
            interface_wa-value = gt_dynpfields-fieldvalue.
          ELSEIF pt_shlp_value-value <> '-'.
            interface_wa-value = pt_shlp_value-value.
          ENDIF.
        ENDIF.
      ELSE.
        interface_wa-value = pt_shlp_value-value.
      ENDIF.
    ENDIF.
    MODIFY gs_shlp-interface FROM interface_wa
          TRANSPORTING valfield value
          WHERE shlpfield = pt_shlp_value-shlp_field.
*   Данные знака выбора значений
    IF pt_shlp_value-sign <> space AND pt_shlp_value-option <> space.
      selopt_wa-shlpname = pi_shlp_name.
      selopt_wa-shlpfield = pt_shlp_value-shlp_field.
      selopt_wa-sign = pt_shlp_value-sign.
      selopt_wa-option = pt_shlp_value-option.
      selopt_wa-low = interface_wa-value.
      APPEND selopt_wa TO gs_shlp-selopt.
    ENDIF.
  ENDLOOP.

  IF pi_dialogtype <> space.
    gs_shlp-intdescr-dialogtype = pi_dialogtype.
  ENDIF.

* Вызвать средство поиска
  CALL FUNCTION 'F4IF_START_VALUE_REQUEST'
    EXPORTING
      shlp          = gs_shlp
    IMPORTING
      rc            = l_rc
    TABLES
      return_values = pt_return.
  IF l_rc <> 0. RAISE cancel_select. ENDIF.

* Прочиать выбранные значения
  LOOP AT pt_return.
    READ TABLE gt_dynpfields WITH KEY fieldname = pt_return-retfield
                                      stepl = l_stepl.
    IF sy-subrc <> 0. CONTINUE. ENDIF.
    gt_dynpfields-fieldvalue = pt_return-fieldval.
    MODIFY gt_dynpfields INDEX sy-tabix.
  ENDLOOP.

* Передать выбранные значения кода поиска в экран
  CALL FUNCTION 'DYNP_VALUES_UPDATE'
    EXPORTING
      dyname               = pi_dyname
      dynumb               = pi_dynumb
    TABLES
      dynpfields           = gt_dynpfields
    EXCEPTIONS
      invalid_abapworkarea = 1
      invalid_dynprofield  = 2
      invalid_dynproname   = 3
      invalid_dynpronummer = 4
      invalid_request      = 5
      no_fielddescription  = 6
      undefind_error       = 7
      OTHERS               = 8.
ENDFUNCTION.
Для танкистов на рисунке Y_TSH_F4IF_START_VALUE_REQUEST_PRM.png ниже показано как это выглядит на экране создания ФМ.  Далее создаем парочку необходимых подпрограмм которые используются в этом ФМ. В принципе код этой подпрограммы можно вставить в текст самого ФМ, просто у меня уже в этой группе функций была это подпрограмма.
Код: You are not allowed to view links. Register or Login
*&---------------------------------------------------------------------*
*&      Form  dynp_values_read
*&---------------------------------------------------------------------*
*     Загрузить список полей и их значений с текущего экрана
*----------------------------------------------------------------------*
*      -->P_DYNPFIELDS - Список полей и значений с текущего экрана
*----------------------------------------------------------------------*
FORM dynp_values_read TABLES p_dynpfields STRUCTURE gt_dynpfields
                      USING p_dyname p_dynumb.
  CALL FUNCTION 'DYNP_VALUES_READ'
    EXPORTING
      dyname               = p_dyname
      dynumb               = p_dynumb
      request              = 'A'
    TABLES
      dynpfields           = p_dynpfields
    EXCEPTIONS
      invalid_abapworkarea = 1
      invalid_dynprofield  = 2
      invalid_dynproname   = 3
      invalid_dynpronummer = 4
      invalid_request      = 5
      no_fielddescription  = 6
      invalid_parameter    = 7
      undefind_error       = 8
      double_conversion    = 9
      stepl_not_found      = 10
      OTHERS               = 11.
ENDFORM.                    " dynp_values_read
Затем это дело сохраняем и оно должно вроде как нормально сгенерироваться, т.е. функциональный модуль готов. Теперь как его вызвать и как это все работает. И так например у вас есть экран с полями, пусть это будет например два поля балансовая единица и поле даты и эти оба поля пусть будут использоваться в некотором уже существующем средстве поиска. При этом на экране мы объявили поля
следующим образом:
Код: You are not allowed to view links. Register or Login
PT_BUKRS LIKE T001-BUKRS,
PT_DATUM LIKE SY-DATUM.
В средстве поиска с именем например MY_SHELP поля средства поиска пусть будут объявлены таким образом:
Код: You are not allowed to view links. Register or Login
BUKRS
FLAG_ONE
DATE_START
Мы хотим, чтобы наши поля копировались в средство поиска следующим образом:
PT_BUKRS => BUKRS, а PT_DATUM => DATE_START, при этом селекционный выбор для даты был бы не равен значению в нашем поле, а передавался бы, как больше равно значения из нашего поля. Тогда в своей программе делаем следующее. На экране программы привязываем средство поиска к вызову через наш модуль, для этого в логике выполнения экрана для поля даты напишем например следующее:
Код: You are not allowed to view links. Register or Login
process on value-request.
  field pt_datum module help_datum.
Далее в своей программе объявим следующие переменные и для упрощения работы один
макрос:
Код: You are not allowed to view links. Register or Login
data: gt_shlp_value like ytsh_f4if_shlp_prepare occurs 1 with header line,
      gt_shlp_return like ddshretval occurs 1 with header line.

define shlp_fill.
* Таблица связи полей экрана с полями средства поиска
  gt_shlp_value-shlp_field = &1.
  gt_shlp_value-scrn_field = &2.
  gt_shlp_value-value = &3.
* Оптиции знака выбора
  gt_shlp_value-sign = &4.
  gt_shlp_value-option = &5.
* Без начальных значений из полей экрана
  gt_shlp_value-init_value = &6.

  append gt_shlp_value.
end-of-definition.
Ну сам модуль:
Код: You are not allowed to view links. Register or Login
*&---------------------------------------------------------------------*
*&      Module  help_datum  INPUT
*&---------------------------------------------------------------------*
module help_datum input.
* Таблица связи полей экрана с полями средства поиска
  clear: gt_shlp_value[].
  shlp_fill: 'BUKRS' 'PT_BUKRS' space space space.
  shlp_fill: 'DATE_START' 'PT_DATUM' space 'I' 'GE'.

* Вызвать средство поиска
  call function 'Y_TSH_F4IF_START_VALUE_REQUEST'
    exporting
      pi_shlp_name   = ' MY_SHELP'
    tables
      pt_shlp_value  = gt_shlp_value
    exceptions
      shlp_not_found = 1
      cancel_select  = 2
      others         = 3.
endmodule.                 " help_datum  INPUT

Собственно все, при этом если поле БЕ уже заполнено то его значение будет передано автоматически в средство поиска, если пользователь выберет нужное значение в средстве поиска, то эти значения будут корректно переданы назад в поля, при этом если например есть два/три или больше полей и средство поиска возвращает набор значений, то эти значения будут корректно перенесены в поля экрана, например есть три поля: Балансовая единица, Завод и Склад. В общем виде есть средство поиска которое выводит эти три поля для выбора, так вот находясь в поел склада, если вы выберете в средстве поиска склад, то так как склад явно присвоен завода а тот в свою очередь присвоен балансовой единице, то данный ФМ перенесет значения завода и балансовой в поля на экране, таким образом пользователю достаточно вызвать средство поиска только в поле склада. Так же если например будет заполнено поле БЕ, поле завода будет пустым, и вы сделаете вызов в поле склад, то в средстве поиска поле БЕ будет уже заполнено вашим введенным на экране значением и это значит, что пользователь сразу получит только заводы и склады уже заданной БЕ. В общем ФМ получился довольно универсальным.

Теперь по параметрам структуры:
* Таблица связи полей экрана с полями средства поиска
  gt_shlp_value-shlp_field - Имя поля в средстве поиска
  gt_shlp_value-scrn_field - Имя поля на вашем экране
  gt_shlp_value-value - Значение которое хотим принудительно поставить в поле. Если передать пустое значение, то система попытается взять значение которое введено на экране, иначе будет подставлено значение которое вы передадите, не зависимо от ввода на экране.
  gt_shlp_value-sign - Собственно переменная знака или I - для включения значений или E - для исключения
  gt_shlp_value-option - Вариант переменной типа GE - больше равно LE - меньше равно и т.д.
  gt_shlp_value-init_value - Не устанавливать начальное значение переменной перед выполнением поиска записей,но возвращать переменную/поле

Последние три поля можно оставлять пустыми, тогда система будет брать значение полей с экрана и вариант вклчюения устанавливать как EQ - равно значению из поля.

PS: Обновления от 01.10.2015 - Описание обновления ниже по тексту.
PS: Обновления от 12.12.2018 - Описание обновления ниже по тексту.
« Последнее редактирование: Декабрь 12, 2018, 06:05:14 pm от Uukrul »

Оффлайн darth

  • Newbie
  • *
  • Сообщений: 11
  • Репутация: +1/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
Привет.
Решил попробовать воспользоваться фм-ом.
нужно определние глобальной таблицы gt_dynpfields...
из проц-ры "dynp_values_read" понятно что она типа: "table of DYNPREAD"...
но хорошо бы положить определение в текст.
« Последнее редактирование: Декабрь 09, 2013, 01:13:01 pm от darth »
I am the master of the C.L.I.T. Remember this fucking face. Whenever you see C.L.I.T., you'll see this fucking face. I make that shit work. It does whatever the fuck I tell it to. No one rules the C.L.I.T like me.

Оффлайн darth

  • Newbie
  • *
  • Сообщений: 11
  • Репутация: +1/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
точнее даже вот так:
DATA: gt_dynpfields TYPE TABLE OF dynpread
                    WITH HEADER LINE.
I am the master of the C.L.I.T. Remember this fucking face. Whenever you see C.L.I.T., you'll see this fucking face. I make that shit work. It does whatever the fuck I tell it to. No one rules the C.L.I.T like me.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 762
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
You are not allowed to view links. Register or Login
точнее даже вот так:
DATA: gt_dynpfields TYPE TABLE OF dynpread
                    WITH HEADER LINE.
Да, только тут в описании нет глобальных переменных, поэтому и не выложил. Ну в принципе думаю твоего описания должно быть достаточно для тех кто будет это использовать.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 762
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Обновления от 10.12.2013

Внесены изменения в текст модуля FUNCTION Y_TSH_F4IF_START_VALUE_REQUEST. Как оказалось была следующая проблема для средств поиска в которых при объявлении параметров использовались значения по умолчанию, рисунок ниже, и при этом так же значение для такого поля передавалось при вызове средства поиска, тогда система брала переданное значение и добавляла к нему значение из параметра заданного при объявлении средства поиска. Это приводило к тому, что например была проводка по БЕ 1000, срабтал SET/GET параметр для БЕ, далее в свой программе мы вызываем средство поиска например для БЕ 2000 и так как в памяти еще есть БЕ 1000, то фактически поиск происходил по двум БЕ 1000 и 2000, что как бы не очень правильно. Поэтому пришлось внести небольшие корректировки, чтобы исключить данный эффект.
« Последнее редактирование: Декабрь 10, 2013, 02:40:40 pm от Uukrul »

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 762
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Обновления от 01.10.2015

В структуру добавил ZICA_F4IF_SHLP_PREPARE добавил параметр INIT_VALUE. Понадобилась ситуация когда поле возвращать из кода поиска нужно,  вот передавать туда значение нет. По умолчанию все работало так, что при указании поля, его значение или бралось из переданных параметров или считывалось автоматически из полей экрана. Сейчас этим процессом можно управлять, если передать в данном поле "X", то инициализация переменной значением выполнятся не будет.
Код: You are not allowed to view links. Register or Login
SHLP_FIELD DDSHLPSFLD
SCRN_FIELD SCRFNAME
VALUE DDSHVALUE
SIGN TVARV_SIGN
OPTION TVARV_OPTI
INIT_VALUE XFELD

Далее изменился по этим причинам макрос:
Код: You are not allowed to view links. Register or Login
DEFINE shlp_fill.
* Таблица связи полей экрана с полями средства поиска
  gt_shlp_value-shlp_field = &1.
  gt_shlp_value-scrn_field = &2.
  gt_shlp_value-value = &3.
* Оптиции знака выбора
  gt_shlp_value-sign = &4.
  gt_shlp_value-option = &5.
* Без начальных значений из полей экрана
  gt_shlp_value-init_value = &6.

  append gt_shlp_value.
END-OF-DEFINITION.

Оффлайн Uukrul

  • SAP ECC 6.0 Ehp(*)
  • Administrator
  • Epic Member
  • *****
  • Сообщений: 3 762
  • Репутация: +47/-0
  • Пол: Мужской
  • YearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYearsYears
    • Sapforum.BIZ
Обновления от 12.12.2018

В общем обнаружилось интересное поведение при вызове средства поиска, которое построено на программной обработке, не заполняется поле interface-valfield, оно пустое и средство поиска поэтому не знает какие поля необходимо возвращать. А так же не переносится значение поля interface-f4field, т.е. какие поля возвращать в средстве поиска при выборе позиции в таблице. Пришлось дописать немного кода в основном модуле FUNCTION Y_TSH_F4IF_START_VALUE_REQUEST.. Сейчас кажется работает. Не знаю это прикол S/4HANA или после ECC EHP5, тоже что-то поменялось.