Текущее время: Ср, июл 30 2025, 08:40

Часовой пояс: 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 часа


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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