Sapforum.Biz
Инструменты => ABAP - Инструментальные средства => Тема розпочата: Uukrul від Червень 11, 2014, 01:30:04 ПП
В общем есть табличка, в ней есть поле LGART = CHAR(4), делам запрос, идея получить все значения только цифрами. Вроде как можно ограничить между "0000" до "9999", буквы явно должны не входить в данный диапазон. Однако выбираются так же и значения содержащие буквы. Чего-то я завтыкал с этим запросом. У кого есть какие версии?
REPORT zi_test_pay.
DATA: lt_payment TYPE TABLE OF v_bw_t512t,
ls_payment TYPE v_bw_t512t.
SELECT * INTO TABLE lt_payment
FROM v_bw_t512t
WHERE langu = sy-langu AND
molga = '36' AND
( lgart BETWEEN '0000' AND '9999' ).
LOOP AT lt_payment INTO ls_payment.
WRITE: / ls_payment-langu,
ls_payment-molga,
ls_payment-lgart,
ls_payment-txtsh,
ls_payment-txtmd.
ENDLOOP.
REPORT ZRU_FOR_TESTING.
DATA: lt_payment TYPE TABLE OF v_bw_t512t,
ls_payment TYPE v_bw_t512t.
DATA: lv_chr(4) type c,
lv_num type p.
SELECT * INTO TABLE lt_payment
FROM v_bw_t512t
WHERE langu = sy-langu AND
molga = '36' AND
( lgart BETWEEN '0000' AND '9999' ).
LOOP AT lt_payment INTO ls_payment.
lv_chr = ls_payment-lgart.
CALL FUNCTION 'MOVE_CHAR_TO_NUM'
EXPORTING
CHR = lv_chr
IMPORTING
NUM = lv_num
EXCEPTIONS
CONVT_NO_NUMBER = 1
CONVT_OVERFLOW = 2
OTHERS = 3.
IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
CONTINUE.
ENDIF.
WRITE: / ls_payment-langu,
ls_payment-molga,
ls_payment-lgart,
ls_payment-txtsh,
ls_payment-txtmd.
ENDLOOP.
вроде ок =)
вообще это от того, что там тип данных char4 - цифры, буквы и т.д.
/вроде очевидно о_О
Цитата: Victor Ghost від Червень 20, 2014, 08:44:24 ДП
вообще это от того, что там тип данных char4 - цифры, буквы и т.д.
/вроде очевидно о_О
Да понятно что CHAR, но код символа цифра, меньше чем буква, поэтому я чего-то считал что при выборке с "0000" до "9999" значения с буквами никак не должно было попасть в выборку. Оказалось что попадает.
ага. только прикол в том, что после 9399 идет не 9400, как хотелось бы, а 939A
/почему-то вспоминается 16-ричная система исчисления
Цитата: Victor Ghost від Червень 20, 2014, 12:06:05 ПП
/почему-то вспоминается 16-ричная система исчисления
Да вот я тоже про это подумал.
Цитата: Victor Ghost від Червень 20, 2014, 12:06:05 ПП
16-ричная система исчисления
Есть такая фенька у САП - нумерация от 0...9 до A...Z. Встретилось такое на номерах запросов
Можно вот так сделать, вместо вывода занести в внутр. таблицу и отсортировать если есть по надобность и потом вывести .
При таком запросе есть один минус:
он пробежит по всей таблице где langu = sy-langu
AND molga = '36'
если данные под такими критериями не большие то в принципе можно использовать :)
DATA: lt_payment TYPE TABLE OF v_bw_t512t,
ls_payment TYPE v_bw_t512t.
DATA: result_tab TYPE match_result_tab.
select * into ls_payment
FROM v_bw_t512t
WHERE langu = sy-langu
AND molga = '36'.
CLEAR: result_tab[].
FIND ALL OCCURRENCES OF REGEX '([0-9][0-9][0-9][0-9])'
IN ls_payment-lgart
RESULTS result_tab .
IF result_tab[] is not INITIAL.
WRITE: / ls_payment-langu,
ls_payment-molga,
ls_payment-lgart,
ls_payment-txtsh,
ls_payment-txtmd.
ENDIF.
ENDSELECT.
можно попробовать вместо ( lgart BETWEEN '0000' AND '9999' ).
поставить в переменные типа numc или i.Жаль что у меня в этой таблицы нету позиций с 0000 >:( я бы по тестил :)))
Думаю что ты передаешь в скобках значение и он понимает как чаровское :)) и по этому выплевывает там и те что с буквами :)) а мои пример наверху где я использовал REGEX ищет только цифровое значение .
Цитата: sergiucz від Липень 02, 2014, 11:55:35 ПП
можно попробовать вместо ( lgart BETWEEN '0000' AND '9999' ).
поставить в переменные типа numc или i.Жаль что у меня в этой таблицы нету позиций с 0000 >:( я бы по тестил :)))
Проверил, один фиг, вот такая же программка возвращает тот же результат, с буквами, кстати тип I, еще хуже получается там вообще лезет все со спецсимволами типа / и т.д. Так что не работает. Кстати, по поводу 16-ричных цифр, тоже фигня, так как там лезут буквы типа в коде 019N, что никак не тянет на 16-ричную систему.
REPORT zi_test_pay.
DATA: lt_payment TYPE TABLE OF v_bw_t512t,
ls_payment TYPE v_bw_t512t.
DATA: l_start(4) TYPE n,
l_end(4) TYPE n.
l_start = '0000'.
l_end = '9999'.
SELECT * INTO TABLE lt_payment
FROM v_bw_t512t
WHERE langu = '8' AND
molga = '36' AND
( lgart BETWEEN l_start AND l_end ).
LOOP AT lt_payment INTO ls_payment.
WRITE: / ls_payment-langu,
ls_payment-molga,
ls_payment-lgart,
ls_payment-txtsh,
ls_payment-txtmd.
ENDLOOP.
Регулярные выражения, можно, но это уже пост-обработка, и там вариантов вагон и тележка если честно начиная с операции CS (ContainString) в условиях.
а в RANGES с типом n или i поставить не пробовал ? и вместо BETWEEN использовать in
1 Создать внутреннюю таблицу с ключами от 0000 до 9999 и потом выполнить поиск
по for all entries
2. Создать прозрачную таблицу с ключами от 0000 до 9999 и выполнить поиск с JOIN
Скорости правда, по всей видимости будут не очень и проще, наверное, потом отсеять все не цифровые ключи.
Цитата: nick_mi від Липень 03, 2014, 01:36:56 ПП
1 Создать внутреннюю таблицу с ключами от 0000 до 9999 и потом выполнить поиск
по for all entries
2. Создать прозрачную таблицу с ключами от 0000 до 9999 и выполнить поиск с JOIN
Ну это все уже обход... решений много может быть, что быстрее можно наверное потом будет отдельно померить :-)