Текущее время: Вс, июл 20 2025, 09:38

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


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


ВНИМАНИЕ!

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



Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Выгрузка в ДБФ - создать поле N 10.2
СообщениеДобавлено: Вт, май 15 2007, 08:48 
Ассистент
Ассистент

Зарегистрирован:
Ср, июн 21 2006, 10:20
Сообщения: 38
Мне нужно создать ДБФ с полем типа N длина 10 десятичных 2 знака.
На входе CURR 15.2 (тип ABAP Packed 8 (байт?) 2 десятичных ) .
ФМ GUI_DOWNLOAD преобразует по умолчанию это в ДБФ С 21.
Пробовали в програме менять тип на Р и N -
получили в ДБФ N 9.2 или N 11.2 или N 10.0 .

НУЖНО N 10.2 !!


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт, май 15 2007, 09:13 
Специалист
Специалист

Зарегистрирован:
Чт, июн 23 2005, 18:05
Сообщения: 119
Попробуйте воспользоватся этой подпрограммой:
Code:
*Программа формирования DBF файла.

DATA:
      prc_filetype TYPE char10 VALUE 'DBF',
      prc_codepage TYPE abap_encoding VALUE '1503',
      ignore_cerr TYPE abap_bool VALUE abap_true,
      replacement TYPE abap_repl VALUE '#',
      prc_filename(1024) TYPE c,
      prc_bytes_transfered TYPE i VALUE 0.


  PERFORM app_dbf_download TABLES gt_doc_head
                                  fieldnames
                           USING  prc_filename
                                  prc_filetype
                                  prc_codepage
                                  ignore_cerr
                                  replacement
                           CHANGING prc_bytes_transfered.


FORM app_dbf_download  TABLES   par_data_tab
                                par_field_names
                       USING    par_filename          TYPE c
                                par_filetype          TYPE c
                                par_encoding          TYPE abap_encoding
                                par_ignore_cerr       TYPE abap_bool
                                par_replacement_char  TYPE abap_repl
                       CHANGING par_bytes_transfered  TYPE i.

  DATA: prc_lines_count   TYPE i,
        prc_all_columns_count TYPE i,
        prc_columns_count TYPE i,
        prc_column_idx    TYPE i,
        prc_data_type     TYPE c,
        prc_output_length TYPE i,
        prc_dpts_length   TYPE i,
        prc_column_name(256)  TYPE c,
        prc_column_name_str   TYPE string,
        prc_column_value(256) TYPE c,
        prc_column_value_str  TYPE string,
        prc_dbf_data_type TYPE c,
        prc_table_type TYPE c,
        prc_output_string TYPE xstring.

  FIELD-SYMBOLS: <f>    TYPE ANY,
                 <name> TYPE c.
*Определение параметров
  DESCRIBE TABLE par_data_tab LINES prc_lines_count.
  DESCRIBE FIELD par_data_tab TYPE  prc_table_type
  COMPONENTS prc_all_columns_count.
*Конвертирование параметров в ABAP number
  DATA: prc_conv    TYPE REF TO cl_abap_conv_out_ce,
        prc_xstr_no TYPE xstring,
        prc_i_no    TYPE i,
        prc_sapno   TYPE cpcharno,
        prc_space   TYPE string.
  TRY.
      CALL METHOD cl_abap_conv_out_ce=>create
        EXPORTING
          encoding = '4000'
        RECEIVING
          conv     = prc_conv.
    CATCH cx_parameter_invalid_range .
      MESSAGE ID 'FES' TYPE 'E' NUMBER '023' RAISING unknown_error.
    CATCH cx_sy_codepage_converter_init .
      MESSAGE ID 'FES' TYPE 'E' NUMBER '024' RAISING unknown_error.
  ENDTRY.
  TRY.
      CALL METHOD prc_conv->write
        EXPORTING
          data = par_replacement_char.
    CATCH cx_sy_codepage_converter_init.
      MESSAGE ID 'FES' TYPE 'E' NUMBER '024' RAISING unknown_error.
    CATCH cx_sy_conversion_codepage.
      MESSAGE ID 'FES' TYPE 'E' NUMBER '026' RAISING unknown_error.
    CATCH cx_parameter_invalid_type.
      MESSAGE ID 'FES' TYPE 'E' NUMBER '023' RAISING unknown_error.
    CATCH cx_parameter_invalid_range.
      MESSAGE ID 'FES' TYPE 'E' NUMBER '023' RAISING unknown_error.
  ENDTRY.
  TRY.
    CALL METHOD prc_conv->get_buffer
      RECEIVING
        buffer = prc_xstr_no.
  ENDTRY.
  prc_i_no  = prc_xstr_no.
  prc_sapno = prc_i_no.
