Текущее время: Пн, июл 21 2025, 23:43

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


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


ВНИМАНИЕ!

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



Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Пт, фев 15 2013, 23:02 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, июл 12 2007, 12:18
Сообщения: 430
нужен класс.метод считывания с рабочей станции файла .DBF известной структуры в нужном мне коде.Сейчас это делается в помощью wc-upload в табл. у которой запись- целиком строка файла,потом по символам она раскидывается по переменным и формируется таблица структуры файла .DBF
Таких файлов много,надоело отсчитывать символы.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Сб, фев 16 2013, 12:19 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, окт 06 2005, 16:44
Сообщения: 3080
Откуда: Москва
DBF (как и другие форматы) хорошо читаются через OLE (см.ФМ ALSM_EXCEL_TO_INTERNAL_TABLE)

_________________
С уважением,
Удав.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Сб, фев 16 2013, 15:11 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, июл 12 2007, 12:18
Сообщения: 430
Спасибо большое за совет,в понедельник попробую


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Пн, фев 18 2013, 12:13 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, июл 12 2007, 12:18
Сообщения: 430
Да,считывается нормально,но не работает с разными кодировками.Хорошо бы такой модуль у которого на входе запрашивается кодировка.По разным задачам приходят от клиентов файлы с разными кодировками,
клиенты выгружают свои файлы по программам в которых зашита кодировка,т.е. они не имеют доступа к смене кодировки


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Пн, фев 18 2013, 14:22 
Ассистент
Ассистент

Зарегистрирован:
Чт, май 17 2007, 16:31
Сообщения: 40
Откуда: Санкт-Петербург
Создание, загрузка DBF (писал очень давно, сейчас что-то сделал-бы иначе):

сообщения
Code:
051   Не задана структура БД
052   Недостаточно полей данных (&). Полей & в структуре.
053   Неизвестный тип поля '&'
054   Ошибка выгрузки в &
055   Ошибка создания объекта конвертации в '&'
056   Ошибка конвертации: '&' (&) поз. & в '&'

структура ZDBF_STRUCT 'Структура DBF-файла':
Code:
FLD_NAME   CHAR11   CHAR   11   0   Длина знака 11
FLD_TYPE   CHAR01   CHAR   1   0   Поле текста (1 знак)
FLD_LEN   INT1   INT1   3   0   Значение - байт
FLD_DEC   INT1   INT1   3   0   Значение - байт

TOP-INCUDE:
Code:
TYPE-POOLS: abap, slis.

DATA: nint4 TYPE int4.

FIELD-SYMBOLS: <tab_to> TYPE table.

TYPES: BEGIN OF tlastdata,
          year(1)          TYPE x,         " YY
          month(1)         TYPE x,         " MM
          day(1)           TYPE x,         " DD
       END   OF tlastdata.

DATA: BEGIN OF dbfheader,
          null_byte(1)     TYPE x,         " заголовочный байт
          last_data        TYPE tlastdata, " дата модификации
          count_rec(4)     TYPE x,         " число записей
          len_header(2)    TYPE x,         " полная длина заголовка
          len_record(2)    TYPE x,         " длина записи
          reserv_1(2)      TYPE x,         "
          flag_transact(1) TYPE x,         " флаг задержки транзакции
          reserv_2(13)     TYPE x,         "
          flag_mdx(1)      TYPE x,         " флаг MDX
          reserv_3(3)      TYPE x,         "
      END   OF dbfheader.

DATA: BEGIN OF dbfdescriptor ,
          fld_name(11)     TYPE x,         " имя поля
          fld_type(1)      TYPE x,         " тип поля
          reserv_1(4)      TYPE x,         "
          fld_len(1)       TYPE x,         " длина поля
          fld_dec(1)       TYPE x,         " десятичных разрядов
          reserv_2(13)     TYPE x,         "
          flag_mdx(1)      TYPE x,         " тег MDX
      END   OF dbfdescriptor .

DATA: idbfdescriptor      LIKE STANDARD TABLE OF dbfdescriptor.

* длина записи (включая байт - признак удаления)
DATA: dbfrecordsize       TYPE i.

********************************************************
DATA: it_tfbin(1)    TYPE x OCCURS 0 WITH HEADER LINE.

ZZ_MAKE_DBF
Code:
FUNCTION zz_make_dbf.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*"  IMPORTING
*"     VALUE(FILE) TYPE  STRING
*"     VALUE(IS_DOS) TYPE  FLAG DEFAULT 'X'
*"     VALUE(IS_APPL) TYPE  FLAG DEFAULT SPACE
*"     VALUE(REPLACEMENT) TYPE  ABAP_REPL DEFAULT SPACE
*"  TABLES
*"      DBF_STRUCT STRUCTURE  ZDBF_STRUCT
*"      DBF_DATA
*"  EXCEPTIONS
*"      EMPTY_DBF_STRUCT
*"      SHORT_DBF_DATA
*"      UNKNOWN_FLD_TYPE
*"      ERROR_DOWNLOAD
*"      CONVERTER_ERROR
*"----------------------------------------------------------------------

  PERFORM checkdata       TABLES dbf_struct dbf_data.
  CHECK sy-subrc = 0.

  PERFORM make_descriptor TABLES dbf_struct USING is_dos.
  CHECK sy-subrc = 0.

  PERFORM makeheader      TABLES dbf_struct dbf_data.
  CHECK sy-subrc = 0.

  PERFORM makedata        TABLES dbf_struct dbf_data USING is_dos.
  CHECK sy-subrc = 0.

  PERFORM downloadheader  USING is_appl file.
  CHECK sy-subrc = 0.

  PERFORM downloaddata    USING is_appl file is_dos replacement.
  CHECK sy-subrc = 0.

  PERFORM download_eof    USING is_appl file.
  CHECK sy-subrc = 0.

