Текущее время: Сб, июл 19 2025, 21:00

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


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

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


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

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