*Конвертирование кодовой страницы
  DATA: converter       TYPE REF TO cl_abap_conv_obj,
        prc_codepage(4) TYPE n,
        prc_miss        TYPE c,
        prc_broken      TYPE c.

  IF par_ignore_cerr = abap_true.
    prc_miss   = 'S'.
    prc_broken = 'M'.
  ELSE.
    prc_miss   = '.'.
    prc_broken = '.'.
  ENDIF.
  prc_codepage = par_encoding.
  CREATE OBJECT converter
    EXPORTING
      outcode  = prc_codepage
      miss     = prc_miss
      broken   = prc_broken
      use_f1   = 'X'
      substc   = prc_sapno
    EXCEPTIONS
      invalid_codepage = 1
      internal_error   = 2.
  IF sy-subrc <> 0.
    CASE sy-subrc.
      WHEN 1.
        MESSAGE ID 'FES' TYPE 'E' NUMBER '023' RAISING unknown_error.
      WHEN 2.
        MESSAGE ID 'FES' TYPE 'E' NUMBER '024' RAISING unknown_error.
    ENDCASE.
  ENDIF.

*Запись заголовка в О байт.
** BYTES: [0] : Version
  DATA: prc_version_number    TYPE x VALUE 3.
  CONCATENATE prc_output_string prc_version_number
    INTO prc_output_string
    IN BYTE MODE.
  DATA: prc_day        TYPE x,
        prc_month      TYPE x,
        prc_year(2)    TYPE x,
        prc_year_short TYPE x.

*Запись даты последнего изменения в 1-3 байты.
** BYTES: [1] - [3]: Date of last change
  MOVE sy-datum(4) TO prc_year.
  prc_year_short = prc_year - 1900.
  MOVE sy-datum+4(2) TO prc_month.
  MOVE sy-datum+6(2) TO prc_day.
  CONCATENATE prc_output_string prc_year_short prc_month prc_day
    INTO prc_output_string
    IN BYTE MODE.

