SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Импорт данных из Excel файла с несколькими листами в SAP R3



 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP
View previous topic :: View next topic  
Author Message
VokMS
Участник
Участник



Joined: 15 Apr 2011
Posts: 7

PostPosted: Fri Apr 15, 2011 3:55 pm    Post subject: Импорт данных из Excel файла с несколькими листами в SAP R3 Reply with quote

Для документов с 1 листом использовал ФМ TEXT_CONVERT_XLS_TO_SAP, но встала проблема импорта данных из Excel-документа, содержащего несколько листов. Может есть ФМ, которые позволяют это сделать или может будут предложения как решить данную проблему.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 46
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Fri Apr 15, 2011 4:35 pm    Post subject: Reply with quote

Стандартного ФМ вроде как не было. Можно написать самому, что нибудь этакое
Code:
" Объявляем данные
TYPE-POOLS: truxs, soi, cntl.

CONSTANTS: g_con_excel TYPE char80 VALUE 'Excel.Sheet',
           g_max_empty_rows TYPE i VALUE 1. " Считываем со второй строки

DATA: xlscontent TYPE REF TO data.
DATA l_oref_container TYPE REF TO cl_gui_custom_container.
DATA l_iref_control TYPE REF TO i_oi_container_control.
DATA l_iref_error TYPE REF TO i_oi_error.
DATA l_iref_document TYPE REF TO i_oi_document_proxy.
DATA: l_cntl_handle TYPE cntl_handle.
DATA  l_iref_spreadsheet TYPE REF TO i_oi_spreadsheet.
DATA  l_retcode TYPE soi_ret_string.
DATA: l_current_row TYPE i,
      l_tabix TYPE i,
      l_top TYPE i,
      l_left TYPE i,
      l_rows TYPE i,
      l_columns TYPE i.
DATA: l_oref_structure TYPE REF TO cl_abap_structdescr.
DATA: l_range_list TYPE soi_range_list.
DATA: l_table       TYPE soi_generic_table.
DATA: l_table_range TYPE soi_generic_table.
DATA: l_gen_tab LIKE LINE OF l_table.
DATA: lt_sheets TYPE soi_sheets_table,
      l_sheet LIKE LINE OF lt_sheets.
DATA: l_text6(6),
      l_text80(80).

FIELD-SYMBOLS: <xlscontent> TYPE table,
               <xlsrow> TYPE ANY.

" Селекционник
PARAMETERS: p_file TYPE rlgrap-filename.


AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.
  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      field_name = 'P_FILE'
    IMPORTING
      file_name  = p_file.

START-OF-SELECTION.
  PERFORM get_spreadsheet_interface
        USING g_con_excel
        CHANGING p_file l_oref_container l_iref_control
                 l_iref_error     l_iref_document
                 l_iref_spreadsheet.

  IF l_iref_spreadsheet IS INITIAL.
    MESSAGE e893(ux) WITH p_file.
  ENDIF.

* Считываем листы файла
  CALL METHOD l_iref_spreadsheet->get_sheets
    IMPORTING
      sheets = lt_sheets.

