Sapforum.Biz
Инструменты => ABAP - Инструментальные средства => SE38 - ABAP Редактор => Тема начата: Uukrul от Апрель 16, 2012, 10:26:26 pm
-
Для программ работающих на сервере приложений, выгрузка данных обычно выполняется через операции OPEN DATASET / CLOSE DATASET и тут встает проблема как выгрузить данные в нужной кодировке для кириллических букв. Системы обычно сейчас юникодные и значит при выгрузке кодировка будет скорее всего UTF-8, но тут встал вопрос что файл должен быть выгружен в кодировке WIN1251 и это файл формата XML. На форумах есть разные варианты, в основном они касаются выгрузки на фонтэнд, для фоновых процессов был найден вариант да и тот предлагал использовать выгрузку в XML со схемой XML. Загвоздка оказалась в том, что я XML не знаю, а его схему тем более. Сформировать файл в заданной XML структуре во внутреннюю таблицу не вопрос, а вот как дальше ее выгрузить?! Короче покопавшись в справке SAP предлагает следующий вариант.
Потребуются следующие переменные:
DATA: hx(2) TYPE x VALUE '0D0A', "Перевод строки для WIN1251
l_str TYPE string,
g_buffer TYPE xstring, "Байтовый буфер в кодировке WIN1251
encoding TYPE string, "Строка кодировки
codepage_n TYPE cpcodepage, "Кодовая страница к кодировке число
codepage_c TYPE abap_encoding, "Кодовая страница как строка
cvto_win TYPE REF TO cl_abap_conv_out_ce.
DATA: BEGIN OF gt_xml_cskt OCCURS 10,
line type string,
END OF gt_xml_cskt.
Для начала получим саповскую кодовую страницу для кодировки WIN1251, для этого есть специальная функция:
encoding = 'windows-1251'.
CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
EXPORTING
external_name = encoding
IMPORTING
sap_codepage = codepage_n
EXCEPTIONS
not_found = 1
OTHERS = 2.
Чтобы узнать вот этот вот код windows-1251, можно просмотреть таблицу TCP00A и там познавательно можно посмотреть соответствие кодовых таблиц SAP общепринятым кодировкам типа KOI8 и т.д. Так что на выходе получаем кодовую таблицу SAP, для кодировки WIN1251 что будет равно 1504. Конечно можно сразу подставлять дальше код 1504, но мы же пишем правильно и на все случаи 8). Далее создадим класс который будет производить конвертацию данных из UTF-8 в нашу WIN1251, точнее 1504. Проблема тут в том, что предыдущая функция возвращает кодировку в типе NUM, а класс требует передачи параметра типа CHAR, поэтому заводим еще одну переменную, которую и передаем в класс в качестве кодовой страницы. Класс CL_ABAP_CONV_OUT_CE:
codepage_c = codepage_n.
CALL METHOD cl_abap_conv_out_ce=>create
EXPORTING
encoding = codepage_c
RECEIVING
conv = cvto_win.
Далее очищаем принимающий буфер для нашего экземпляра класса
cvto_win->reset( ).
И теперь перегоняем в буфер нашу внутреннюю таблицу которая содержит данные в формате XML. На вход передаем просто строку и далее передаем символ перевода строки, а то иначе файл выгрузится в одну строку.
LOOP AT gt_xml_cskt.
CALL METHOD cvto_win->write
EXPORTING
data = gt_xml_cskt-line.
CALL METHOD cvto_win->write
EXPORTING
data = hx.
ENDLOOP.
Теперь открываем файл для записи. Обратите внимание, что файл надо открывать с параметром BINARY MODE иначе в файле получите коды символов вместо внятных данных.
OPEN DATASET g_file_cost FOR OUTPUT IN BINARY MODE.
Записываем буфер в файл:
TRANSFER cvto_win->get_buffer( ) TO g_file_cost.
После чего закрываем файл:
CLOSE DATASET g_file_cost.
Все данные в файле будут в кодировке WIN1251. Так сказать быстро и просто.
PS: Во внутренней таблице gt_xml_cskt данные записаны типа в таком виде, каждая строка отдельная строка внутренней таблицы:
<?xml version="1.0" encoding="windows-1251" ?>
<MVZ date_time="16.04.2012 23:21:02" unit_count="ОАО «Пупкин и КО»">
<unit Index="1 ">
<Kod>3000200001</Kod>
<Name>Отдел передачи данны</Name>
<Date>31.12.9999</Date>
</unit>
</MVZ>
-
Огромное человеческое спасибо! :)
Только не прокатывает по синтаксису
TRANSFER cvto_win->get_buffer( ) TO g_file_cost.
Сап хочет что-то вроде
DATA: lv_xstring TYPE xstring.
...
CALL METHOD lo_win_coder->get_buffer
RECEIVING
buffer = lv_xstring.
-
Сап хочет что-то вроде
CALL METHOD lo_win_coder->get_buffer
RECEIVING
buffer = lv_xstring.
К сожалению с версии 7.0х, по версию 7.3х а уж тем более в версии 7.4х очень много чего изменилось в абапе. Как минимум практически нет переносимости кода с верхних версий вниз и чем дальше, тем так сказать версии разбегаются. Абап 7.4х поверьте вещь и писать на нем намного удобнее и понял я это, когда пришлось недавно делать программу обратно совместимой для 7.0х, точнее она должна была параллельно работать в двух разных системах 7.0х и 7.4х. Поверьте, очень сильно ругался, пока делал. Так что чем дальше, тем более странные синтаксисы операторов вы будете видеть на этом форуме 8)
PS: Вообще у меня тут есть мысль, по поводу абапа 7.4х пописать о различиях и удобствах, но все никак руки не доходят.
-
Не очень понял Ваш пост про версии.
Я работаю в системе с абап 7.40. И код 2012 года в нем должен работать по-любому.
Еще раз Вам спасибо :)
-
Я работаю в системе с абап 7.40. И код 2012 года в нем должен работать по-любому.
Если честно, я не помню когда вышло ядро 7.40, но к примеру абап 7.40 отличается от ABAP 7.31 и очень сильно отличается от ядер абапа 7.01 / 7.02. Поэтому работать по любому, я бы не взялся утверждать. Точнее смотря как вы пишете... и что пишете.