Загрузка курсов валют в систему R/3 средствами ABAP

Работаю я 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 '(\W\w+\W\w+\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 начала врываться на сайт и заби-рать нужные данные во внутреннею таблицу. Программа забирала данные с сайта, потом из полученной таблички выдергиваются посредством регулярных выражений выдергива-ется коды и курсы валют, а дальше все это вводится в систему пакетным вводом.

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 11

    0
    На двух проектах, где вставала аналогичная задача, мы делали это средствами XI. Там вызов веб-сервиса на стороне ЦБ РФ и дальнейшая обработка полученного XML делаются, мне кажется, проще, чем только средствами ABAP.
      0
      Мне ставили задачу переделать уже имеющуюся программу, да и глубоких познаний у меня не было, пришлось выкручиваться в меру своих возможностей и знаний.
      +1
      А какая версия SAP, почему не используете стандартный парсер XML или XLST преобразования из xml в структуры?
      Более того, в зависимости от сервера действительно есть возможность напрямую использовать вебсервисы того же ЦБ.
        –1
        Со стандартным парсером разобраться не хватило ума. Тут у нас такие программисты, что у меня волосы шевелиться начинают в самых не скромных местах. Даже мое решение вызвало небывалый интерес.
        +1
        А дефисы в тексте это от абапа болезнь?
        Кстати, что за сайт? Просто классический cbrates.rbc.ru выдает в виде TAB separated values
          +1
          Интересно конечно, но я бы убил разработчика за такую реализацию.
          Тема парсинга XML поднималась тысячи раз, написаны сотни годных мануалов, читая которые мозг не взрывается и не нужно вникать в подробности. Параметры прокси отлично прописываются прямо в SM59 для соединений типа «G». Добило использование пакетного ввода. BAPI_EXCHANGERATE_CREATE зачем придумали?
          Конечно, отсутствие хорошего ТЗ — одна из основных причин подобного. Советую штудировать (хотя бы) SCN, если не можете разобраться и все хорошо с английским. Поверьте, если функционал который Вы используете вышел не в последнем EhP, там это уже обсудили и объяснили.
            0
            Добавлю от себя 5 копеек:

            Не используйте больше ФМ WS_UPLOAD — считается устаревшим. Пакетный ввод это кошмар в дальнейшем сопровождении, его стоит применять только в крайних случаях (отсутствие BAPI, FM, классов). Как отметили выше есть встроенные XML парсеры очень удобные в использовании, Simple Transformation к примеру.

            А вообще на хабре статья про ABAP это уже хорошо :)
              0
              К сожалению, у нас на предприятии знакомы исключительно только с пакетным вводом, и меня это очень сильно огорчает. А еще у нас довольно сложно вносить изменения в уже работающие программы. Пока пользователь не напишет служебную записку, что ему в программе не нравится, никто и не почешется.
              Это можно сказать моя первая программа на ABAP. Хоть опыта работы у меня не так много, но сейчас я написал бы по другому.

              Думаю в скором времени я еще что-нибудь напишу про ABAP

            Only users with full accounts can post comments. Log in, please.