ABAP: Selection of reference values ​​by their keys from database tables

Not so long ago I wrote a method for fetching reference values ​​for their keys into an internal table by creating a dynamic program. Unfortunately, the source code cannot be attached, as the authorities forbade it to be done. So I will limit myself to a general description of the theory.

For example, we have an internal table:

DATA:
  begin of it_TABLE occurs 0, 
      BE type T001-BUKRS,
      BENAME type T001-BUTXT,
  end of it_TABLE
.

The table is filled with a field BE and we have to choose from a T001 value BUTXT by appropriate BE and fill in the beName . How to do this “correctly” (that is, with minimal memory overhead and as quickly as possible).

  1. Select unique values ​​for the BE field;
  2. Let's make FOR ALL ENTRIES of T001;
  3. We go through the internal table and for each BE we find the corresponding value in the data selected from T001. (Of course, we use a HASH table to speed up the search)
And this sequence is always the same.
Here is the code for this process
FIELD-SYMBOLS:
   like line of it_Table
.  
*-- Создаем список уникальных значений поля BE
TYPES:
	BEGIN OF s_k1,
		BUKRS type T001-BUKRS,
	END OF s_k1
.
DATA:
	it_k1 TYPE SORTED TABLE OF s_k1 WITH UNIQUE KEY
	 BUKRS
	, wa_k1 like line of it_k1.
LOOP AT it_Table ASSIGNING .
	wa_k1-BUKRS = -BE.
	INSERT wa_k1 INTO TABLE it_k1.
ENDLOOP.
*-- Выбираем список значений из T001 по сформированным ключам
TYPES:
	BEGIN OF s_v1,
		BUKRS TYPE T001-BUKRS,
		BUTXT TYPE T001-BUTXT,
	END OF s_v1
.
DATA:
	it_v1 TYPE SORTED TABLE OF s_v1 WITH NON-UNIQUE KEY
	BUKRS
	, wa_v1 like line of it_v1.
IF it_k1[] IS INITIAL.
	REFRESH it_v1.
ELSE.
	SELECT
	 BUKRS
	 BUTXT
	 FROM T001
	 INTO CORRESPONDING FIELDS OF TABLE it_v1
	  FOR ALL ENTRIES in it_k1
	WHERE BUKRS = it_k1-BUKRS
	.
ENDIF.
*-- Присваиваем значения по ключам
LOOP AT it_Table ASSIGNING .
	READ TABLE it_v1 INTO wa_v1
	 with table key
		BUKRS = -BE
	.
	IF sy-subrc = 0.
		-BENAME = wa_v1-BUTXT.
	ELSE.
		CLEAR -BENAME.
	ENDIF.
ENDLOOP.
And if the same actions are always performed at our place, then it is worth reducing their description to a minimum. In particular, in this case, we need to specify the table from which we need to select, the key fields and fields from which to write data.

Those. we have the following small line in which the whole essence of the above code is written:
  'T001{BUKRS=BE}{BUTXT>BENAME}'   

We pass to the method the line above + our internal table. And after calling the method, the BENAME field will be filled with the corresponding values ​​from T001-BUTXT. We have reduced our code, besides, it is enough for another programmer to have help on hand by the method and he will quickly understand what this line does. In this case, the entire algorithm fits into a small line.
Here is the code generated by my method
 TYPES:
   BEGIN OF s_k1,
     BUKRS type T001-BUKRS,
   END OF s_k1
 .
 DATA:
    it_k1 TYPE SORTED TABLE OF s_k1 WITH UNIQUE KEY
     BUKRS
   , wa_k1 like line of it_k1.
 FIELD-SYMBOLS:
     type ANY,
     type ANY
 .
"-- Создаем список уникальных значений поля BE
 LOOP AT  ASSIGNING .
   "--
   ASSIGN COMPONENT 'BE'
       OF STRUCTURE 
       TO .
   wa_k1-BUKRS = .
   "-- Добавить в список ключей
   INSERT wa_k1 INTO TABLE it_k1.
 ENDLOOP.
 TYPES:
   BEGIN OF s_v1,
     BUKRS TYPE T001-BUKRS,
     BUTXT TYPE T001-BUTXT,
   END OF s_v1
 .
 DATA:
   it_v1 TYPE SORTED TABLE OF s_v1 WITH NON-UNIQUE KEY
    BUKRS
   , wa_v1 like line of it_v1.
*-- Выбираем значения из T001
 IF it_k1[] IS INITIAL.
   REFRESH it_v1.
 ELSE.
   SELECT
     BUKRS
     BUTXT
     FROM T001
     INTO CORRESPONDING FIELDS OF TABLE it_v1
      FOR ALL ENTRIES in it_k1
    WHERE BUKRS = it_k1-BUKRS
   .
 ENDIF.
 FREE it_k1.
*-- Присваиваем значения по ключам
 LOOP AT  ASSIGNING .
   ASSIGN COMPONENT 'BE'
       OF STRUCTURE  TO .
   ASSIGN COMPONENT 'BENAME'
       OF STRUCTURE  TO .
   "-- Читаем значение
   READ TABLE it_v1 INTO wa_v1
     with table key
        BUKRS = 
   .
   IF sy-subrc = 0.
      = wa_v1-BUTXT.
   ELSE.
     CLEAR:
       
     .
   ENDIF.
 ENDLOOP.
 FREE it_v1.
 
For the method to work fully, we add the ability to specify constants and system variables to it (for example, sy-langu is often required to select texts). We also add the ability to specify a list of commands - then we can sequentially select the data.

How it works? - using dynamic programs. Those. The method analyzes the parameters passed through the string, generates a dynamic program and starts it. Adding a program occurs through "INSERT REPORT l_repid FROM CODE." So as not to be limited by the number of programs created.

PS I am especially pleased with this method when I have to choose a lot of values ​​and periodically in the process of working from the director an indication is added to add new fields for the selection.

update: The process code was written in the correct form - it turned out 53 lines. Parameter line + method call = 5 lines. Those. the code has been reduced by 10 times and now it is placed within one page. Which, in my opinion, greatly enhances readability.

Also popular now: