Текущее время: Вт, июл 29 2025, 19:49

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Изменение кодировки кириллического файла в user-exit
СообщениеДобавлено: Ср, июл 25 2007, 11:52 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Привет, коллеги.

Заранее приношу извинения за довольно заезженную тему. Но, к сожалению, поиск по форуму и многочисленные (в т.ч. полезные) ответы специалистов не помогают решить проблему.

А проблема такова:
Ситема ECC 6.0, Юникод. Файл с текстовой кириллической информацией загружается в систему стандартной программой (тр. FF_5, выписка банка). Кодировка, используемая в файле - DOS 866. После загрузки файла и до его обработки следующим алгоритмом программы мне становится доступен массив строк типа c в user-exit'е. Кириллица на этом этапе отображается, как набор символов псевдографики (видимо, при запуске UPLOAD-функции SAP по-умолчанию использовала CODEPAGE 1504 вместо нужной 1503).

Вопрос - как перекодировать, чтобы кириллица приняла нормальный вид?

Пробовал вот что (с разнообразными вариациями):
Исходная строка:
— >24ЋЇ« в § в®ў а. ‚Є«оз п Ќ„>25‘ 30508.47а.
Код (спасибо sibrin за пример http://sapboard.ru/forum/viewtopic.php?t=25668&start=0&postdays=0&postorder=asc&highlight=buf+1024)
Code:
DATA:
  buf(1024) TYPE x,
  conv TYPE REF TO cl_abap_conv_x2x_ce,
  view TYPE REF TO cl_abap_view_offlen,
  conv2 TYPE REF TO cl_abap_conv_x2x_ce.

FIELD-SYMBOLS: <c> TYPE c.

LOOP AT t_raw_data into lf_raw_data.

ASSIGN buf TO <c> CASTING.
<c> = lf_raw_data.
conv = cl_abap_conv_x2x_ce=>create( in_encoding = '1500' out_encoding = '1504' input = buf IGNORE_CERR = ABAP_TRUE ).
conv->convert_c( ).
buf = conv->get_out_buffer( ).
lf_raw_data = <c>.
conv2 = cl_abap_conv_x2x_ce=>create( in_encoding = '1503' out_encoding = '1500' input = buf IGNORE_CERR = ABAP_TRUE ).
conv2->convert_c( ).
buf = conv2->get_out_buffer( ).
lf_raw_data = <c>.

  modify t_raw_data from lf_raw_data index sy-tabix.

ENDLOOP.


Результирующая строка практически не изменилась.

Всем заранее спасибо за помощь.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 12:08 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Ср, ноя 23 2005, 13:37
Сообщения: 1805
Откуда: ECC 6.0
Пол: Мужской
У вас система юникодная, поэтому нужно использовать CL_ABAP_CONV_IN_CE.
Code:
data: ce type ref to CL_ABAP_CONV_IN_CE
    , buf(200) type x
    , cdata(100)
    , n type i
    .
*field-SYMBOLS: <f> type c.
*assign buf to <f> casting.
*<f> = '‡ ?®¤??®? ­­ ? ???®?'.
buf = '87A0AAAEA4A8E0AEA2A0ADADA0EF20E1E2E0AEAAA0'.
n = 21.

ce = CL_ABAP_CONV_IN_CE=>create( encoding = '1503' ).
ce->convert(
    exporting input = buf
              n     = n
    importing data  = cdata
  ).
write cdata.

Так даже лучше, потому что и в неюникодной системе тоже сработает.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 14:10 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Огромное спасибо за ответ.

Но у меня есть уточняющий вопрос.

Текст в программе хранится в переменной lf_raw_data(512) TYPE c. Как его правильно передать в BUF?

Еще раз спасибо.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 14:25 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Ср, ноя 23 2005, 13:37
Сообщения: 1805
Откуда: ECC 6.0
Пол: Мужской
Раскомментировать три строчки, которые в примере закомментированы.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 15:00 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Огромное спасибо за ответ.

Но у меня есть уточняющий вопрос.

Текст в программе хранится в переменной lf_raw_data(512) TYPE c. Как его правильно передать в BUF?

Еще раз спасибо.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 15:08 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Так я пробовал :)

Даже полностью латинский текст на входе превращается на выходе примерно вот во что:

#:#2#5#:#A#B#N#A#R#U#M#M#/#5#0#7#3#2#2#7#R#U#R# # # # # # # # # #

Как можно исправить?


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 15:37 
Гуру-эксперт
Гуру-эксперт

Зарегистрирован:
Вт, сен 07 2004, 17:47
Сообщения: 2988
Nord написал(а):
Так я пробовал :)

...

Как можно исправить?

Покажите Ваш код, что и как вы делаете.

_________________
"После" - не значит "вследствие"


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 15:44 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Пожалуйста:

Code:
DATA:
  buf(1024) TYPE x,
  conv TYPE REF TO cl_abap_conv_x2x_ce,
  view TYPE REF TO cl_abap_view_offlen,
  conv2 TYPE REF TO cl_abap_conv_x2x_ce.

FIELD-SYMBOLS: <c> TYPE c.
data: ce type ref to CL_ABAP_CONV_IN_CE
    , n type i
    .
data str type string.
*data buf type xstring.

LOOP AT t_raw_data into lf_raw_data.

field-SYMBOLS: <f> type c.
assign buf to <f> casting.
<f> = lf_raw_data.

n = 65.

ce = CL_ABAP_CONV_IN_CE=>create( encoding = '1503' IGNORE_CERR = ABAP_TRUE ).
ce->convert(
    exporting input = buf
              n     = n
    importing data  = lf_raw_data
  ).
endloop.


Есть скриншоты до и после конвертации. Не знаю только, как прислать...


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 16:49 
Гуру-эксперт
Гуру-эксперт

Зарегистрирован:
Вт, сен 07 2004, 17:47
Сообщения: 2988
Nord написал(а):
...

Есть скриншоты до и после конвертации. Не знаю только, как прислать...

Скриншиты не нужны, а вот шестнадцатеричное представление данных хотелось-бы увидеть. Хотя-бы для выше-приведённой строки "— >24ЋЇ« в § в®ў а. ‚Є«оз п Ќ„>25‘ 30508.47а. "

_________________
"После" - не значит "вследствие"


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 17:57 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
Пожалуйста (только пример на другой строчке):

Это оригинал (так в файле)

ИХАИЛ АЛЕКСАНДРОВИЧ >24Оплата за товар. Включая НД>25С 30508.47р.

Это пападает в экзит
€•Ђ€‹ Ђ‹…Љ‘ЂЌ„ђЋ‚€— >24ЋЇ« в § в®ў а. ‚Є«оз п Ќ„>25‘ 30508.47а.

Это пападает в экзит (побайтово)
20AC2022040220AC20390020040220392026040920180402040C201E0452040B201A20AC20140020003E00320034040B040700AB00A0043200A0002000A700A00020

Это после перекодировки
м "## м 9# ## 9 &## ↑#### ##R## → м ¶# #>#2#4#####л#а#2#а# #з#а#

Это после перекодировки (побайтово)
0020043C00200022000400020020043C00200039000000200004000200200039002000260004000900202191000400020004000C0020001E000400520004000B0020


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 18:21 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Ср, ноя 23 2005, 13:37
Сообщения: 1805
Откуда: ECC 6.0
Пол: Мужской
Понятно. Никак не привыкну к юникодным системам. lf_raw_data типа C, значит уже содержит юникод.

Надо сначала с помощью CL_ABAP_CONV_OUT_CE закодировать всё в X, используя ту же саповскую кодовую страницу, которую он подразумевал раскодируя всё в юникод: скорее всего это ISO-8859-5, а может и Latin 1, кто его знает...

А потом уже раскодировать с помощью CL_ABAP_CONV_OUT_CE используя правильную кодовую страницу, т.е. cp866.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 18:28 
Председатель
Председатель
Аватара пользователя

Зарегистрирован:
Чт, апр 13 2006, 12:32
Сообщения: 1503
Откуда: Питер
Может вам лучше файл перекодировать в windows перед загрузкой в ff_5 или разобраться, где кодирока каверкается. Например, у меня на проекте выписки приходят от 8 банков, если каждый банк начнет в своей кодировке присылать... ИМХО, идеологически неправильно делать перекодировку в user-exit.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср, июл 25 2007, 19:07 
Ассистент
Ассистент

Зарегистрирован:
Вс, авг 29 2004, 15:18
Сообщения: 35
2 vga:

Спасибо за ответ. Первое, что я выяснил, это то, что файлы формируются непосредственно в банке и присылаются клиенту готовые. Менять это банк не собирается (i.e. этих изменений прийдется ждать долго, если настаивать).

Перекодировать в windows - это менее управляемо, чем то же самое делать в SAP/ABAP.

Насчет идеологии - ну, спорить не стану. Это будет непродуктивный диалог :).

Успехов.

2 sibrin:

Получилось!!! Спасибо огромное!!! Вот, в итоге, рабочий код:

Code:
DATA:
*  buf(1024) TYPE x,
  conv TYPE REF TO cl_abap_conv_x2x_ce,
  view TYPE REF TO cl_abap_view_offlen.

FIELD-SYMBOLS: <c> TYPE c.
data: ce type ref to CL_ABAP_CONV_IN_CE,
      n type i.