* Теперь бежим по ним и получаем данные
  LOOP AT lt_sheets INTO l_sheet.
    CALL METHOD l_iref_spreadsheet->select_sheet
      EXPORTING
        name = l_sheet-sheet_name.

    l_oref_structure ?= cl_abap_typedescr=>describe_by_data(
                      <xlsrow> ).

    DESCRIBE TABLE l_oref_structure->components LINES l_columns.
    l_left = 1.
    l_rows = 100.

    CLEAR l_current_row.
    WHILE l_current_row <= g_max_empty_rows.
      REFRESH l_table_range.
      CALL METHOD l_iref_spreadsheet->set_selection
        EXPORTING
          top     = l_top
          left    = l_left
          rows    = l_rows
          columns = l_columns
        IMPORTING
          retcode = l_retcode.
      CALL METHOD l_iref_spreadsheet->insert_range
        EXPORTING
          columns = l_columns
          rows    = l_rows
          name    = 'SAP_range1'
        IMPORTING
          retcode = l_retcode.

      CALL METHOD l_iref_spreadsheet->get_ranges_names
        IMPORTING
          ranges  = l_range_list
          retcode = l_retcode.

      DELETE l_range_list WHERE name <> 'SAP_range1'.

      CALL METHOD l_iref_spreadsheet->get_ranges_data
        IMPORTING
          contents = l_table_range
          retcode  = l_retcode
        CHANGING
          ranges   = l_range_list.
      LOOP AT l_table_range INTO l_gen_tab.
        AT NEW row.
          REFRESH l_table.
        ENDAT.

        APPEND l_gen_tab TO l_table.

        AT END OF row.
          PERFORM parse_table_line(sapltrux) USING    l_table sy-tabix
                                             CHANGING <xlsrow>.
          IF <xlsrow> IS INITIAL.
            l_current_row = l_current_row + 1.
          ELSE.
            APPEND <xlsrow> TO <xlscontent>.
            l_tabix = sy-tabix.
            IF sy-batch IS INITIAL.
              l_text80 = text-kox.
              l_text6 = l_tabix.
              REPLACE '&&&&&&' WITH l_text6 INTO l_text80.
              REPLACE '&&&&&&' WITH 'Excel' INTO l_text80.
              CONDENSE l_text80.
              CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
                EXPORTING
                  text = l_text80.
            ENDIF.
            CLEAR l_current_row.
          ENDIF.
        ENDAT.
      ENDLOOP.
      l_top = l_top + l_rows.
    ENDWHILE.

* Выравниваем десятичные
    PERFORM correct_decimals_for_current(sapltrux) TABLES <xlscontent>.

* Вуаля! В табличке <xlscontent> находятся данные с текущего Excel листа

* А вот здесь придется посоздавать динамических таблиц под эти данные

    any_dynamic_itab_sheet_name[] = <xlscontent>.

  ENDLOOP.

*&---------------------------------------------------------------------*
*&      Form  get_spreadsheet_interface
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->VALUE(PI_APPLICATION)       text
*      -->VALUE(PC_FILENAME)          text
*      -->VALUE(PC_OREF_CONTAINER)    text
*      -->VALUE(PC_IREF_CONTROL)      text
*      -->VALUE(PC_IREF_ERROR)        text
*      -->VALUE(PC_IREF_DOCUMENT)     text
*      -->VALUE(PC_IREF_SPREADSHEET)  text
*----------------------------------------------------------------------*
FORM get_spreadsheet_interface
      USING
           value(pi_application) TYPE char80
      CHANGING
            value(pc_filename) TYPE rlgrap-filename
            value(pc_oref_container) TYPE REF TO cl_gui_custom_container
            value(pc_iref_control) TYPE REF TO i_oi_container_control
            value(pc_iref_error) TYPE REF TO i_oi_error
            value(pc_iref_document) TYPE REF TO i_oi_document_proxy
            value(pc_iref_spreadsheet).
  DATA l_item_url(256) TYPE c.
  DATA l_retcode TYPE soi_ret_string.
  DATA l_has TYPE i.

