SAPфорум.RU
https://sapboard.ru/forum/

Полезные трюки ABAP
https://sapboard.ru/forum/viewtopic.php?f=13&t=87197
Страница 4 из 8

Автор:  nicky555 [ Вт, июн 16 2015, 15:13 ]
Заголовок сообщения:  Считывание записи внутренней таблицы неопределенной структуры по ключу

Иногда в процедурах приходится иметь дело с разными по структуре внутренними таблицами (в зависимости от параметров обработки), имеющими одинаковые ключевые поля. Ниже пример для иллюстрации такой ситуации, самое интересное - READ TABLE ...
Code:
PARAMETERS: pa_bukrs TYPE bkpf-bukrs,
            pa_belnr TYPE bkpf-belnr,
            pa_gjahr TYPE bkpf-gjahr.

PARAMETERS: rb_bkpf  RADIOBUTTON GROUP sel DEFAULT 'X',
            rb_bsis  RADIOBUTTON GROUP sel,
            rb_other RADIOBUTTON GROUP sel.

DATA: lt_bkpf TYPE STANDARD TABLE OF bkpf,
      lt_bsis TYPE STANDARD TABLE OF bsis.

DATA: t_ref TYPE REF TO data.

FIELD-SYMBOLS: <t_data> TYPE table,
               <w_data> TYPE ANY.

CASE 'X'.
  WHEN rb_bkpf.
    SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_bkpf
      FROM bkpf
      WHERE bukrs = pa_bukrs.
    IF sy-subrc IS INITIAL.
      GET REFERENCE OF lt_bkpf INTO t_ref.
    ENDIF.

  WHEN rb_bsis.
    SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_bsis
      FROM bsis
      WHERE bukrs = pa_bukrs.
    IF sy-subrc IS INITIAL.
      GET REFERENCE OF lt_bsis INTO t_ref.
    ENDIF.

  WHEN rb_other.
*   For test only ...

  WHEN OTHERS.
    RETURN.

ENDCASE.

CHECK t_ref IS NOT INITIAL.

ASSIGN t_ref->* TO <t_data>.

READ TABLE <t_data> ASSIGNING <w_data>
                    WITH KEY ('BUKRS') = pa_bukrs
                             ('BELNR') = pa_belnr
                             ('GJAHR') = pa_gjahr.
IF sy-subrc IS INITIAL.
* Something to do:
*   <w_data> TYPE bkpf OR
*   <w_data> TYPE bsis
ENDIF.

Автор:  funtik [ Вт, июн 16 2015, 16:09 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Блин, а я всегда выходил из этой ситуации через LOOP... Спасибо!

Автор:  Skif [ Ср, июн 17 2015, 09:23 ]
Заголовок сообщения:  Re: Считывание записи внутренней таблицы неопределенной структуры по ключу

nicky555 написал:
Иногда в процедурах приходится иметь дело с разными по структуре внутренними таблицами (в зависимости от параметров обработки), имеющими одинаковые ключевые поля. Ниже пример для иллюстрации такой ситуации, самое интересное -

изящненько ;)
попробую в ближайшей задачке

Автор:  Chaser009 [ Вт, июн 30 2015, 04:52 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Я что-то похожее в свое время делал так:

read table <linktab> assigning <result> from <s_linktab> using key (lv_key_name)

В структуре <s_linktab> заполняются поля для соответствующего ключа и указывается нужный ключ для поиска. В результате один и тот же код шерстит таблицу по-разному :-).