*Цикл по столбцам таблицы с приведением типов
  DATA: prc_enc_column_name   TYPE xstring,
        prc_enc_dbf_data_type TYPE xstring,
        prc_enc_column_data   TYPE xstring,
        prc_enc_column_value  TYPE xstring,
        prc_enc_all_columns   TYPE xstring,
      prc_rec_len           TYPE i VALUE 1. " Add 1 for additional SPACE

  prc_column_idx = 1.
  prc_columns_count = prc_all_columns_count.
  WHILE prc_column_idx <= prc_all_columns_count.
    ASSIGN COMPONENT prc_column_idx OF STRUCTURE par_data_tab TO <f>.
    DESCRIBE FIELD <f> TYPE          prc_data_type
                       OUTPUT-LENGTH prc_output_length.

    READ TABLE par_field_names INDEX prc_column_idx.

    IF sy-subrc = 0.
      ASSIGN COMPONENT 1 OF STRUCTURE par_field_names TO <name>.
      IF sy-subrc = 0.
        prc_column_name = <name>.
      ENDIF.
    ELSE.
      prc_column_name = 'F'.
      WRITE prc_column_idx TO prc_column_name+1.
    ENDIF.
    CONDENSE prc_column_name NO-GAPS.

    prc_dpts_length = 0.
    prc_dbf_data_type = prc_data_type.

    IF prc_data_type = 'C' OR prc_data_type = 'D'.
      DESCRIBE FIELD <f> LENGTH prc_output_length IN CHARACTER MODE.
    ENDIF.

    CASE prc_data_type.
      WHEN 'C'.
      WHEN 'X'.
        prc_dbf_data_type = 'C'.
        prc_output_length = prc_output_length + 1.  " leading 'x'
      WHEN 'P' OR 'N'.
        IF prc_output_length < 20.
          prc_dbf_data_type = 'N'.
          DESCRIBE FIELD <f> DECIMALS prc_dpts_length.
        ELSE.                      "// Typ C
          prc_dbf_data_type = 'C'.
        ENDIF.
      WHEN 'I'.
        prc_dbf_data_type = 'N'.
      WHEN 'F'.
        prc_dbf_data_type = 'C'.
      WHEN 's'.
        prc_dbf_data_type = 'N'.
        prc_output_length = 6.
      WHEN 'b'.
        prc_dbf_data_type = 'N'.
        prc_output_length = 3.
      WHEN 'D'.
**        prc_output_length = 8.
      WHEN 'T'.
        prc_dbf_data_type = 'C'.
**        prc_output_length = 6.
      WHEN OTHERS.
        CLEAR prc_dbf_data_type.
        prc_columns_count = prc_columns_count - 1.
    ENDCASE.

    prc_column_name_str = prc_column_name.

    IF NOT prc_dbf_data_type IS INITIAL.

      prc_rec_len = prc_rec_len + prc_output_length.

      CALL METHOD converter->convert
        EXPORTING
          inbuff         = prc_column_name_str
          inbufflg       = 0
          outbufflg      = 0
        IMPORTING
          outbuff        = prc_enc_column_name
        EXCEPTIONS
          internal_error = 1
          OTHERS         = 2.
      IF sy-subrc <> 0.
        CASE sy-subrc.
          WHEN 1.
            MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
              RAISING unknown_error.
          WHEN 2.
            MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
              RAISING unknown_error.
        ENDCASE.
      ENDIF.

      CALL METHOD converter->convert
        EXPORTING
          inbuff         = prc_dbf_data_type
          inbufflg       = 0
          outbufflg      = 0
        IMPORTING
          outbuff        = prc_enc_dbf_data_type
        EXCEPTIONS
          internal_error = 1
          OTHERS         = 2.
      IF sy-subrc <> 0.
        CASE sy-subrc.
          WHEN 1.
            MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
              RAISING unknown_error.
          WHEN 2.
            MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
              RAISING unknown_error.
        ENDCASE.
      ENDIF.
*Определение информации по столбцу.
      PERFORM buildcolumninfo USING prc_enc_column_name
                                    prc_enc_dbf_data_type
                                    prc_output_length
                                    prc_dpts_length
                              CHANGING prc_enc_column_data.

      CONCATENATE prc_enc_all_columns prc_enc_column_data
        INTO prc_enc_all_columns
        IN BYTE MODE.
    ENDIF.

    prc_column_idx = prc_column_idx + 1.
  ENDWHILE.

*Запись номера строки в 4-7 байты и длины заголовка в 8-9 байты.
  DATA: prc_hex_lines_count(4)    TYPE x,
        prc_hex_lines_count_le(4) TYPE x,
        prc_header_len            TYPE i,
        prc_hex_header_len(2)     TYPE x.

  MOVE prc_lines_count TO prc_hex_lines_count.

  prc_header_len = prc_columns_count * 32.
  prc_header_len = prc_header_len + 33.
  MOVE prc_header_len TO prc_hex_header_len.

** Convert to little-endian
* Окончательное конвертирование
  MOVE prc_lines_count TO prc_hex_lines_count.
  MOVE prc_hex_lines_count(1) TO prc_hex_lines_count_le+3(1).
  MOVE prc_hex_lines_count+1(1) TO prc_hex_lines_count_le+2(1).
  MOVE prc_hex_lines_count+2(1) TO prc_hex_lines_count_le+1(1).
  MOVE prc_hex_lines_count+3(1) TO prc_hex_lines_count_le(1).

  CONCATENATE prc_output_string prc_hex_lines_count_le
              prc_hex_header_len+1 prc_hex_header_len(1)
    INTO prc_output_string
    IN BYTE MODE.
*Пишем длину записи в 10-11 байты
  DATA: prc_hex_rec_len(2) TYPE x.
  MOVE prc_rec_len TO prc_hex_rec_len.
  CONCATENATE prc_output_string prc_hex_rec_len+1 prc_hex_rec_len(1)
INTO prc_output_string
    IN BYTE MODE.
  PERFORM addzerobytes USING 20
                       CHANGING prc_output_string.
* Определение столбца
  CONCATENATE prc_output_string prc_enc_all_columns
    INTO prc_output_string
    IN BYTE MODE.
*Конец заголовка
  DATA: prc_end_of_header TYPE x VALUE 13.
  CONCATENATE prc_output_string prc_end_of_header
    INTO prc_output_string
    IN BYTE MODE.
  DATA: prc_val_tmp(40)   TYPE c,
        prc_enc_value_len TYPE i,
        prc_spaces_to_add TYPE i,
        prc_do_append     TYPE c.
  LOOP AT par_data_tab.
    PERFORM addspaces USING 1
                      CHANGING prc_output_string.
    prc_column_idx = 1.
    WHILE prc_column_idx <= prc_all_columns_count.
      ASSIGN COMPONENT prc_column_idx OF STRUCTURE par_data_tab TO <f>.

      DESCRIBE FIELD <f> TYPE prc_data_type
                         OUTPUT-LENGTH prc_output_length.
      DESCRIBE FIELD <f> DECIMALS prc_dpts_length.

      prc_do_append = 'X'.

      IF prc_data_type = 'C' OR prc_data_type = 'D'.
        DESCRIBE FIELD <f> LENGTH prc_output_length IN CHARACTER MODE.
      ENDIF.

      CASE prc_data_type.
        WHEN 'C' OR 'D' OR 'T'.
          prc_column_value =  <f>.
        WHEN 'X'.
          prc_column_value = 'x'.
          WRITE <f> TO prc_column_value+1.
          CONDENSE prc_column_value NO-GAPS.
        WHEN 'P' OR 'I' OR 'N' OR 'b' OR 's'.
          CLEAR prc_val_tmp.
          IF <f> < 0.
            MOVE <f> TO prc_val_tmp+1.
            TRANSLATE prc_val_tmp USING '- '.
            WRITE '-' TO prc_val_tmp(1).
          ELSE.
            MOVE <f> TO prc_val_tmp.
          ENDIF.
          CONDENSE prc_val_tmp NO-GAPS.