ENDFUNCTION.

*---------------------------------------------------------------------*
*       FORM CheckData                                                *
*---------------------------------------------------------------------*
FORM checkdata       TABLES dbf_struct STRUCTURE zdbf_struct
                            dbf_data.

  DATA: ndatafield    TYPE i,
        nstructfield  TYPE i.

  FIELD-SYMBOLS: <field_from>.

  IF dbf_struct[] IS INITIAL.
    sy-subrc = 1.
    MESSAGE e051 RAISING empty_dbf_struct.
  ENDIF.

  DO.
    ASSIGN COMPONENT sy-index OF STRUCTURE dbf_data  TO <field_from>.
    IF sy-subrc = 0.
      ndatafield = sy-index.
    ELSE.
      DESCRIBE TABLE dbf_struct LINES nstructfield.
      IF ndatafield < nstructfield.
        sy-subrc = 2.
        MESSAGE e052 WITH ndatafield nstructfield
                     RAISING short_dbf_data.
      ELSE.
        sy-subrc = 0.
      ENDIF.
      EXIT.
    ENDIF.
  ENDDO.

ENDFORM.                    "CheckData

*---------------------------------------------------------------------*
*       FORM Make_Descriptor                                          *
*---------------------------------------------------------------------*
FORM make_descriptor TABLES dbf_struct STRUCTURE zdbf_struct
                     USING  is_dos     TYPE      flag.

* для замены пробелов на x00 в имени поля
  DATA: ctransf(2) TYPE x VALUE '2000'.

  dbfrecordsize = 1.   " 1 байт - флаг удаления записи

  REFRESH idbfdescriptor.

  LOOP AT dbf_struct.

    TRANSLATE dbf_struct-fld_name TO UPPER CASE.
    TRANSLATE dbf_struct-fld_type TO UPPER CASE.

    CASE dbf_struct-fld_type.
      WHEN 'C'.
*       dbf_struct-fld_len =  .
        dbf_struct-fld_dec = 0.
      WHEN 'L'.
        dbf_struct-fld_len = 1.
        dbf_struct-fld_dec = 0.
      WHEN 'N'.
*     when 'M'.
*     when 'F'.
      WHEN 'D'.
        dbf_struct-fld_len = 8.
        dbf_struct-fld_dec = 0.
      WHEN OTHERS.
        sy-subrc = 1.
        MESSAGE e053 WITH dbf_struct-fld_type RAISING unknown_fld_type.
    ENDCASE.

    MODIFY dbf_struct INDEX sy-tabix.

* создание дескриптора
    CLEAR dbfdescriptor.

*   DbfDescriptor-fld_name = dbf_struct-fld_name.
*   TRANSLATE DbfDescriptor-fld_name USING cTransf.
    PERFORM data_2_x     USING    is_dos
                                  dbf_struct-fld_name
                         CHANGING dbfdescriptor-fld_name.

*   DbfDescriptor-fld_type = dbf_struct-fld_type.
    PERFORM data_2_x     USING    is_dos
                                  dbf_struct-fld_type
                         CHANGING dbfdescriptor-fld_type.

    nint4 = dbf_struct-fld_len.
    PERFORM inttohex USING nint4 1 CHANGING dbfdescriptor-fld_len.

    nint4 = dbf_struct-fld_dec.
    PERFORM inttohex USING nint4 1 CHANGING dbfdescriptor-fld_dec.

    APPEND dbfdescriptor TO idbfdescriptor.

* длина записи
    ADD dbf_struct-fld_len TO dbfrecordsize.

  ENDLOOP.

  sy-subrc = 0.

ENDFORM.                    "Make_Descriptor

*---------------------------------------------------------------------*
*       FORM inttohex                                                 *
*---------------------------------------------------------------------*
* записывает данные в заголовок, дескриптор в соглашениях DOS
* например iNum = 4660 (10СС) = '1234' (16СС)
*          if iLen = 1 then cHex = '34'
*          if iLen = 2 then cHex = '3412'
*          if iLen = 4 then cHex = '34120000'
*---------------------------------------------------------------------*
FORM inttohex USING inum    TYPE int4
                    ilen    TYPE int1
           CHANGING chex    TYPE x.

  DATA: nflagint  TYPE i,
        pos_from  TYPE i,
        pos_to    TYPE i,
        nlenhex   TYPE i.

  FIELD-SYMBOLS <fs> TYPE x.

  CLEAR chex.

* для 64 разрядной платформы 4660 (10СС) = '00001234' (16СС)
* для 32 разрядной платформы 4660 (10СС) = '34120000' (16СС)

  nflagint = 4660.
  ASSIGN nflagint TO <fs> CASTING.

  CASE <fs>+0(1).
    WHEN '00'.               " 00001234         " инвертировать
      ASSIGN inum TO <fs> CASTING.
      DESCRIBE FIELD <fs> LENGTH nlenhex IN BYTE MODE.
      DO ilen TIMES.
        pos_from       = nlenhex - sy-index.    " читать от конца
        pos_to         = sy-index - 1.          " писать от начала
        chex+pos_to(1) = <fs>+pos_from(1).
      ENDDO.

    WHEN '34'.               " 34120000         " взять iLen байт
      ASSIGN inum TO <fs> CASTING.
      chex = <fs>+0(ilen).

    WHEN OTHERS.

  ENDCASE.

ENDFORM.                    "inttohex

