Разбить смешанный ввод строки в диапазон отдельных значений - PullRequest
2 голосов
/ 11 февраля 2020

У меня есть вход, который позволяет несколько идентификаторов. Их можно ввести так:

[  1000, 1001, 1050-1060, 1100  ]              

Из этой входной строки я хочу получить все одиночные идентификаторы. Я уже обнаружил, что это делится после каждого ,, поэтому часть с 1000, 1001 уже работает.

data : itab TYPE TABLE OF string,
SPLIT l_bukrs_string AT ';' INTO TABLE itab.

Моя проблема - это самодельный диапазон. Любая идея, как я мог бы объединить это с вышеупомянутым случаем, чтобы разделить 1050-1060 на отдельные значения?

Я хочу получить 1050 | 1051 | 1052 | ... | 1060 вне его.

Ценю каждый намек :) Большое спасибо!

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Если вы получили строку со списком смешанных значений, одинарные и интервальные значения BUKRS, разделенные на da sh, и этот список отделяется запятой + пробел, тогда

DATA: input   TYPE string VALUE '1000, 1001, 1050-1060, 1100, 1300-1340',
      itab    TYPE TABLE OF char10,
      r_bukrs TYPE RANGE OF bukrs.

SPLIT input AT `, ` INTO TABLE itab.

r_bukrs = VALUE #( FOR GROUPS bukrs OF <bukrs> IN itab WHERE ( table_line+4(1) NE '-' ) GROUP BY <bukrs> WITHOUT MEMBERS ( sign = 'I' option = 'EQ' low = bukrs ) ).
DATA(ranges) = VALUE ddtest_ttyp_char( FOR GROUPS bukrs OF <bukrs> IN itab WHERE ( table_line+4(1) EQ '-' ) GROUP BY <bukrs> WITHOUT MEMBERS ( bukrs ) ).

LOOP AT ranges ASSIGNING FIELD-SYMBOL(<range>).
  r_bukrs = VALUE #( BASE r_bukrs FOR j = CONV i( <range>(4) ) UNTIL j = CONV i( <range>+5(4) ) + 1 ( sign = 'I' option = 'EQ' low = j ) ).
ENDLOOP.

Первое табличное выражение (7-я строка) заполняет r_bukrs уникальными значениями из исходной строки таблицы.

Второе табличное выражение (8-я строка) заполняет ranges таблицу диапазонами da sh, найденными в начальной строке таблицы, 1050-1060 и 1300-1340 в нашем случае.

В таблице от l oop до ranges <range>(4) - это левые экстремумы интервала, а <range>+5(4) - правые экстремумы, например 1300 и 1340 соответственно для последнего интервала значений.

1 голос
/ 11 февраля 2020

Самое простое решение - вместо этого использовать реальный диапазон / выбор для пользовательского (?) Ввода. Затем вы будете использовать этот диапазон для выбора каждого значения из таблицы базы данных.

Если вы не можете использовать реальный диапазон / параметр выбора, то вы можете преобразовать строку в единицу, как показано ниже.

DATA: bukrs_string   TYPE string,
      split_bukrs    TYPE TABLE OF string,
      bukrs          TYPE bukrs,
      bukrs_between  TYPE TABLE OF bukrs,
      bukrs_range    TYPE RANGE OF bukrs,
      bukrs_rline    LIKE LINE OF bukrs_range,
      bukrs_table    TYPE TABLE OF bukrs.

FIELD-SYMBOLS: <string>     TYPE string,
               <bukrs>      TYPE bukrs,
               <bukrs_from> TYPE bukrs,
               <bukrs_to>   TYPE bukrs.

bukrs_string = '1000, 1001, 1050-1060, 1100'.
CONDENSE bukrs_string NO-GAPS.
SPLIT bukrs_string AT ',' INTO TABLE split_bukrs.

LOOP AT split_bukrs ASSIGNING <string>.

  bukrs_rline-sign = 'I'.

  IF <string> CA '-'.

    SPLIT <string> AT '-' INTO TABLE bukrs_between.
    bukrs_rline-option = 'BT'.
    READ TABLE bukrs_between INDEX 1 ASSIGNING <bukrs_from>.
    bukrs_rline-low = <bukrs_from>.
    READ TABLE bukrs_between INDEX 2 ASSIGNING <bukrs_to>.
    bukrs_rline-high = <bukrs_to>.

  ELSE.

    bukrs_rline-option = 'EQ'.
    bukrs = <string>.
    bukrs_rline-low = bukrs.

  ENDIF.

  APPEND bukrs_rline TO bukrs_range.
  CLEAR bukrs_rline.

ENDLOOP.

SELECT bukrs
  FROM t001
  INTO TABLE bukrs_table
 WHERE bukrs IN bukrs_range.

Перед тем как разбить строку, вы должны сжать ее, чтобы удалить все пробелы. Тогда вы бы l oop над результирующими частями и проверили, содержит ли он '-'. Если это так, вы снова разделяете его и создаете в своем диапазоне запись BETWEEN (подумайте, не хотите ли вы провести дополнительную проверку, чтобы увидеть, действительно ли последнее число больше). Если нет «-», вы просто создаете запись EQUAL.

Получив реальный диапазон, вы используете его для выбора из базы данных. Это связано с тем, что не все букры в этом диапазоне должны существовать. Например, у вас может быть только 1000, 1050, 1055 и 1060.

Редактировать : причина нет команды, функционального модуля или класса для преобразования диапазона в отдельные значения, потому что то, что необходимо сделать, сильно изменяется в зависимости от того, ЧЕМ данные предназначены для диапазона, и если / сколько значений необходимо проверить. Если у вас есть целочисленный диапазон, то все, что вам нужно сделать, это взять значение from и добавлять к нему 1, пока не достигнете значения to. Как насчет диапазона двоичных чисел с плавающей точкой? А как насчет диапазона цветов? А как насчет ваших балансовых единиц, где не все они обязательно существуют? Вот почему преобразование должно быть сделано вручную.

...