Автор:  olegbash [ Чт, июл 16 2015, 19:17 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

За READ - спасибо!!!

Не относится к READ:
для целей отладки есть еще класс CL_DEBUG - полезно использовать.
также в пакете лежит класс CL_ABAP_TOOL с методом MOVE_COMPLEX
документация к классам имеется.

Автор:  _Sipo_ [ Пт, окт 16 2015, 17:42 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

внесу свою лепту в раздел.
Если имеем текстовое поле в базе, которое после чтения будем разбирать на подстроки. можно сделать вот так:

Code:
select z as A+0(2)   
       x as A+2(2)   
       y as A+4(2) 
       u as A+6(2)   
       v as B+0(2) 
       w as B+2(2)  FROM dbtab 
       INTO CORRESPONDING FIELDS OF TABLE itab
          WHERE <where condition>.


В итоге, в колонках z,x,y,u будут соответсвующие подстроки табличной колонки A, а в v,w - из колонки B. Не помню с какой версии это работает. в 7.0 работало

Автор:  Parazit [ Пт, окт 16 2015, 17:47 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

_Sipo_ написал:
внесу свою лепту в раздел.
Если имеем текстовое поле в базе, которое после чтения будем разбирать на подстроки. можно сделать вот так:

Code:
select z as A+0(2)   
       x as A+2(2)   
       y as A+4(2) 
       u as A+6(2)   
       v as B+0(2) 
       w as B+2(2)  FROM dbtab 
       INTO CORRESPONDING FIELDS OF TABLE itab
          WHERE <where condition>.


В итоге, в колонках z,x,y,u будут соответсвующие подстроки табличной колонки A, а в v,w - из колонки B. Не помню с какой версии это работает. в 7.0 работало

Использовал такой метод с версии 4.6C и во всех последующих.

Автор:  Orgazm [ Пт, окт 23 2015, 12:19 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Не совсем трюк, а, скажем, предупреждение для молодых абаперов.

При работе с FOR ALL ENTRIES

Code:
clear: lt_result, lt_itab.

select *
  from dbtab
  into table lt_result
  for all entries in lt_itab
  where f1 = lt_itab-f1
  and   f2 = 1000.


Если таблица lt_itab пустая - то второе условие ( f2 = 1000 ) тоже будет проигнорировано и результатом будет select * from dbtab.

Автор:  nicky555 [ Ср, окт 28 2015, 15:08 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Вы еще не задумывались, в чем разница между обычными одинарными кавычками (') и обратными (`)? Тогда рекомендую посмотреть результат следующего "финта" :lol: :
Code:
  DATA: ld_output TYPE string.

  CONCATENATE `123    ` `321` INTO ld_output. WRITE / ld_output.
  CONCATENATE '123    ' '321' INTO ld_output. WRITE / ld_output.

Смысл простой: тип последовательности символов в одинарных кавычках (') определяется как CHAR, в обратных кавычках (`) - как STRING ...

Автор:  AFH [ Пн, ноя 02 2015, 12:04 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Code:
READ TABLE <t_data> ASSIGNING <w_data>
                    WITH KEY ('BUKRS') = pa_bukrs
                                   ('BELNR') = pa_belnr
                                   ('GJAHR') = pa_gjahr


Такая конструкция работает в несколько раз медленнее обычного READ, особенно заметно при доступе к хэш-таблицам (через WITH TABLE KEY). Замедление составляет где-то 3..9 раз в засимости от количества полей по которым идет поиск. Наверное на конструкциях WITH KEY будет не так заметно, потому что большую часть времени идет поиск записи в таблице а не анализ условия поиска.

Автор:  Orgazm [ Пт, ноя 06 2015, 11:37 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Как сделать call transaction в новом окне?

Code:
call function 'ABAP4_CALL_TRANSACTION' starting new task 'NONE'
            exporting tcode = 'TCODE'.

Автор:  Stenj_90 [ Чт, дек 03 2015, 10:55 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

При ведении таблиц, структур:
.INCLU-xxx - позволяет вставить структуры с суффиксом полей (.INCLU-001 BKPF_KEY)
Например можно использовать для вставки одинаковых комплектов полей для дебиторов и кредиторов, и т.д.

Автор:  Stenj_90 [ Чт, дек 03 2015, 12:48 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Недавно столкнулся с тем, что средство поиска на ФМ работает по-разному на разных версиях базиса. Точнее, record_tab предполагает разный порядок полей. Более того, при первом и последующих вызовах порядок тоже может оказаться разный. Пришлось динамически генерировать структуру:
Code:
...
  DATA: lo_struct       TYPE REF TO data.

  FIELD-SYMBOLS:
        <fs_struct>     TYPE ANY,
        <fs_fld>        TYPE ANY,
        <fs_record_tab> LIKE LINE OF record_tab.

  REFRESH record_tab.

  PERFORM make_struct USING shlp CHANGING lo_struct.
  ASSIGN lo_struct->* TO <fs_struct>.
  ...
  LOOP AT prps_tab.
    CLEAR <fs_struct>.
    MOVE-CORRESPONDING prps_tab TO <fs_struct>.
    ...
    ASSIGN COMPONENT 'POST1_H' OF STRUCTURE <fs_struct> TO <fs_fld>.
    <fs_fld> = prps_tab-post1.
    ...
    APPEND INITIAL LINE TO record_tab ASSIGNING <fs_record_tab>.
    <fs_record_tab>-string = <fs_struct>.
    IF callcontrol-maxrecords = LINES( record_tab ).
      EXIT.
    ENDIF.
  ENDLOOP.

*&---------------------------------------------------------------------*
*&      Form  make_struct
*&---------------------------------------------------------------------*
FORM make_struct USING    shlp     TYPE shlp_descr_t
                 CHANGING p_struct TYPE REF TO data.

  DATA: lo_type         TYPE REF TO cl_abap_elemdescr,
        lo_struct       TYPE REF TO cl_abap_structdescr,
        lt_comp         TYPE cl_abap_structdescr=>component_table,
        i_length        TYPE i,
        i_decimals      TYPE i.

  FIELD-SYMBOLS:
        <fs_fieldprop>  LIKE LINE OF shlp-fieldprop,
        <fs_fielddescr> LIKE LINE OF shlp-fielddescr,
        <fs_comp>       LIKE LINE OF lt_comp.

  LOOP AT shlp-fieldprop ASSIGNING <fs_fieldprop>
                         WHERE NOT shlplispos IS INITIAL.

    READ TABLE shlp-fielddescr ASSIGNING <fs_fielddescr>
               WITH KEY fieldname = <fs_fieldprop>-fieldname.

    IF sy-subrc = 0.

*     i_length   = <fs_fielddescr>-leng. " при повторном вызове LENG увеличивается в 2 раза :(
      i_length   = <fs_fielddescr>-intlen.
      PERFORM unicode_byte2char(saplsdsd) CHANGING i_length.

      i_decimals = <fs_fielddescr>-decimals.

      FREE lo_type.
      CASE <fs_fielddescr>-inttype.
        WHEN cl_abap_typedescr=>typekind_string.  lo_type = cl_abap_elemdescr=>get_string( ).
        WHEN cl_abap_typedescr=>typekind_xstring. lo_type = cl_abap_elemdescr=>get_xstring( ).
        WHEN cl_abap_typedescr=>typekind_int.     lo_type = cl_abap_elemdescr=>get_i( ).
        WHEN cl_abap_typedescr=>typekind_float.   lo_type = cl_abap_elemdescr=>get_f( ).
        WHEN cl_abap_typedescr=>typekind_date.    lo_type = cl_abap_elemdescr=>get_d( ).
        WHEN cl_abap_typedescr=>typekind_time.    lo_type = cl_abap_elemdescr=>get_t( ).
        WHEN cl_abap_typedescr=>typekind_char.    lo_type = cl_abap_elemdescr=>get_c( p_length = i_length ).
        WHEN cl_abap_typedescr=>typekind_num.     lo_type = cl_abap_elemdescr=>get_n( p_length = i_length ).
        WHEN cl_abap_typedescr=>typekind_hex.     lo_type = cl_abap_elemdescr=>get_x( p_length = i_length ).
        WHEN cl_abap_typedescr=>typekind_packed.  lo_type = cl_abap_elemdescr=>get_p( p_length = i_length p_decimals = i_decimals ).
      ENDCASE.

      IF lo_type IS BOUND.
        APPEND INITIAL LINE TO lt_comp ASSIGNING <fs_comp>.
        <fs_comp>-name       = <fs_fieldprop>-fieldname.
        <fs_comp>-type       = lo_type.
*       <fs_comp>-as_include
        <fs_comp>-suffix     = <fs_fielddescr>-offset. " <fs_fieldprop>-shlplispos.
      ENDIF.

    ENDIF.
  ENDLOOP.

* отсортировать поля в порядке вывода на экран
  SORT lt_comp BY suffix.

  LOOP AT lt_comp ASSIGNING <fs_comp>.
    CLEAR <fs_comp>-suffix.
  ENDLOOP.

* Create new type from component table
  lo_struct = cl_abap_structdescr=>create( lt_comp ).

* Create dynamic structure and assign to Field Symbol
*  FIELD-SYMBOLS: <fs_struct>  TYPE ANY.
  CREATE DATA p_struct TYPE HANDLE lo_struct.
*  ASSIGN lo_struct->* TO <fs_struct>.

ENDFORM.                    "make_struct

Автор:  nicky555 [ Чт, дек 03 2015, 13:57 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Stenj_90 написал(а):
Недавно столкнулся с тем, что средство поиска на ФМ работает по-разному на разных версиях базиса. Точнее, record_tab предполагает разный порядок полей. Более того, при первом и последующих вызовах порядок тоже может оказаться разный..

Мне казалось, ФМ-ов группы функций SF4U для подобных целей достаточно :roll:
Например, ФМ F4UT_RESULTS_MAP.

Автор:  GeneralLao [ Вт, окт 04 2016, 10:04 ]
Заголовок сообщения:  Re: Полезные трюки ABAP

Чтобы сдвинуть блок кода вправо, зажав альт выделяем колонку перед блоком, и затем пробелами или табляцией двигается весь блок

Страница 4 из 8 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/