*---------------------------------------------------------------------*
*       FORM MakeHeader                                               *
*---------------------------------------------------------------------*
FORM makeheader      TABLES dbf_struct STRUCTURE  zdbf_struct
                            dbf_data.

  CLEAR dbfheader.

* заголовочный байт

* 7   - подключение файла DBT
* 6-5 - флаг SQL
* 4   - ???
* 3   - файл DBT
* 2-0 - Номер версии

  dbfheader-null_byte = '03'. " DBASE III

* дата модификации
  nint4 = sy-datum+2(2).     " YY
  PERFORM inttohex USING nint4 1 CHANGING dbfheader-last_data-year.

  nint4 = sy-datum+4(2).     " MM
  PERFORM inttohex USING nint4 1 CHANGING dbfheader-last_data-month.

  nint4 = sy-datum+6(2).     " DD
  PERFORM inttohex USING nint4 1 CHANGING dbfheader-last_data-day  .

* число записей
  DESCRIBE TABLE dbf_data        LINES nint4.
  PERFORM inttohex USING nint4 4 CHANGING dbfheader-count_rec.

* полная длина заголовка (заголовок + дескрипторы + терминальный байт)
  DESCRIBE TABLE idbfdescriptor LINES nint4.
  nint4 = nint4 * 32 + 32 + 1.
  PERFORM inttohex USING nint4 2 CHANGING dbfheader-len_header.

* длина записи (включая байт - признак удаления)
  nint4 = dbfrecordsize.
  PERFORM inttohex USING nint4 2 CHANGING dbfheader-len_record.

  sy-subrc = 0.

ENDFORM.                    "MakeHeader

*---------------------------------------------------------------------*
*       FORM MakeData                                                 *
*---------------------------------------------------------------------*
FORM makedata        TABLES dbf_struct STRUCTURE  zdbf_struct
                            dbf_data
                      USING is_dos   TYPE  flag.

  DATA: lt_fieldcat TYPE lvc_t_fcat         ,
        fcat_line   LIKE LINE OF lt_fieldcat,
        gt_outtab   TYPE REF TO data        ,
        gf_line     TYPE REF TO data        .

  FIELD-SYMBOLS: <line_to>   ,
                 <field_from>,
                 <field_to>  .

  REFRESH lt_fieldcat.

* флаг удаления записи
  CLEAR fcat_line.
  fcat_line-fieldname = 'FLAG_DEL_123456789'. " > 11 знаков
  fcat_line-inttype   = 'C'.
  fcat_line-outputlen = '1'.
  APPEND fcat_line TO lt_fieldcat.

  LOOP AT dbf_struct.

    CLEAR fcat_line.
    fcat_line-fieldname = dbf_struct-fld_name.

    CASE dbf_struct-fld_type.
      WHEN 'C'.
        fcat_line-inttype   = 'C'.
        fcat_line-outputlen = dbf_struct-fld_len.

      WHEN 'L'.
        fcat_line-inttype   = 'C'.
        fcat_line-outputlen = dbf_struct-fld_len.

      WHEN 'N'.
*       fcat_line-inttype   = 'P'.
*       fcat_line-outputlen = dbf_struct-fld_len.
*       fcat_line-decimals  = dbf_struct-fld_dec.
        fcat_line-inttype   = 'C'.
        fcat_line-outputlen = dbf_struct-fld_len.

*     when 'M'.
*     when 'F'.
      WHEN 'D'.
        fcat_line-inttype   = dbf_struct-fld_type.
        fcat_line-outputlen = dbf_struct-fld_len.

      WHEN OTHERS.
    ENDCASE.

    APPEND fcat_line TO lt_fieldcat.

  ENDLOOP.

  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      it_fieldcatalog = lt_fieldcat
    IMPORTING
      ep_table        = gt_outtab.

  ASSIGN gt_outtab->* TO <tab_to>.

  CREATE DATA gf_line LIKE LINE OF <tab_to>.
  ASSIGN gf_line->* TO <line_to>.

  LOOP AT dbf_data.

    LOOP AT dbf_struct.

      nint4 = sy-tabix + 1. " смещение + 1 за счет флага удаления.

      ASSIGN COMPONENT sy-tabix OF STRUCTURE dbf_data  TO <field_from>.
      ASSIGN COMPONENT nint4    OF STRUCTURE <line_to> TO <field_to>  .

      CASE dbf_struct-fld_type.
        WHEN 'C'.
          <field_to> = <field_from>.
        WHEN 'L'.
          IF <field_from> CA 'TtYyXx'.
            <field_to> = 'T'.
          ELSE.
            <field_to> = 'F'.
          ENDIF.
        WHEN 'N'.
          WRITE <field_from> TO <field_to> LEFT-JUSTIFIED NO-GROUPING
                                           DECIMALS dbf_struct-fld_dec.
          REPLACE ',' WITH '.' INTO <field_to>.

          SEARCH <field_to> FOR '-'.
          IF sy-subrc = 0.
            <field_to>+sy-fdpos(1) = ''.
            SHIFT <field_to> BY 1 PLACES RIGHT.
            <field_to>+0(1) = '-'.
          ENDIF.
          SHIFT <field_to> RIGHT DELETING TRAILING space.
*       when 'M'.
*       when 'F'.
        WHEN 'D'.
          <field_to> = <field_from>.
        WHEN OTHERS.
      ENDCASE.

    ENDLOOP.

    APPEND <line_to> TO <tab_to>.

  ENDLOOP.

  sy-subrc = 0.

ENDFORM.                    "MakeData