data str type string.
data buf type xstring.

LOOP AT t_raw_data into lf_raw_data.

str = lf_raw_data.

call function 'SCMS_STRING_TO_XSTRING'
  exporting text = str
            encoding = '1504'
  importing buffer = buf.

n = 65.

ce = CL_ABAP_CONV_IN_CE=>create( encoding = '1503' IGNORE_CERR = ABAP_TRUE ).
ce->convert(
    exporting input = buf
              n     = n
    importing data  = lf_raw_data
  ).

modify t_raw_data from lf_raw_data.

endloop.


Еще раз, большое спасибо.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, янв 18 2008, 16:33 
Младший специалист
Младший специалист

Зарегистрирован:
Чт, янв 17 2008, 14:22
Сообщения: 64
Товарисчи, Помогите пожалуйста.
Такая же проблема в 4.6С.
Не могу решить


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, янв 18 2008, 17:27 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Сб, сен 25 2004, 16:30
Сообщения: 1368
Откуда: Москва
Пол: Мужской
Идея вы том, чтобы загрузить файл с рабочей станции в бинарном виде, потом перекодировать при помощи
Code:
TRANSLATE l_ex_line FROM CODE PAGE '1503'.

На моем текущем проекте (4.6с) работает. Пример кода загрузки файла:
Code:
IMPORTINTG
IM_FILENAME   TYPE RLGRAP-FILENAME
CHANGING
VALUE( CH_FILELENGTH )   TYPE I OPTIONAL
CH_DATA_TAB   TYPE STANDARD TABLE

METHOD upload_dos_file.
  DATA:
    filename   TYPE rlgrap-filename,

    l_len TYPE i,
    l_ofs TYPE i,
    l_fdpos TYPE i,

    l_line TYPE text1024,
    l_ex_line TYPE text4096,
    lt_data TYPE TABLE OF text1024,
    l_ref TYPE REF TO data,

    lcl_tabdescr TYPE REF TO cl_abap_tabledescr,
    lcl_strdescr TYPE REF TO cl_abap_structdescr,

    BEGIN OF eol,
      eol(2) TYPE x VALUE '0D0A',
    END OF eol.

  FIELD-SYMBOLS:
    <fs_char> TYPE ANY.

  lcl_tabdescr ?= cl_abap_tabledescr=>describe_by_data( ch_data_tab ).
  lcl_strdescr ?= lcl_tabdescr->get_table_line_type( ).

  CREATE DATA l_ref TYPE (lcl_strdescr->absolute_name).
  ASSIGN l_ref->* TO <fs_char>.

*  create dat
*
  filename = im_filename.
  CALL FUNCTION 'WS_UPLOAD'
       EXPORTING
            filename                = filename
            filetype                = 'BIN'
       IMPORTING
            filelength              = ch_filelength
       TABLES
            data_tab                = lt_data
       EXCEPTIONS
            conversion_error        = 1
            file_open_error         = 2
            file_read_error         = 3
            invalid_type            = 4
            no_batch                = 5
            unknown_error           = 6
            invalid_table_width     = 7
            gui_refuse_filetransfer = 8
            customer_error          = 9
            OTHERS                  = 10.

  IF sy-subrc <> 0.
  ENDIF.

  CLEAR l_ofs.
  LOOP AT lt_data INTO l_line.
    l_len = 1024.

    IF l_line(1) = eol+1(1).
      SHIFT l_line.
    ENDIF.

    DO.
      SEARCH l_line FOR eol(1).
      l_fdpos = sy-fdpos.
      IF sy-subrc = 0.

        IF l_ofs < 4096 AND l_fdpos > 0.
          l_ex_line+l_ofs = l_line(l_fdpos).
        ENDIF.

        ADD l_fdpos TO l_ofs.

        SHIFT l_line BY l_fdpos PLACES.
        SHIFT l_line BY 2 PLACES.

        l_len = l_len - l_fdpos - 2.

        CLEAR l_ofs.

        TRANSLATE l_ex_line FROM CODE PAGE '1503'.
        <fs_char> = l_ex_line.
        APPEND <fs_char> TO ch_data_tab.

        CLEAR l_ex_line.
      ELSE.
        l_ex_line+l_ofs = l_line(l_len).
        ADD l_len TO l_ofs.
        CLEAR l_len.
      ENDIF.

      IF l_len <= 0.
        EXIT.
      ENDIF.
    ENDDO.
  ENDLOOP.

  IF l_ofs > 0.
    TRANSLATE l_ex_line FROM CODE PAGE '1503'.
    <fs_char> = l_ex_line.
    APPEND <fs_char> TO ch_data_tab.
  ENDIF.

ENDMETHOD.

_________________
С уважением, Сергей Королев


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot]


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB