(原创)自定义抓取特定SHEET页数据的功能模块

      利用DOI技术自定义了一个能够抓取EXCEL中特定SHEET页数据的FUNCTION.如下:

FUNCTION源代码:

FUNCTION Z15540_EXCEL_TO_SAP.
*"----------------------------------------------------------------------
*"*"本地接口:
*"  IMPORTING
*"     VALUE(I_ROW) TYPE  INT_5 DEFAULT 2000
*"     VALUE(I_FILENAME) TYPE  RLGRAP-FILENAME
*"     REFERENCE(I_HEADERLINE) TYPE  CHAR01 DEFAULT 'X'
*"     REFERENCE(I_SHEET) TYPE  INT_5 DEFAULT 1
*"  TABLES
*"      T_DATA TYPE  STANDARD TABLE
*"----------------------------------------------------------------------
  DATA:LV_FILEURL    TYPE  BDS_URI,
       LCL_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER, "容器引用对象
       LCL_CONTROL   TYPE REF TO I_OI_CONTAINER_CONTROL, "容器控制器引用对象
       LCL_DOCUMENT  TYPE REF TO I_OI_DOCUMENT_PROXY, "对应EXCEL文档层次引用对象
       LCL_SHEET     TYPE REF TO I_OI_SPREADSHEET, "对应SHEET层次操作的接口引用对象
       LCL_ERROR     TYPE REF TO I_OI_ERROR, "返回消息
       HAS_SPREAD    TYPE I,
       LS_SHEET      TYPE ZSHEET.
  DATA: LCL_STRUCTURE TYPE REF TO CL_ABAP_STRUCTDESCR,
        LS_RANGE      TYPE SOI_RANGE_ITEM,
        LT_RANGE      TYPE TABLE OF SOI_RANGE_ITEM, "为SET_RANGE_DATA方法标明填充数据的范围名及其行列数
        LS_CONTENT    TYPE SOI_GENERIC_ITEM,
        LT_CONTENT    TYPE TABLE OF SOI_GENERIC_ITEM, "为SET_RANGE_DATA方法提供填充数据
        LV_COLUMNS    TYPE I, "输出内表列数
        LV_LEFT       TYPE I, "抓取范围左上角列号
        LV_TOP        TYPE I, "抓取反复问左上角行号
        LV_ROWS       TYPE I,
        LV_SHEET      TYPE I,
        LV_ASSIGN_COL TYPE I.
  DATA: LT_SHEETNAME TYPE SOI_SHEETS_TABLE, "EXCEL中SHEET名称集合
        LS_SHEETNAME TYPE LINE OF SOI_SHEETS_TABLE.
  DATA LV_COUNT_SHEET TYPE I.
  FIELD-SYMBOLS:<FS_FIELD>.
  RANGES LR_SHEET FOR  ZSHEET-SHEET.

  IF I_FILENAME(7) NE 'FILE://'.
    CONCATENATE 'FILE://' I_FILENAME INTO LV_FILEURL."拼接文件URL
  ENDIF.
  LV_ROWS = I_ROW.
  LV_SHEET = I_SHEET.
  "实例化控制器
  CALL METHOD C_OI_CONTAINER_CONTROL_CREATOR=>GET_CONTAINER_CONTROL
    IMPORTING
      CONTROL = LCL_CONTROL
      ERROR   = LCL_ERROR
*     RETCODE =
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
    MESSAGE '实例化控制器失败' TYPE 'E'.
  ENDIF.
  "实例化容器
  CREATE OBJECT LCL_CONTAINER
    EXPORTING
      CONTAINER_NAME = 'CONTAINER1'.
  .
  "初始化控制器,绑定容器
  CALL METHOD LCL_CONTROL->INIT_CONTROL
    EXPORTING
*     DYNPRO_NR                = SY-DYNNR
*     GUI_CONTAINER            = ' '
      INPLACE_ENABLED          = 'X'
*     INPLACE_MODE             = 0
      INPLACE_RESIZE_DOCUMENTS = 'X'
      INPLACE_SCROLL_DOCUMENTS = 'X'
*     INPLACE_SHOW_TOOLBARS    = 'X'
      NO_FLUSH                 = 'X'
*     PARENT_ID                = cl_gui_cfw=>dynpro_0
      R3_APPLICATION_NAME      = 'R/3 TR'
*     REGISTER_ON_CLOSE_EVENT  = ' '
*     REGISTER_ON_CUSTOM_EVENT = ' '
*     REP_ID                   = SY-REPID
*     SHELL_STYLE              = 1384185856
      PARENT                   = LCL_CONTAINER
*     NAME                     =
*     AUTOALIGN                = 'x'
    IMPORTING
      ERROR                    = LCL_ERROR
*     RETCODE                  =
*    EXCEPTIONS
*     JAVABEANNOTSUPPORTED     = 1
*     OTHERS                   = 2
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
   MESSAGE '初始化控制器失败!' TYPE 'E'.
  ENDIF.
  "实例化LCL_DOCUMENT
  CALL METHOD LCL_CONTROL->GET_DOCUMENT_PROXY
    EXPORTING
*     DOCUMENT_FORMAT    = 'NATIVE'
      DOCUMENT_TYPE  = 'EXCEL.SHEET' "应用类型
      NO_FLUSH       = 'X'
*     REGISTER_CONTAINER = ' '
    IMPORTING
      DOCUMENT_PROXY = LCL_DOCUMENT
      ERROR          = LCL_ERROR
*     RETCODE        =
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
    MESSAGE '实例化LCL_DOCUMENT失败!' TYPE 'E'.
  ENDIF.
  "打开EXCEL文件
  CALL METHOD LCL_DOCUMENT->OPEN_DOCUMENT
    EXPORTING
*     DOCUMENT_TITLE   = ' '
      DOCUMENT_URL  = LV_FILEURL
*     NO_FLUSH      = ' '
      OPEN_INPLACE  = 'X'
      OPEN_READONLY = 'X'
*     PROTECT_DOCUMENT = ' '
*     ONSAVE_MACRO  = ' '
*     STARTUP_MACRO = ''
*     USER_INFO     =
    IMPORTING
      ERROR         = LCL_ERROR
*     RETCODE       =
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
   MESSAGE '打开文件夹失败!' TYPE 'E'.
  ENDIF.


  "实例化SHEET对象
*  IF HAS_SPREAD IS NOT INITIAL.
  CALL METHOD LCL_DOCUMENT->GET_SPREADSHEET_INTERFACE
    EXPORTING
      NO_FLUSH        = 'X'
    IMPORTING
      ERROR           = LCL_ERROR
      SHEET_INTERFACE = LCL_SHEET
*     RETCODE         =
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
    MESSAGE '实例化LCL_SHEET失败' TYPE 'E'.
  ENDIF.
*  ENDIF.

  LCL_STRUCTURE ?= CL_ABAP_TYPEDESCR=>DESCRIBE_BY_DATA( T_DATA ).

  "计算结构的列数
  DESCRIBE TABLE LCL_STRUCTURE->COMPONENTS LINES LV_COLUMNS.
  LV_LEFT = 1.
  IF I_HEADERLINE IS NOT INITIAL.
    LV_TOP = 2.
  ELSE.
    LV_TOP = 1.
  ENDIF.
  "获取EXCEL中的所有SHEET页名称
  CALL METHOD LCL_SHEET->GET_SHEETS
*    EXPORTING
*      NO_FLUSH = ''
*     UPDATING = -1
    IMPORTING
      SHEETS   = LT_SHEETNAME
      ERROR    = LCL_ERROR
*     RETCODE  =
    .
  IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
  MESSAGE '获取文件SHEET页名称失败!' TYPE 'E'.
  ENDIF.

  LOOP AT LT_SHEETNAME INTO LS_SHEETNAME.
    LV_COUNT_SHEET = LV_COUNT_SHEET + 1.
    IF LV_COUNT_SHEET = LV_SHEET.

    ELSE.
      CONTINUE.
    ENDIF.
    "选中SHEET
    CALL METHOD LCL_SHEET->SELECT_SHEET
      EXPORTING
        NAME     = LS_SHEETNAME-SHEET_NAME
*        NO_FLUSH = ''
*  IMPORTING
*       ERROR    =
*       RETCODE  =
      .

    "设置范围,创建一个,名叫RANGE1的范围对象
    CALL METHOD LCL_SHEET->INSERT_RANGE_DIM
      EXPORTING
*        NO_FLUSH = ''
        NAME     = 'RANGE1'
        LEFT     = LV_LEFT
        TOP      = LV_TOP
        ROWS     = LV_ROWS
        COLUMNS  = LV_COLUMNS
*       UPDATING = -1
*       SHEETNAME = ''
*  IMPORTING
*       ERROR    =
*       RETCODE  =
      .
    CALL METHOD LCL_SHEET->GET_RANGES_NAMES
      IMPORTING
        RANGES = LT_RANGE.
    DELETE LT_RANGE WHERE NAME NE 'RANGE1'.
    "获取范围数据
    CALL METHOD LCL_SHEET->GET_RANGES_DATA