*---------------------------------------------------------------------*
*       FORM add_dbf                                                  *
*---------------------------------------------------------------------*
FORM add_dbf USING    ctext   TYPE x
             CHANGING xbuffer TYPE x
                      xsize   TYPE i.

  DATA: nlen TYPE i.

  xbuffer+xsize = ctext.

  DESCRIBE FIELD ctext LENGTH nlen IN BYTE MODE.
  ADD nlen TO xsize.

ENDFORM.                    "add_dbf

*---------------------------------------------------------------------*
*       FORM DownloadHeader                                           *
*---------------------------------------------------------------------*
FORM downloadheader  USING is_appl  TYPE flag
                           filename TYPE string.

  DATA: x0d(1)    TYPE x VALUE '0D'.

  DATA: xstring   TYPE xstring.
  DATA: hex_tab   LIKE STANDARD TABLE OF tbl1024.
  DATA: bytes     TYPE i.

  DATA: xbuffer(32768) TYPE x.
  DATA: xsize          TYPE i.

  FIELD-SYMBOLS <fs> TYPE x.

* заголовок
  ASSIGN dbfheader TO <fs> CASTING.
  PERFORM add_dbf USING <fs> CHANGING xbuffer xsize.

* дескрипторы
  LOOP AT idbfdescriptor INTO dbfdescriptor.
    ASSIGN dbfdescriptor TO <fs> CASTING.
    PERFORM add_dbf USING <fs> CHANGING xbuffer xsize.
  ENDLOOP.

* терминальный байт
  PERFORM add_dbf USING x0d CHANGING xbuffer xsize.

* отрезать хвост от буффера
  xstring = xbuffer+0(xsize).

* в таблицу для выгрузки
  PERFORM buffer_2_hex_tab TABLES   hex_tab
                           CHANGING xstring
                                    bytes.

  IF is_appl IS INITIAL.
    PERFORM download_presentation TABLES   hex_tab
                                  USING    filename
                                           space
                                           bytes.
  ELSE.
    PERFORM download_application  TABLES   hex_tab
                                  USING    filename
                                           space
                                           bytes.
  ENDIF.

ENDFORM.                    "DownloadHeader

*---------------------------------------------------------------------*
*       FORM DownloadData                                             *
*---------------------------------------------------------------------*
FORM downloaddata     USING is_appl     TYPE flag
                            filename    TYPE string
                            is_dos      TYPE flag
                            replacement TYPE abap_repl.

* объект для конвертации
  DATA: convout        TYPE REF TO cl_abap_conv_out_ce.
  DATA: encoded_string TYPE xstring.

* таблица в 16CC для выгрузки
  DATA: hex_tab        LIKE STANDARD TABLE OF tbl1024.
  DATA: bytes          TYPE i.

* получить объект для конвертации
  PERFORM make_converter USING    is_dos
                                  replacement
                         CHANGING convout.

  FIELD-SYMBOLS: <fs_line>  TYPE ANY,
                 <fs_field> TYPE c.

* строку разворачиваем вертикально, по одному байту,
* преобразуя к 16CC (для выгрузки в BIN)
  DATA: it_tab(1)     TYPE x OCCURS 0 WITH HEADER LINE.

*  LOOP AT <tab_to> ASSIGNING <fs_line>.
*    DO.
*      ASSIGN COMPONENT sy-index OF STRUCTURE <fs_line> TO <fs_field>
*                       TYPE 'C'.
*      IF sy-subrc = 0.
*        PERFORM convert       USING    is_dos
*                                       replacement
*                                       <fs_field>
*                              CHANGING convout.
*      ELSE.
*        EXIT.
*      ENDIF.
*    ENDDO.
*  ENDLOOP.

* для ускорения будем перекодировать сразу всю строку
  LOOP AT <tab_to> ASSIGNING <fs_line>.
    ASSIGN  <fs_line> TO <fs_field> CASTING.
    PERFORM convert       USING    is_dos
                                   replacement
                                   <fs_field>
                          CHANGING convout.
  ENDLOOP.

* получить перекодированную строку
  CALL METHOD convout->get_buffer
    RECEIVING
      buffer = encoded_string.

* переложить в таблицу по 1K
  PERFORM buffer_2_hex_tab TABLES   hex_tab
                           CHANGING encoded_string
                                    bytes.

  IF is_appl IS INITIAL.

    PERFORM download_presentation TABLES   hex_tab
                                  USING    filename
                                           'X'
                                           bytes.
  ELSE.
    PERFORM download_application  TABLES   hex_tab
                                  USING    filename
                                           'X'
                                           bytes.
  ENDIF.

ENDFORM.                    "DownloadData

*---------------------------------------------------------------------*
*       FORM Download_EOF                                             *
*---------------------------------------------------------------------*
FORM download_eof     USING is_appl  TYPE flag
                            filename TYPE string.

  DATA: x1a(1) TYPE x VALUE '1A'.

  DATA: hex_tab        LIKE STANDARD TABLE OF tbl1024.
  DATA: bytes          TYPE i.
  DATA: hex_record     LIKE LINE OF hex_tab.

  hex_record-line = x1a.
  APPEND hex_record TO hex_tab.
  bytes = XSTRLEN( x1a ).

  IF is_appl IS INITIAL.
    PERFORM download_presentation TABLES   hex_tab
                                  USING    filename
                                           'X'
                                           bytes.
  ELSE.
    PERFORM download_application  TABLES   hex_tab
                                  USING    filename
                                           'X'
                                           bytes.
  ENDIF.

ENDFORM.                    "Download_EOF