*         Write number right-aligned
          DATA: prc_val_tmp_len TYPE i,
                prc_shift_len TYPE i.

          prc_val_tmp_len = STRLEN( prc_val_tmp ).

          prc_shift_len = prc_output_length - prc_val_tmp_len.
          IF prc_shift_len > 0.
            SHIFT prc_val_tmp BY prc_shift_len PLACES RIGHT.
          ENDIF.

          prc_column_value = prc_val_tmp.
        WHEN 'F'.
          CLEAR prc_val_tmp.
          IF <f> = 0.
            prc_val_tmp = '0'.
          ELSE.
            WRITE <f> TO prc_val_tmp EXPONENT 0.
          ENDIF.
          TRANSLATE prc_val_tmp USING ',.'.
          CONDENSE prc_val_tmp NO-GAPS.
          prc_column_value = prc_val_tmp.
        WHEN OTHERS.               "// nothing, no append
          CLEAR prc_do_append.
      ENDCASE.

      IF NOT prc_do_append IS INITIAL.
        prc_column_value_str = prc_column_value.
        CALL METHOD converter->convert
          EXPORTING
            inbuff         = prc_column_value_str
            inbufflg       = 0
            outbufflg      = 0
          IMPORTING
            outbuff        = prc_enc_column_value
          EXCEPTIONS
            internal_error = 1
            OTHERS         = 2.
        IF sy-subrc <> 0.
          CASE sy-subrc.
            WHEN 1.
              MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
                RAISING unknown_error.
            WHEN 2.
              MESSAGE ID 'FES' TYPE 'E' NUMBER '024'
                RAISING unknown_error.
          ENDCASE.
        ENDIF.

        CONCATENATE prc_output_string prc_enc_column_value
          INTO prc_output_string
          IN BYTE MODE.

        prc_enc_value_len = XSTRLEN( prc_enc_column_value ).

        prc_spaces_to_add = prc_output_length - prc_enc_value_len.

        PERFORM addspaces USING prc_spaces_to_add
                             CHANGING prc_output_string.
      ENDIF.
      prc_column_idx = prc_column_idx + 1.

    ENDWHILE.
  ENDLOOP.
*Ставим метку конца таблицы
  DATA: prc_end_of_table TYPE x VALUE 26.
  CONCATENATE prc_output_string prc_end_of_table INTO prc_output_string
    IN BYTE MODE.
*Отправка dataprovider.
  DATA: BEGIN OF hex_record,
          myhex(1024) TYPE x,
        END OF hex_record.

  DATA: prc_hex_tab LIKE hex_record OCCURS 1 WITH HEADER LINE,
        prc_bin_filesize TYPE i,
        prc_rest         TYPE i,
        prc_dp_error     TYPE i VALUE 0,
        prc_dp_sysubrc   TYPE i VALUE 0.

  prc_bin_filesize = XSTRLEN( prc_output_string ).
  prc_rest = prc_bin_filesize.

  WHILE prc_rest > 1024.
    prc_hex_tab-myhex = prc_output_string(1024).
    APPEND prc_hex_tab.
    MOVE prc_output_string+1024 TO prc_output_string.
    prc_rest = prc_rest - 1024.
  ENDWHILE.

  IF prc_rest > 0.
    prc_hex_tab-myhex = prc_output_string.
    APPEND prc_hex_tab.
  ENDIF.

  DATA l_data TYPE STANDARD TABLE OF tbl1024.

  l_data[] = prc_hex_tab[].

  CALL FUNCTION 'SCMS_DOWNLOAD'
    EXPORTING
      filename = par_filename
      filesize = prc_bin_filesize
      binary   = 'X'
      frontend = ' '
    TABLES
      data     = l_data
    EXCEPTIONS
      error    = 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
            RAISING error_file.
  ENDIF.

  par_bytes_transfered = prc_bin_filesize.
ENDFORM.                    " app_dbf_download


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт, май 15 2007, 12:05 
Ассистент
Ассистент

Зарегистрирован:
Ср, июн 21 2006, 10:20
Сообщения: 38
Не знаю стоит ли пробовать ?
Этот фрагмент почти копия
FORM gui_dbf_download в групе функций SFES
которая и вызывается ФМ GUI_DOWNLOAD
Если глубже - то проблема в коде сопоставления типов/размера полей
АБАП и ДБФ :
Code:
DESCRIBE FIELD <f> TYPE          prc_data_type
                       OUTPUT-LENGTH prc_output_length.
и
Code:
WHEN 'P' OR 'N'.
        IF prc_output_length < 20.
          prc_dbf_data_type = 'N'.
          DESCRIBE FIELD <F> DECIMALS prc_dpts_length.
        ELSE.                      "// Typ C
          prc_dbf_data_type = 'C'.
        ENDIF.

в фрагменте (со строки 1394 )
Code:
WHILE prc_column_idx <= prc_all_columns_count.
    ASSIGN COMPONENT prc_column_idx OF STRUCTURE par_data_tab TO <f>.
   DESCRIBE FIELD <f> TYPE          prc_data_type
                       OUTPUT-LENGTH prc_output_length.
    READ TABLE par_field_names INDEX prc_column_idx.

    IF SY-SUBRC = 0.
      ASSIGN COMPONENT 1 OF STRUCTURE par_field_names TO <NAME>.
      prc_column_name = <NAME>.
    ELSE.
      prc_column_name = 'F'.
      WRITE prc_column_idx TO prc_column_name+1.
    ENDIF.
    CONDENSE prc_column_name NO-GAPS.

    prc_dpts_length = 0.
    prc_dbf_data_type = prc_data_type.

    IF prc_data_type = 'C' OR prc_data_type = 'D'.
        DESCRIBE FIELD <f> LENGTH prc_output_length IN CHARACTER MODE.
    ENDIF.

    CASE prc_data_type.
      WHEN 'C'.
      WHEN 'X'.
        prc_dbf_data_type = 'C'.
        prc_output_length = prc_output_length + 1.  " leading 'x'
      WHEN 'P' OR 'N'.
      IF prc_output_length < 20.
          prc_dbf_data_type = 'N'.
          DESCRIBE FIELD <F> DECIMALS prc_dpts_length.
        ELSE.                      "// Typ C
          prc_dbf_data_type = 'C'.
        ENDIF.
      WHEN 'I'.
        prc_dbf_data_type = 'N'.
      WHEN 'F'.
        prc_dbf_data_type = 'C'.
      WHEN 's'.
        prc_dbf_data_type = 'N'.
        prc_output_length = 6.
      WHEN 'b'.
        prc_dbf_data_type = 'N'.
        prc_output_length = 3.
      WHEN 'D'.
*        prc_output_length = 8.
      WHEN 'T'.
        prc_dbf_data_type = 'C'.
*        prc_output_length = 6.
      WHEN OTHERS.
        CLEAR prc_dbf_data_type.
        prc_columns_count = prc_columns_count - 1.
    ENDCASE.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт, май 15 2007, 13:16 
Специалист
Специалист

Зарегистрирован:
Чт, июн 23 2005, 18:05
Сообщения: 119
Так, в чем проблема?
Подкорректируйте код описания длин и числа десятичных.
Я для выгрузки в DBF пользуюсь этим кодом.
Все отлично выгружается. Правда десятичные не проверял.


Принять этот ответ
Вернуться к началу
 Профиль Отправить email  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт, май 17 2007, 17:00 
Ассистент
Ассистент

Зарегистрирован:
Чт, май 17 2007, 16:31
Сообщения: 40
Откуда: Санкт-Петербург
Когда-то написал для себя ФМ ZZ_MAKE_DBF для выгрузки в DBF.
Для преобразования в DOS использовал перекодировку 1500->1503.
Писал очень давно, сейчас что-то сделал-бы иначе :)

P.S. Ну вот, стоит немного отлучиться, и все собственные старые сообщения уже не прочитать. Мда... :?

структура 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:
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 c,         " имя поля
          fld_type(1)      type c,         " тип поля
          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.

** DBF table
data: DbfBuffer(32768)    type x occurs 0 with header line.

** DBF parameters
data: DbfFileSize         type i.

data: DbfRecordSize       type i.



ФМ: ZZ_MAKE_DBF

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

  perform CheckData       tables dbf_struct dbf_data.
  check sy-subrc = 0.

  perform Make_Descriptor tables dbf_struct.
  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 file.
  check sy-subrc = 0.

  perform DownloadData    using file.
  check sy-subrc = 0.

  perform Download_EOF    using 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 e...(...) 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 e...(...) with nDataField nStructField
                                raising short_dbf_data.
      else.
        sy-subrc = 0.
      endif.
      exit.
    endif.
  enddo.

endform.