*      EXPORTING
*        NO_FLUSH = ''
*       ALL      = ''
*       UPDATING = -1
*       RANGESDEF =
      IMPORTING
        CONTENTS = LT_CONTENT
        ERROR    = LCL_ERROR
*       RETCODE  =
      CHANGING
        RANGES   = LT_RANGE.
    IF LCL_ERROR->HAS_FAILED IS NOT INITIAL.
     MESSAGE '获取文件数据失败!' TYPE 'E'.
    ENDIF.
    DELETE LT_CONTENT WHERE VALUE IS INITIAL.
    "转换数据
    LOOP AT LT_CONTENT INTO LS_CONTENT.
      LV_ASSIGN_COL = LS_CONTENT-COLUMN.
      ASSIGN COMPONENT LV_ASSIGN_COL OF STRUCTURE T_DATA TO <FS_FIELD>.
      <FS_FIELD> = LS_CONTENT-VALUE.
      AT END OF ROW.
        APPEND T_DATA.
      ENDAT.
      CLEAR:LS_CONTENT.
    ENDLOOP.
  ENDLOOP.
  "释放SHEET实例
  FREE: LCL_SHEET.
  "关闭文件,释放DOCUMENT是咯
  CALL METHOD LCL_DOCUMENT->CLOSE_DOCUMENT.
  CALL METHOD LCL_DOCUMENT->RELEASE_DOCUMENT.
  FREE LCL_DOCUMENT.
  "销毁控制器
  CALL METHOD LCL_CONTROL->RELEASE_ALL_DOCUMENTS.
  CALL METHOD LCL_CONTROL->DESTROY_CONTROL.

ENDFUNCTION.

      

      最后给出一个测试程序:

读取目标:可用库存清单(第2个SHEET页)

测试程序代码:

*&---------------------------------------------------------------------*
*& Report Z15540_GET_EXCEL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT Z15540_GET_EXCEL.
"数据定义
DATA:BEGIN OF GS_DATA,
       WERKS TYPE MARD-WERKS,
       LGORT TYPE MARD-LGORT,
       MATNR TYPE MARD-MATNR,
       MAKTX TYPE MAKT-MAKTX,
       LABST TYPE MARD-LABST,
       MEINS TYPE MARA-MEINS,
     END OF GS_DATA.
DATA GT_DATA LIKE TABLE OF GS_DATA.
DATA LV_FILENAME TYPE RLGRAP-FILENAME.
DATA:LT_FILETABLE TYPE FILETABLE WITH HEADER LINE,
     LV_RC TYPE I.
START-OF-SELECTION.

CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_OPEN_DIALOG
*  EXPORTING
*    WINDOW_TITLE            =
*    DEFAULT_EXTENSION       =
*    DEFAULT_FILENAME        =
*    FILE_FILTER             =
*    WITH_ENCODING           =
*    INITIAL_DIRECTORY       =
*    MULTISELECTION          =
  CHANGING
    FILE_TABLE              = LT_FILETABLE[]
    RC                      = LV_RC.
*    USER_ACTION             =
*    FILE_ENCODING           =
*  EXCEPTIONS
*    FILE_OPEN_DIALOG_FAILED = 1
*    CNTL_ERROR              = 2
*    ERROR_NO_GUI            = 3
*    NOT_SUPPORTED_BY_GUI    = 4
*    OTHERS                  = 5
        .
IF SY-SUBRC <> 0.
* Implement suitable error handling here
ENDIF.
READ TABLE LT_FILETABLE INDEX 1.
IF SY-SUBRC = 0.
LV_FILENAME = LT_FILETABLE-FILENAME.
ENDIF.

  CALL FUNCTION 'Z15540_EXCEL_TO_SAP'
    EXPORTING
*     I_ROW      = 2000
      I_FILENAME = LV_FILENAME
     I_HEADERLINE       = ''
     I_SHEET    = 2
    TABLES
      T_DATA     = GT_DATA.
  LOOP AT GT_DATA INTO GS_DATA.
   WRITE:/ GS_DATA-WERKS,GS_DATA-LGORT,GS_DATA-MATNR,GS_DATA-MAKTX,GS_DATA-LABST,GS_DATA-MEINS.
  ENDLOOP.

输出结果:

原文地址:https://www.cnblogs.com/jianglaizhen/p/8796857.html