*&---------------------------------------------------------------------*
*&      form  data_2_x
*&---------------------------------------------------------------------*
FORM data_2_x     USING    is_dos   TYPE flag
                           data_chr TYPE c
                  CHANGING data_x   TYPE x.

* объект для конвертации
  DATA: convout          TYPE REF TO cl_abap_conv_out_ce.
  DATA: encoded_string   TYPE xstring.
  DATA: len              TYPE i.

  CLEAR data_x.

* получить объект для конвертации
  PERFORM make_converter USING    is_dos
                                  space
                         CHANGING convout.

  PERFORM convert        USING    is_dos
                                  space
                                  data_chr
                         CHANGING convout.

  CALL METHOD convout->get_buffer
    RECEIVING
      buffer = encoded_string.

  len = STRLEN( data_chr ).

  data_x+0(len) = encoded_string+0(len).

ENDFORM.                                                    "data_2_x

*&---------------------------------------------------------------------*
*&      Form  make_converter
*&---------------------------------------------------------------------*
FORM make_converter USING    is_dos      TYPE flag
                             replacement TYPE abap_repl
                    CHANGING convout    TYPE REF TO cl_abap_conv_out_ce.

  DATA:
    encoding    TYPE abap_encoding,
    ignore_cerr TYPE abap_bool.
  DATA:
*   text        type string,
    oref        TYPE REF TO cx_root.

  IF is_dos = 'X'.
    encoding = '1503'.
  ELSE.
    encoding = '1504'.
  ENDIF.

  IF replacement IS INITIAL.
    ignore_cerr = abap_false.
  ELSE.
    ignore_cerr = abap_true .
  ENDIF.

  TRY.
      CALL METHOD cl_abap_conv_out_ce=>create
        EXPORTING
          encoding    = encoding
*         endian      =
          replacement = replacement
          ignore_cerr = ignore_cerr
        RECEIVING
          conv        = convout.
*   CATCH cx_parameter_invalid_range .
*   CATCH cx_sy_codepage_converter_init .
    CATCH cx_root INTO oref.
*     text = oref->get_text( ).
*     Ошибка создания объекта конвертации в '&'
      MESSAGE e055 WITH encoding RAISING converter_error.
  ENDTRY.

ENDFORM.                    "make_converter

*&---------------------------------------------------------------------*
*&      Form  convert
*&---------------------------------------------------------------------*
FORM convert       USING    is_dos      TYPE flag
                            replacement TYPE abap_repl
                            data        TYPE any
                   CHANGING convout     TYPE REF TO cl_abap_conv_out_ce.

  DATA:
*   text        TYPE string,
    oref        TYPE REF TO cx_root.

  TRY.
      CALL METHOD convout->write
        EXPORTING
*         n    = text_len
          data = data.
*   CATCH cx_sy_codepage_converter_init .
*   CATCH cx_sy_conversion_codepage .
*   CATCH cx_parameter_invalid_type .
*   CATCH cx_parameter_invalid_range .
    CATCH cx_root INTO oref.

      PERFORM convert_error     USING    is_dos
                                         replacement
                                         data.

  ENDTRY.

ENDFORM.                    "convert

*&---------------------------------------------------------------------*
*&      Form  convert_error
*&---------------------------------------------------------------------*
FORM convert_error     USING    is_dos      TYPE flag
                                replacement TYPE abap_repl
                                data        TYPE any.

  DATA:
    convout     TYPE REF TO cl_abap_conv_out_ce.

  DATA:
    text        TYPE string,
    oref        TYPE REF TO cx_root.

  DATA:
    n_pos       TYPE sy-fdpos,
    char01      TYPE char01,
    subrc       TYPE sy-subrc.

  PERFORM make_converter USING    is_dos
                                  replacement
                         CHANGING convout.

* посимвольным перебором найти ошибочный знак
  DO.
    n_pos = sy-index - 1.
    PERFORM get_char01 USING    data    " очередной символ
                                n_pos
                       CHANGING char01
                                subrc.
    IF subrc = 0.
      TRY.
          CALL METHOD convout->write
            EXPORTING
*             n    = text_len
              data = char01.
        CATCH cx_root INTO oref.
          PERFORM char_2_view_x USING    char01  " ошибочный знак
                                CHANGING text.              " в 16CC
          n_pos = n_pos + 1.
          EXIT.
      ENDTRY.
    ELSE.
      EXIT.
    ENDIF.
  ENDDO.

* Ошибка конвертации: '&' (&) поз. & в '&'
  MESSAGE e056 WITH char01 text n_pos data RAISING converter_error.

ENDFORM.                    "convert_error

*&---------------------------------------------------------------------*
*&      Form  get_chr
*&---------------------------------------------------------------------*
FORM get_char01 USING    data   TYPE any
                         pos    TYPE sy-fdpos
                CHANGING char01 TYPE char01
                         subrc  TYPE sy-subrc.

  CLEAR: char01, subrc.

  CATCH SYSTEM-EXCEPTIONS data_access_errors = 1.
    char01 = data+pos(1).
  ENDCATCH.
  subrc = sy-subrc.

ENDFORM.                                                    "get_char01

*&---------------------------------------------------------------------*
*&      Form  char_2_view_x
*&---------------------------------------------------------------------*
*  данные в виде символьной строки в 16CC (для внешнего предствления)
*&---------------------------------------------------------------------*
FORM char_2_view_x USING    data   TYPE any
                   CHANGING view_x TYPE string.

  DATA: len_byte TYPE sy-fdpos,
        pos      TYPE sy-fdpos,
        chr(2)   TYPE c.

  FIELD-SYMBOLS <fs> TYPE x.

  CLEAR: view_x.

  ASSIGN data TO <fs> CASTING.

  DESCRIBE FIELD <fs> LENGTH len_byte IN BYTE MODE.
  DO len_byte TIMES.
    pos = sy-index - 1.
    chr = <fs>+pos(1).
    CONCATENATE view_x chr INTO view_x.
  ENDDO.