*---------------------------------------------------------------------*
*       FORM Make_Descriptor                                          *
*---------------------------------------------------------------------*
form Make_Descriptor tables dbf_struct structure zdbf_struct.

* для замены пробелов на 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 e...(...) 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.

    DbfDescriptor-fld_type = dbf_struct-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.

*---------------------------------------------------------------------*
*       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.
      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.

*---------------------------------------------------------------------*
*       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.

*---------------------------------------------------------------------*
*       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>.
          if IS_DOS = 'X'.
            translate <field_to> from code page '1500'
                                   to code page '1503'.
          endif.
        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.

*---------------------------------------------------------------------*
*       FORM add_dbf                                                  *
*---------------------------------------------------------------------*
form add_dbf using cText type x.

  data: nLen type i.

  DbfBuffer+DbfFileSize = cText.

  describe field cText length nLen.
  add nLen to DbfFileSize.

endform.

*---------------------------------------------------------------------*
*       FORM DownloadHeader                                           *
*---------------------------------------------------------------------*
form DownloadHeader  using filename type  string.

  data: x0D(1) type x VALUE '0D'.

  field-symbols <fs> type x.

  refresh DbfBuffer.
  clear: DbfBuffer, DbfFileSize.

* заголовок
  assign DbfHeader to <fs> casting.
  perform add_dbf using <fs>.

* дескрипторы
  loop at iDbfDescriptor into DbfDescriptor.
    assign DbfDescriptor to <fs> casting.
    perform add_dbf using <fs>.
  endloop.

* терминальный байт
  perform add_dbf using x0D.

  append DbfBuffer.

  CALL FUNCTION 'GUI_DOWNLOAD'
    EXPORTING
            BIN_FILESIZE = DbfFileSize
            FILENAME     = filename
            FILETYPE     = 'BIN'
*           APPEND       = ' '
    TABLES
            DATA_TAB     = DbfBuffer
    EXCEPTIONS
            OTHERS       = 22.

  if sy-subrc <> 0.
* Ошибка выгрузки в &
    message e...(...) with filename raising error_download.
  endif.

endform.

*---------------------------------------------------------------------*
*       FORM DownloadData                                             *
*---------------------------------------------------------------------*
form DownloadData     using filename type  string.

  describe table <tab_to> lines DbfFileSize.
  DbfFileSize = DbfFileSize * DbfRecordSize.

  CALL FUNCTION 'GUI_DOWNLOAD'
       EXPORTING
            BIN_FILESIZE = DbfFileSize
            FILENAME     = filename
            FILETYPE     = 'BIN'
            APPEND       = 'X'
       TABLES
            DATA_TAB     = <tab_to>
       EXCEPTIONS
            OTHERS       = 22.

  if sy-subrc <> 0.
* Ошибка выгрузки в &
    message e...(...) with filename raising error_download.
  endif.

endform.

*---------------------------------------------------------------------*
*       FORM Download_EOF                                             *
*---------------------------------------------------------------------*
form Download_EOF     using filename type  string.

  data: x1A(1) type x VALUE '1A'.

  refresh DbfBuffer.
  clear: DbfBuffer, DbfFileSize.

* EOF
  perform add_dbf using x1A.

  append DbfBuffer.

  CALL FUNCTION 'GUI_DOWNLOAD'
       EXPORTING
            BIN_FILESIZE = DbfFileSize
            FILENAME     = filename
            FILETYPE     = 'BIN'
            APPEND       = 'X'
       TABLES
            DATA_TAB     = DbfBuffer
       EXCEPTIONS
            OTHERS       = 22.

  if sy-subrc <> 0.
* Ошибка выгрузки в &
    message e...(...) with filename raising error_download.
  endif.

endform.


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пт, дек 21 2007, 14:36 
Начинающий
Начинающий

Зарегистрирован:
Ср, окт 03 2007, 06:57
Сообщения: 9
Откуда: Киев
Спасибо!


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

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


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

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


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

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