* don't do anything in batch, because there is no GUI...
  CHECK sy-batch IS INITIAL.

  l_item_url = pc_filename.
  SET LOCALE LANGUAGE sy-langu.
  TRANSLATE pc_filename TO UPPER CASE.
  SET LOCALE LANGUAGE space.

  IF pc_filename(7) <> 'HTTP://' AND pc_filename(7) <> 'FILE://'.
    CONCATENATE 'FILE://' l_item_url INTO l_item_url.
  ENDIF.
  pc_filename = l_item_url.

  CALL METHOD c_oi_container_control_creator=>get_container_control
    IMPORTING
      control = pc_iref_control
      error   = pc_iref_error.
  CREATE OBJECT pc_oref_container
    EXPORTING
      container_name = 'TRUX_CONTAINER'.

  CALL METHOD pc_iref_control->init_control
    EXPORTING
      r3_application_name      = 'R/3 TR'
      inplace_enabled          = 'X'
      inplace_scroll_documents = 'X'
      parent                   = pc_oref_container
    IMPORTING
      error                    = pc_iref_error.

  CALL METHOD pc_iref_control->get_document_proxy
    EXPORTING
      document_type  = pi_application
    IMPORTING
      document_proxy = pc_iref_document
      error          = pc_iref_error.

  CALL METHOD pc_iref_document->open_document
    EXPORTING
      open_inplace = 'X'
      document_url = l_item_url
    IMPORTING
      retcode      = l_retcode.

  CALL METHOD pc_iref_document->has_spreadsheet_interface
    IMPORTING
      is_available = l_has.

  IF NOT l_has IS INITIAL.
    CALL METHOD pc_iref_document->get_spreadsheet_interface
      IMPORTING
        sheet_interface = pc_iref_spreadsheet.
  ENDIF.

ENDFORM.                               " GET_SPREADSHEET_INTERFACE

_________________
FunCoding.ru
KicksCollector.ru
Back to top
View user's profile Send private message Blog
VokMS
Участник
Участник



Joined: 15 Apr 2011
Posts: 7

PostPosted: Wed May 04, 2011 1:46 pm    Post subject: Reply with quote

Попробовал использовать представленный листинг, но не могу решить проблему в строке:
l_oref_structure ?= cl_abap_typedescr=>describe_by_data(<xlsrow> ).

Программа выпадает в дамп с ошибкой:
Field symbol has not get been assigned.

Непонятно что передает параметр <xlsrow> Embarassed
Back to top
View user's profile Send private message
Igor_34_rus
Специалист
Специалист



Joined: 08 Apr 2009
Posts: 75

PostPosted: Wed May 04, 2011 1:55 pm    Post subject: Reply with quote

VokMS wrote:
Попробовал использовать представленный листинг, но не могу решить проблему в строке:
l_oref_structure ?= cl_abap_typedescr=>describe_by_data(<xlsrow> ).

Программа выпадает в дамп с ошибкой:
Field symbol has not get been assigned.

Непонятно что передает параметр <xlsrow> Embarassed


я так понимаю, что <xlsrow> не передаёт, а получает. Количество строк на листе в экселе.
попробуй поменять на обычный "type i".
Back to top
View user's profile Send private message
Igor_34_rus
Специалист
Специалист



Joined: 08 Apr 2009
Posts: 75

PostPosted: Wed May 04, 2011 2:05 pm    Post subject: Reply with quote

ещё можно из экселя макросом предавать в буфер, а потом читать из сапа(RFC или из sap)

Code:
sap.
    (class I_OI_TABLE_COLLECTION-GET_TABLE)

EXCEL
     Dim it_data As Object
     Set it_data = oContainer.Tables("IT_DATA_NAME").Table
*   Запускаем макрос
      CALL METHOD ref_excel_document->proxy->execute_macro
        EXPORTING
          macro_string = 'Utils.Start'
          param_count = 0
        IMPORTING
          error = ref_error
          retcode = retcode.
      CALL METHOD c_oi_errors=>show_message
        EXPORTING
          type = 'E'.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 46
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Wed May 04, 2011 2:26 pm    Post subject: Reply with quote

Все чуть иначе.

Я в примере не указал следующее.

Code:
  ASSIGN: gt_xls_table TO <xlscontent>,
          ls_xls_row   TO <xlsrow>.

  l_top  = 2.
  l_left = 2.

где gt_xls_table будет табличка данных из Excel с нужной вам типизацией, а ls_xls_row - хидер для таблички.

А процедура, на которой падает, определяет количество столбцов по структуре. Ну или можно задать жестко, как предложили выше.

_________________
FunCoding.ru
KicksCollector.ru
Back to top
View user's profile Send private message Blog
VokMS
Участник
Участник



Joined: 15 Apr 2011
Posts: 7