ENDFORM.                    "char_2_view_x

*&---------------------------------------------------------------------*
*&      Form  buffer_2_hex_tab
*&---------------------------------------------------------------------*
FORM buffer_2_hex_tab TABLES   hex_tab        STRUCTURE tbl1024
                      CHANGING encoded_string TYPE xstring
                               bytes          TYPE i.

  DATA: hex_record       LIKE LINE OF hex_tab.
  DATA: bytes_len_rest   TYPE i.
  DATA: bytes_len_record TYPE i.

  REFRESH hex_tab.

*  попробуем поэкономить память за счет уменьшения encoded_string
*  при перекладке в hex_tab

*  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
*    EXPORTING
*      buffer                = buffer
*      append_to_table       = 'X'
**   importing
**     output_length         =
*    TABLES
*      binary_tab            = hex_tab.

  bytes           = XSTRLEN( encoded_string ).
  bytes_len_rest  = XSTRLEN( encoded_string ).

  DESCRIBE FIELD hex_record LENGTH bytes_len_record IN BYTE MODE.

  WHILE bytes_len_rest > bytes_len_record.
    MOVE encoded_string(bytes_len_record) TO hex_record-line.
    APPEND hex_record TO hex_tab.
    encoded_string = encoded_string+bytes_len_record.
    bytes_len_rest = XSTRLEN( encoded_string ).
  ENDWHILE.

  IF bytes_len_rest > 0.
    MOVE encoded_string TO hex_record-line.
    APPEND hex_record TO hex_tab.
  ENDIF.

ENDFORM.                    "buffer_2_hex_tab

*&---------------------------------------------------------------------*
*&      Form  download_presentation
*&---------------------------------------------------------------------*
*       выгружаем на  presantation
*&---------------------------------------------------------------------*
FORM download_presentation TABLES   hex_tab  STRUCTURE tbl1024
                           USING    filename TYPE string
                                    append   TYPE char01
                                    bytes    TYPE i.

* выгружаем в двоичном виде
  CALL FUNCTION 'GUI_DOWNLOAD'
    EXPORTING
      bin_filesize = bytes
      filename     = filename
      filetype     = 'BIN'
      append       = append
    TABLES
      data_tab     = hex_tab
    EXCEPTIONS
      OTHERS       = 22.

  IF sy-subrc <> 0.
    MESSAGE e054 WITH filename RAISING error_download.
  ENDIF.

ENDFORM.                    "download_presentation

*&---------------------------------------------------------------------*
*&      Form  download_application
*&---------------------------------------------------------------------*
*       выгружаем на  application
*&---------------------------------------------------------------------*
FORM download_application  TABLES   hex_tab  STRUCTURE tbl1024
                           USING    filename TYPE string
                                    append   TYPE char01
                                    bytes    TYPE i.

  DATA: bytes_len_rest   TYPE i.
  DATA: bytes_len_record TYPE i.

  FIELD-SYMBOLS: <fs> LIKE LINE OF hex_tab.

  DESCRIBE FIELD <fs> LENGTH bytes_len_record IN BYTE MODE.

* выгружаем в двоичном виде
  IF append IS INITIAL.
    OPEN DATASET filename FOR OUTPUT    IN BINARY MODE.
  ELSE.
    OPEN DATASET filename FOR APPENDING IN BINARY MODE.
  ENDIF.
  IF sy-subrc <> 0.
    MESSAGE e054 WITH filename RAISING error_download.
  ENDIF.

  LOOP AT hex_tab ASSIGNING <fs>.

    IF bytes > bytes_len_record.
      bytes_len_rest = bytes_len_record.
    ELSE.
      bytes_len_rest = bytes.
    ENDIF.

    TRANSFER <fs> TO filename LENGTH bytes_len_rest.
    bytes = bytes - bytes_len_rest.

  ENDLOOP.

  CLOSE DATASET filename .

ENDFORM.                    "download_application

ZZ_LOAD_DBF
Code:
FUNCTION zz_load_dbf.
*"----------------------------------------------------------------------
*"*"Локальный интерфейс:
*"  IMPORTING
*"     VALUE(I_FILE) TYPE  STRING OPTIONAL
*"     REFERENCE(I_DOS_FLAG) TYPE  FLAG DEFAULT 'X'
*"  TABLES
*"      DBF_STRUCT STRUCTURE  ZDBF_STRUCT OPTIONAL
*"  CHANGING
*"     REFERENCE(IT_FIELDCAT) TYPE  LVC_T_FCAT OPTIONAL
*"     REFERENCE(IT_DBF_DATA) TYPE REF TO  DATA OPTIONAL
*"  EXCEPTIONS
*"      UNKNOWN_FLD_TYPE
*"----------------------------------------------------------------------

  DATA:
    descr_count       TYPE i,
    mimetype(30)      TYPE c,
    pos               TYPE sy-index.

  DATA: header        LIKE dbfheader.

  DATA: count_rec     TYPE i,
        len_header    TYPE i,
        len_record    TYPE i.

  DATA: descriptor_x  LIKE dbfdescriptor.

  DATA: wa_fieldcat   LIKE LINE OF it_fieldcat,
