Предыстория
Вот создали вы собственную Z-таблицу с полем типа HKONT. Счёт главной книги используется восьмизначный.
И вот вы начали заполнять её данными вручную или грузить напрямую из файла без использования SM30.
wa-HKONT = ‘10100000’.
insert into zhkont values wa.
Потом оказалось, что когда вы делаете выборку по таким данных из таблиц SAP, то вы не находите данных. Вы видите, что в таблице SKB1 значения сидят с лидирующими нулями (‘0010100000’) – значит надо приклеить спереди два лидирующих нуля.
concatenate ’00’ wa-hkont(8) into lv_hkont.
select single xspeb into lv_xspeb from skb1 where bukrs = p_bukrs and saknr = lv_hkont.
И вот вы протестировали, успокоились, передали запрос и забыли.
А грабля лежит расставленная и ждёт своих жертв:
У типа данных работает программа преобразования при вводе и при выводе: при вводе дописывает лидирующие нули, при выводе убирает лидирующие нули.
Но (а) эта подпрограмма не работает в режиме прямого доступа к данным, и (б) только тогда когда значение – полностью численное.
А так как тип данных текстовый, то проверки на целочисленность никогда не делается. Технически разрешается использовать латинские буквы, что часто и делается, а количество пробелов и нулей – тоже не проверяется базой данных.
Последствия
И вот спустя какое-то время до кого-то доходят спец.эффекты:
1. В таблице не работает выборка по условию в SE16
Открываете se16, в поле для поиска вбиваете значение 10100000. А данные отсутствуют. В состоянии недоумения открываете таблицу без фильтра – видите значения. Копируете-вставляете – результат нулевой.
В этом случае помогает следующий workaround – добавить звёздочку в конец. Глупо, но работает.
В чём фикус: SE16 снимает ваши данные ввода, дописывает нули, делает запрос с лидирующими нулями, и не находит, потому что физически в поле лежит значение без лидирующих нулей.
А так как вы добавили звёздочку, то лидирующие нули не дописываются – и данные выбираются.
2. После того как вы настроили ведение данных SM30 программа разваливается
Данные, вводимые через SM30 (как и любые другие способы непрямой записи) начинают вводить программу в заблуждение.
Она клеит лидирующие нули, получает из уже правильного значения ‘001010000’ уж совсем неправильное значение вроде ‘0000101000’.
Особо настырные разработчики будут усиливать нажим:
if lv_hkont1(2) = ’00’.
lv_hkont2 = lv_hkont1.
else.
concatenate ’00’ lv_hkont1 into lv_hkont2.
endif.
И куда такое может дальше завести…. ?
3. Программа разваливается на технических счетах
Точно также как и в предыдущем пункте, только дополнительный нажим достигается другими дополнительными проверками.
4. Перенос разработки в другую систему – непредсказуем
В другой системе может использоваться другой подход к нумерации счетов – что будет в результате работы программы предсказать сложно. Но в любом случае – ничего хорошего.
Что делать?
1. Продолжать использовать поля с преобразованием – так же как и везде в SAP.
2. Обрабатывать данные на границе системы. Вставлять в Z-таблицу только обработанные данные. Внутри работать только с правильными лидирующими нулями, где конвертация не требуется.
Если нашли внутри старые необработанные данные – обработать и забыть.
3. Никогда не использовать concatenate для выправления таких ситуаций.
Для этого есть стандартная функция:
CALL FUNCTION ‘FI_ALPHA_CONVERT’
EXPORTING I_STRING = wa-hkont
IMPORTING E_STRING = wa-hkont.
4. Помнить, что это касается не только счетов главной книги, но дебиторов, кредиторов и прочих.
5. Есть, конечно, нюансы, но о них как-нибудь при случае ещё напишу.