Работаю я ABAP-программистом на одном весьма крупном промышленном пред-приятии. Занимаюсь в основном поддержкой и сопровождением, потому в работе часто бывают затишья. Решил написать статью про ABAP.
Когда устраивался на работу R/3 я уже видел и кое-что умел делать. ABAP/4 мы изучали в институте. Показали основной синтаксис, да пару программ написали простеньких.
Первую неделю на работе я читал книжку по ABAP и скучал откровенно. По про-шествии некоторого времени, мне, наконец-то, дали задание.
Кому интересно добро пожаловать.
Как оказалось, задание было направленно на решение довольно распространенной проблемы. А именно, загрузка курсов валют в систему с сайта центробанка.
В нашей фирме есть человек, который занимается вводом этих самых курсов.
Как работало это до моего вмешательства. Пользователь заходил на сайт центро-банка, копировал табличку с курсами, потом скриптом написаным на питоне это дело приводилось в нужный вид, а затем пользователь запускал транзакцию в R/3 и скармливал программе полученный текстовый файл. Крайне мудреная операция.
Принялся я за работу.
Вначале я посмотрел сайт центробанка и узнал, что с сайта можно забрать курсы валют в виде XML файла. Я решил
R/3 умеет кушать XML файлы, но как работает Функциональный модуль для рабо-ты с XML я тогда разобраться не сумел и решил написать свой велосипед, молодой был. Методом не хилого закапывания в интернет, хелп и умную книжку я нашел ФМ который считывает файл во внутреннею табличку. Получилась вот такая вот форма:
*Подпрограмма чтения фаила в таблицу.
form get_file tables table_name using file_name like rlgrap-filename.
call function 'WS_UPLOAD'
exporting
CODEPAGE = ' '
FILENAME = FILE_NAME
FILETYPE = 'ASC'
tables
DATA_TAB = TABLE_NAME
exceptions
CONVERSION_ERROR = 1
FILE_OPEN_ERROR = 2
FILE_READ_ERROR = 3
INVALID_TYPE = 4
NO_BATCH = 5
OTHERS = 6.
*Вывод сообщения об ошибке.
case sy-subrc.
when 1.
write 'Ошибка конвертирования данных.'.
exit.
when 2.
write 'Ошибка открытия фаила.'.
exit.
when 3.
write 'Ошибка чтения фаила.'.
exit.
when 4.
write 'Неправельный тип фаила.'.
exit.
when 5.
write 'Front-End Function Cannot Be Executed in Backgrnd.'.
exit.
when 6.
write 'Другая ошибка.'.
exit.
endcase.
endform.
ФМ выдает табличку TABLE_NAME в которой каждая строка это строка загру-женного файла. Встал вопрос как из строк вида:
<Valute ID="R01010">
<NumCode>036</NumCode>
<CharCode>AUD</CharCode>
<Nominal>1</Nominal>
<Name>Австралийский доллар</Name>
<Value>27,0138</Value>
</Valute>
Выудить код валюты, номинал и собственно курс. На предыдущей работе занимал-ся вэб-разработкой, особых успехов на этом поприще я не добился, но кое какие полезные знания получил. В общем при очередном погружении в хелп я узнал что в язык ABAP умеет работать с регулярными выражениями. Не долго думая я соорудил конструкцию типа:
* Извлечение даты курса валют.
read table valuta into valuta index 2.
RE-PLACE REGEX '(Ww+Ww+W+)(d+)(D)(d+)(D)(d+)(W+w+W+w+.w+)' IN valuta WITH `$2.$4.$6`.
if sy-subrc = 0.
date = valuta.
endif.
* Заполнение внутренней таблицы курсами валют.
loop at l_val into l_val.
clear val.
if l_val-waers <> 'UE'.
* Поиск в таблице срдержащей курсы валют XML фаила необходимых валют.
concatenate '<CharCode>' l_val-waers '</CharCode>' into s_val.
find s_val in table valuta match line index.
if sy-subrc = 0.
val-kodv = l_val-waers.
val-datan = date.
add 1 to index.
read table valuta into valuta index index.
* Извлечение номинала валюты.
REPLACE REGEX '(W+w+W)(d+)(W+w+W)' IN valuta WITH '$2'.
nom = valuta.
add 2 to index.
read table valuta into valuta index index.
* Извлечение и перерасчет курса валюты.
RE-PLACE REGEX '(W+w+W)(d+)(D)(d+)(W+w+W)' IN valuta WITH '$2.$4'.
if sy-subrc = 0.
tmp = valuta / nom.
val-kyrsp = tmp.
replace all occurrences of '.' in val-kyrsp with ','.
* Добавление данных в таблицу.
append val.
endif.
else.
s_val = text-wv1.
replace '&1' in s_val with l_val-waers.
message s_val type 'I'.
endif.
endif.
endloop.
Коряво, но я тогда был горд собой, когда всё это дело заработало.
К этому времени мне выдали логин и пароль для доступа в интернет. И начальник предложил посмотреть в сторону функционального модуля HTTP_GET. Но к несчастью документации по этому модулю в нашей системе не было, пришлось догадываться на ощупь, как с этим чудом работать.
Я пробовал скармливать URL пароль и логин к прокси, но результата не было. По-сле нескольких экспериментов, я определил, что прокси сервер не пропускает во внешний мир.
Пришлось опять закапываться в гугл и форумы. На одном из форумов я нашел ре-шение. Оказывается, что HTTP_GET криво общается с проксями и предлогалось решение.
Данные по прокси надо прописывать в табличке THTTP, в поле EXITFUNC этой таблицы надо прописать функциональный модуль 'HTTP_PROXY_CONFIG' (он определяет требуется ли прокся для подключения к URL, если да, то передаются данные из строки таблицы).
Ну и сам вызов функционального модуля выглядит у меня примерно так:
call function 'HTTP_GET'
exporting
absolute_uri = url
blankstocrlf = 'x'
timeout = 500
rfc_destination = 'SAPHTTP'
tables
response_entity_body = file_table
response_headers = file_headers
exceptions
connect_failed = 1
timeout = 2
internal_error = 3
tcpip_error = 4
data_error = 5
system_failure = 6
communication_failure = 7.
После всех манипуляций и пляски с бубном R/3 начала врываться на сайт и заби-рать нужные данные во внутреннею таблицу. Программа забирала данные с сайта, потом из полученной таблички выдергиваются посредством регулярных выражений выдергива-ется коды и курсы валют, а дальше все это вводится в систему пакетным вводом.
Автор: Cr0w