*       gt_outtab     TYPE REF TO data,
        gf_line       TYPE REF TO data.

  FIELD-SYMBOLS: <tab> TYPE table,
                 <line>,
                 <field>.

  DATA: text_buffer        TYPE string,
        flag_del           TYPE flag.

  REFRESH: it_fieldcat, dbf_struct.

  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename                = i_file
      filetype                = 'BIN'
    TABLES
      data_tab                = it_tfbin
    EXCEPTIONS
      file_open_error         = 1
      file_read_error         = 2
      no_batch                = 3
      gui_refuse_filetransfer = 4
      invalid_type            = 5
      no_authority            = 6
      unknown_error           = 7
      bad_data_format         = 8
      header_not_allowed      = 9
      separator_not_allowed   = 10
      header_too_long         = 11
      unknown_dp_error        = 12
      access_denied           = 13
      dp_out_of_memory        = 14
      disk_full               = 15
      dp_timeout              = 16
      OTHERS                  = 17.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  CASE i_dos_flag.
    WHEN 'X'.
      mimetype = 'charset=cp866'.
    WHEN space.
      mimetype = 'charset=windows-1251'.
  ENDCASE.


  PERFORM get_header CHANGING header.

  PERFORM get_4int USING header-count_rec  CHANGING count_rec .
  PERFORM get_2int USING header-len_header CHANGING len_header.
  PERFORM get_2int USING header-len_record CHANGING len_record.

  descr_count = ( len_header - 1 - 32 ) / 32.

  DO descr_count TIMES.
    PERFORM get_descriptor USING    sy-index
                           CHANGING descriptor_x.

    PERFORM get_data       USING    descriptor_x-fld_name
                                    1
                                    10
                                    abap_true
                                    mimetype
                           CHANGING dbf_struct-fld_name.

    PERFORM get_data       USING    descriptor_x-fld_type
                                    1
                                    1
                                    abap_true
                                    mimetype
                           CHANGING dbf_struct-fld_type.

    dbf_struct-fld_len  = descriptor_x-fld_len.
    dbf_struct-fld_dec  = descriptor_x-fld_dec.
    APPEND dbf_struct.
  ENDDO.

* Построение каталога полей для выходной таблицы
  LOOP AT dbf_struct.

    CLEAR wa_fieldcat.

    wa_fieldcat-fieldname = dbf_struct-fld_name.

    CASE dbf_struct-fld_type.
      WHEN 'C'.
        wa_fieldcat-inttype   = 'C'.
        wa_fieldcat-outputlen = dbf_struct-fld_len.
        wa_fieldcat-intlen    = dbf_struct-fld_len.
      WHEN 'L'.
        wa_fieldcat-inttype   = 'C'.
        wa_fieldcat-outputlen = '1'.
        wa_fieldcat-intlen    = '1'.
      WHEN 'N'.
        wa_fieldcat-inttype   = 'P'.
        wa_fieldcat-decimals  = dbf_struct-fld_dec.

* Ограничение длины поля типа P
        IF dbf_struct-fld_len > 16.
          wa_fieldcat-outputlen = 16.
          wa_fieldcat-intlen    = 16.
        ELSE.
          wa_fieldcat-outputlen = dbf_struct-fld_len.
          wa_fieldcat-intlen    = dbf_struct-fld_len.
        ENDIF.

*     when 'M'.
*     when 'F'.

      WHEN 'D'.
        wa_fieldcat-inttype   = dbf_struct-fld_type.
        wa_fieldcat-outputlen = 8.
      WHEN OTHERS.
        sy-subrc = 1.
        MESSAGE e053 WITH dbf_struct-fld_type
                     RAISING unknown_fld_type.
    ENDCASE.

    APPEND wa_fieldcat TO it_fieldcat.

  ENDLOOP.

* создать динамическую таблицу
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
*      i_style_table             =
      it_fieldcatalog           = it_fieldcat
      i_length_in_byte          = abap_true
    IMPORTING
      ep_table                  = it_dbf_data. " gt_outtab.
*      e_style_fname             =
*    EXCEPTIONS
*      generate_subpool_dir_full = 1
*      others                    = 2
  .
  IF sy-subrc <> 0.
*   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

*  ASSIGN gt_outtab->* TO <tab>.
  ASSIGN it_dbf_data->* TO <tab>.
  CREATE DATA gf_line LIKE LINE OF <tab>.
  ASSIGN gf_line->* TO <line>.

  DO count_rec TIMES.

    PERFORM get_record USING    len_header
                                len_record
                                sy-index
                                mimetype
                       CHANGING text_buffer.

* Проверка флага удаления записи обязательно через присвоение
* символьной переменной, иначе не работает IF
    flag_del = text_buffer+0(1).

    IF flag_del IS INITIAL.

      pos = 1.

      LOOP AT dbf_struct.

        ASSIGN COMPONENT dbf_struct-fld_name
                         OF STRUCTURE <line>      TO <field>.

        CATCH SYSTEM-EXCEPTIONS conversion_errors = 1.
          <field> = text_buffer+pos(dbf_struct-fld_len).
        ENDCATCH.

        pos = pos + dbf_struct-fld_len.
      ENDLOOP.

      APPEND <line> TO <tab>.
    ENDIF.

  ENDDO.

ENDFUNCTION.


*&---------------------------------------------------------------------*
*&      Form  get_header
*&---------------------------------------------------------------------*
FORM get_header     CHANGING header     LIKE dbfheader.

  DATA: wa_32(32) TYPE x,
        pos       TYPE sy-index.

  FIELD-SYMBOLS: <fs_in>     TYPE x,
                 <fs_out>    TYPE x,
                 <fs_header> TYPE ANY.

  DO 32 TIMES.
*   from
    READ TABLE it_tfbin INDEX sy-index ASSIGNING <fs_in>.
* to
    pos = sy-index - 1.
    ASSIGN wa_32+pos(1) TO <fs_out>.
    <fs_out> = <fs_in>.
  ENDDO.

  ASSIGN wa_32 TO <fs_header> CASTING LIKE dbfheader.
  header = <fs_header>.

ENDFORM.                    "get_header

*&---------------------------------------------------------------------*
*&      Form  get_descriptor
*&---------------------------------------------------------------------*
FORM get_descriptor USING    num          TYPE sy-index
                    CHANGING descriptor_x LIKE dbfdescriptor.

  DATA: wa_32(32) TYPE x,
        pos       TYPE sy-index,
        pos_start TYPE sy-index.

  FIELD-SYMBOLS: <fs_in>            TYPE x,
                 <fs_out>           TYPE x,
                 <fs_dbfdescriptor> TYPE ANY.

  pos_start = num * 32.

  DO 32 TIMES.
*   from
    pos = pos_start + sy-index.
    READ TABLE it_tfbin INDEX pos ASSIGNING <fs_in>.
* to
    pos = sy-index - 1.
    ASSIGN wa_32+pos(1) TO <fs_out>.
    <fs_out> = <fs_in>.
  ENDDO.

  ASSIGN wa_32 TO <fs_dbfdescriptor> CASTING LIKE dbfdescriptor.
  descriptor_x = <fs_dbfdescriptor>.

ENDFORM.                    "get_descriptor

*&---------------------------------------------------------------------*
*&      Form  get_data
*&---------------------------------------------------------------------*
FORM get_data USING    var_x      TYPE x
                       start      TYPE i
                       count      TYPE i
                       if_exit    TYPE flag
                       i_mimetype TYPE c
              CHANGING var_c      TYPE c.

  DATA: text_buffer      TYPE string.

  DATA: binary_tab(1)    TYPE x OCCURS 0 WITH HEADER LINE.

  PERFORM get_binary_tab TABLES binary_tab
                         USING  var_x
                                start
                                count
                                if_exit.

  CALL FUNCTION 'SCMS_BINARY_TO_STRING'
    EXPORTING
      input_length = count
      mimetype     = i_mimetype
    IMPORTING
      text_buffer  = text_buffer
    TABLES
      binary_tab   = binary_tab
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.
  IF sy-subrc = 0.
    var_c = text_buffer.
  ELSE.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    "get_data


*&---------------------------------------------------------------------*
*&      Form  get_record
*&---------------------------------------------------------------------*
FORM get_record USING    i_headerlen   TYPE i
                         i_recordlen   TYPE i
                         i_rec_num     TYPE i
                         i_mimetype    TYPE c
                CHANGING i_text_buffer TYPE string.

  FIELD-SYMBOLS: <x_record> TYPE x.

  DATA: start_pos  TYPE i,
        end_pos    TYPE i,
        it_xrecord TYPE STANDARD TABLE OF x.

  start_pos = i_headerlen + ( i_rec_num - 1 ) * i_recordlen + 1.
  end_pos   = start_pos + i_recordlen - 1.

  LOOP AT it_tfbin ASSIGNING <x_record> FROM start_pos TO end_pos.
    APPEND <x_record> TO it_xrecord.
  ENDLOOP.

  CALL FUNCTION 'SCMS_BINARY_TO_STRING'
    EXPORTING
      input_length = i_recordlen
      mimetype     = i_mimetype
    IMPORTING
      text_buffer  = i_text_buffer
    TABLES
      binary_tab   = it_xrecord
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.
  IF sy-subrc = 0.
  ELSE.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    "get_records
*&---------------------------------------------------------------------*
*&      Form  get_binary_tab
*&---------------------------------------------------------------------*
FORM get_binary_tab TABLES binary_tab
                    USING  var_x      TYPE x
                           start      TYPE i
                           count      TYPE i
                           if_exit    TYPE flag.
  DATA: pos  TYPE i,
        byte TYPE x.

  REFRESH: binary_tab.
  DO count TIMES.
    pos  = start - 1 + sy-index - 1.
    byte = var_x+pos(1).
    IF byte IS INITIAL AND if_exit = abap_true.
      EXIT.
    ELSE.
      APPEND byte TO binary_tab.
    ENDIF.
  ENDDO.

ENDFORM.                    "get_binary_tab
*---------------------------------------------------------------------*
*       FORM GET_4INT                                                 *
*---------------------------------------------------------------------*
FORM get_4int USING    var_x TYPE x
              CHANGING res   TYPE i.
  DATA: s(4) TYPE x.
  MOVE var_x(1)   TO s+3(1).
  MOVE var_x+1(1) TO s+2(1).
  MOVE var_x+2(1) TO s+1(1).
  MOVE var_x+3(1) TO s(1).
  res = s.
ENDFORM.                                                    "GET_4INT

*---------------------------------------------------------------------*
*       FORM GET_2INT                                                 *
*---------------------------------------------------------------------*
FORM get_2int USING    var_x TYPE x
              CHANGING res   TYPE i.
  DATA: s(2) TYPE x.
  MOVE var_x(1)   TO s+1(1).
  MOVE var_x+1(1) TO s(1).
  res = s.
ENDFORM.                                                    "GET_2INT


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: нужен класс.метод считывания с рабочей станции файла .DBF
СообщениеДобавлено: Пн, фев 18 2013, 14:50 
Старший специалист
Старший специалист

Зарегистрирован:
Чт, июл 12 2007, 12:18
Сообщения: 430
Спасибо большое,попробую


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

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


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

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


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

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