PostPosted: Wed May 04, 2011 2:31 pm    Post subject: Reply with quote

Igor_34_rus wrote:
VokMS wrote:
Попробовал использовать представленный листинг, но не могу решить проблему в строке:
l_oref_structure ?= cl_abap_typedescr=>describe_by_data(<xlsrow> ).

Программа выпадает в дамп с ошибкой:
Field symbol has not get been assigned.

Непонятно что передает параметр <xlsrow> Embarassed


я так понимаю, что <xlsrow> не передаёт, а получает. Количество строк на листе в экселе.
попробуй поменять на обычный "type i".

Смена типа не помогла
Sad
Выдает ошибку:
Dynamic type conflict when assigning references
Back to top
View user's profile Send private message
Igor_34_rus
Специалист
Специалист



Joined: 08 Apr 2009
Posts: 75

PostPosted: Wed May 04, 2011 2:42 pm    Post subject: Reply with quote

напиши изменения которые внёс в код
Back to top
View user's profile Send private message
VokMS
Участник
Участник



Joined: 15 Apr 2011
Posts: 7

PostPosted: Wed May 04, 2011 3:57 pm    Post subject: Reply with quote

Общими усилиями заставили работать программу. Но может кто знает возможно или нет определить количество заполненных данными строк на листе Excel (ну если это возможно вообще). Это бы сильно помогло ускорить работу программы(количество столбцов известно, а количество записей на листе всегда разное бывает) Rolling Eyes
Back to top
View user's profile Send private message
VokMS
Участник
Участник



Joined: 15 Apr 2011
Posts: 7

PostPosted: Fri May 06, 2011 4:00 pm    Post subject: Reply with quote

Возникла проблема при ASSIGN, не мог разобраться почему, может кто-нибудь подскажет в чём я неправ.
Фрагмент:
Code:
DATA: BEGIN OF gt_xls_table OCCURS 0 ,
      pole1(100),
      pole2(100),
      pole3(100),
      pole4(100),
      pole5(100),
      pole6(100),
  END OF gt_xls_table.

DATA: ls_xls_row like gt_xls_table.
     
FIELD-SYMBOLS: <xlscontent> TYPE table,
               <xlsrow> TYPE ANY.
 ASSIGN:
          gt_xls_table TO <xlscontent>,
          ls_xls_row   TO <xlsrow>.

Ошибка:
Code:
"GT_XLS_TABLE" and "<XLSCONTENT>" are type-incompatible.
Back to top
View user's profile Send private message
Igor_34_rus
Специалист
Специалист



Joined: 08 Apr 2009
Posts: 75

PostPosted: Fri May 06, 2011 4:39 pm    Post subject: Reply with quote

попробуй
ASSIGN:
gt_xls_table[] TO <xlscontent>.
Back to top
View user's profile Send private message
Nicks
Участник
Участник



Joined: 02 Aug 2010
Posts: 9

PostPosted: Tue May 10, 2011 6:59 am    Post subject: Reply with quote

VokMS wrote:
Общими усилиями заставили работать программу. Но может кто знает возможно или нет определить количество заполненных данными строк на листе Excel (ну если это возможно вообще). Это бы сильно помогло ускорить работу программы(количество столбцов известно, а количество записей на листе всегда разное бывает) Rolling Eyes

Возможно, вот так например
Code:
 GET PROPERTY OF  h_sheet 'UsedRange' = h_over.
  GET PROPERTY OF  h_over  'Rows'      = h_over1.
  GET PROPERTY OF h_over1  'Count'     = lc_count.   "определяем к-во записей в запросе

Делаем предположение что h_sheet уже присвоен требуемый лист рабочей книги. Правда есть свои проблемы-следует помнить что UsedRange обновляется только при сохранении книги - может быть ситуация когда данные удалены а UsedRange не пересчитался. т.е данные должны удаляться через удаление строк или столбцов.На самом деле эта проблема более широка и его обсуждение
http://www.sql.ru/forum/actualthread.as ... 48#4535898
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.