利用DATA CLUSTER技术存储图片或者文档

一、 DATA CLUSTER介绍
Data cluster是data objects的组合。Data object可以是fields, structured fields, internal tables以及complex data objects。可以通过ABAP语句EXPORT,IMPORT和DELETE来操作data cluster。Data cluster可以存储在cluster database中。可以通过application area来划分cluster database的区域。Application area的name是由两个字符组成的。同一个application area的cluster是通过cluster id来区分的。
对于export需要一个cluster database,table INDX是一个cluster database。Cluster database在ABAP dictionary中是transparent table并有standardized structure。执行EXPORT需要指定cluster database及其application area。通过cluster ID来区分cluster本身。如果cluster中的field name与program中的不同可以通过addition from来实现。对于export没有任何write protection。数据在cluster database中是以压缩的形式存储的。程序启动时,可以通过TABLES语句来声明cluster database的application area。Internal table的headline不能被export。

    EXPORT <NAME> FROM <obj>
                           [obj]
                    TO DATABASE <dbtab>(<ar>) ID <id>
    例:REPORT XXX.
         TABLES indx.
             EXPORT 
                  <field1> from <field a>
                  <field2> from <field b>
                  ...
                  <structure1> from <structure a>
                  ...
                  <itab1> from <itab a>
                TO DATABASE indx(<ar>)
                ID <id>

对于IMPORT你只需要列出cluster data objects的子集,如program中的变量的名称与cluster中data object的名称不同可以通过addition TO来实现。通过sy-subrc来返回IMPORT执行的结果,如果不成功sy-subrc <> 0。Field,structure和internal table的结构与cluster中相应object的必须相同,否则就会产生runtime error。IMPORT时所使用的field name与EXPORT时所使用的field name必须相同。如果cluster存在sy-subrc = 0,而不管data field是否被imported。DELETE用来删除整个cluster。DELETE也通过return code返回结果。

         IMPORT <name> TO <obj>
              [obj]
              FROM DATABASE <dbtab>(<ar>) ID <id>
    例:REPORT XXX.
          TABLES indx.
            IMPORT
                 <field1> TO <field a>
               <field2> TO <field b>
               <field3> TO <field c>
               ...
               <structure1> TO <structure a>
               ...
               <itab1> TO <itab a>
             TO DATABASE indx(<ar>)
             ID <id>.

 数据簇操作
(一) ABAP/4内存中的数据簇
1. 在 ABAP/4 内存中存储数据对象

EXPORT <f1> [FROM <g1>] <f2> [FROM <g2>] ... TO MEMORY ID <key>.

此语句将列表中指定的数据对象存储为ABAP/4内存中的数据簇。如果忽略选项FROM,则将数据对象存储到自己的名称之下。如果使用该选项,则将数据对象存储到下面。
注:ID 用于标识内存数据,不得超过32个字符. EXPORT语句总是完全改写 ID 相同的任何现有数据簇的内容.对于有表头行的内表,只可以存储表本身,而不能存储表头行。在EXPORT语句中,将表名解释为表。这是例外。通常情况下,语句将表名解释为表工作区
2. 从内存中读取数据对象

IMPORT <f1> [TO <g1>] <f2> [TO <g2>] ... FROM MEMORY ID <key>.

此语句从ABAP/4内存的数据簇中读取列表中指定的数据对象。如果忽略选项TO,则将内存中的数据对象赋给程序中的同名数据对象。如果使用此选项,则将内存中的数据对象写入字段中。ID用于标识内存数据,不得超过32个字符。
不必读取存储在特定ID下的所有对象。相反,可以从名称中进行选择。如果内存中不包含指定ID下的对象,则将SY-SUBRC设置为4。但是,如果内存中存在带此ID的数据簇,无论数据对象是否也存在,SY-SUBRC之值总是为0。如果簇中不存在数据对象,则目标字段保持不变。
此语句不进行这种检查:即内存中的对象结构与要写入的结构是否匹配。因为数据是按位进行传送的,所以不匹配的结构可能会引起不一致。
3. 删除内存中的数据簇
FREE MEMORY [ID ].如果不附加 ID , 则此语句删 除整个内存 ,包括此前 用 EXPORT 存储到 ABAP/4 内存中的所 有数据簇。 附加 ID 之后,该语 句只删除用 此名称命名 的数据簇。
(二) 数据库中的数据簇
1. 簇数据库的结构:
这里写图片描述
建立簇数据库的规则如下所述。必须创建第一点到第四点中列出的关键字段。上述数据类型都是ABAP/4词典类型。
 如果该表是针对客户的,第一个字段必须这样定义:名称为MANDT,类型为CHAR,长度为3字节,用于存储客户ID。存储数据簇时,系统既可自动使用当前客户填写字段MANDT,还可使用EXPORT语句中显式指定的客户进行填写。2.下一字段(对于与客户无关的表,这是第一个字段)必须这样定义:名称为RELID,类型为CHAR,长度为2字节。该字段包含区域ID。簇数据库被分成不同的区域。存储数据簇时,系统用EXPORT语句中指定的区域ID填写字段RELID。3.下一字段类型为CHAR,长度可变。它包含簇的名称,存储数据簇时,在程序中用EXPORT语句的附加ID指定了该簇。因为后面的字段要对齐,所以系统应最多使用3个未用字节填充在字段RELID的结尾。如果创建自己的簇数据库,应该相应地定义此字段的长度。
 下一字段必须名称为SRTF2,类型为INT4,长度为4。单个数据簇可以扩展到数据库表的好几行中。在理论上,每个簇可能有2**31行。字段SRTF2包含存储的数据簇内行的顺序号码,可以是0和2**31-1之间的任何值。存储数据簇时,系统自动填写此字段(参见第7点)。
 SRTF2的后面可以是任何数目的资料字段元,这些字段名称和类型可任意交换。存储数据簇时,系统并不自动填写这些字段。必须在程序中的EXPORT语句之前将值显式分配到这些字段。通常包含诸如程序名、用户ID等控制信息。
 行上的倒数第二个字段名称必须为CLUSTR,类型为INT2,并且长度必须为2。它包含后面的字段CLUSTD中的数据长度。存储数据簇时,系统自动填写此字段。
 行上的最后一个字段必须名称为CLUSTD,类型为VARC。其长度可以任意,但通常为1000个字节左右。存储数据簇时,系统按压缩格式用实际数据填写此字段。如果CLUSTD的长度不足以存储簇数据,则数据就被分布到多行上。这些行在字段SRTF2中进行编号(参见上面的第4点)。
既可以按照上述规则创建自己的簇数据库(此时参见文档ABAP/4词典),也可以使用系统定义的簇数据库INDX
2. 在簇数据库中存储数据对象

EXPORT <f1> [FROM <g1>] <f2> [FROM <g2>] ... 
TO DATABASE <dbtab>(<ar_id>) [CLIENT <cli>] ID <key>.

此语句将列表中指定的数据对象存储为簇数据库中的簇。必须用TABLES语句对加以声明。如果不附加FROM,则将数据对象存储在自己的名称之下。如果有附件项,则将数据对象存储到名称之下。
是存储数据库的簇的两字符区域ID。
标识数据库中的数据,其最大长度取决于中名称字段的长度。
在处理特定客户的簇数据库时可以使用选项CLIENT 关闭自动客户处理,然后自己指定客户。必须在指定数据库名称之后立即指定此选项。
EXPORT语句也将表工作区的用户字段内容传输到数据库表。根据需要,可以预先填写这些字段。
在具有相同名称的相同工作区和相同客户系统中,EXPORT语句总是完全改写任何现有资料簇的内容。对于含有表头行的内表,只可以存储表本身,而不能存储表头行。在EXPORT语句中,将表名解释为表。这是例外。通常将表名解释为表工作区
3. 创建数据簇目录表

IMPORT DIRECTORY INTO <dirtab> 
FROM DATABASE <dbtab>(<ar>)
[CLIENT <cli>] ID <key>.

此语句在存储于数据库中的数据簇中创建一系列数据对象,并将其放到表中。必须使用TABLES语句声明。要将数据簇存储到数据库中,通常使用EXPORTTODATABASE语句
是即将存储数据库的簇的两字符ID。标识数据库中的数据,其最大长度取决于中名称字段的长度。在处理特定客户的簇数据库时,可以使用选项CLIENT关闭自动客户处理,然后自己指定客户。必须在指定数据库名称之后立即指定此选项。
IMPORT语句也自动从数据库表中读取表工作区的用户字段内容。如果可以创建某个目录表,则把SY-SUBRC设置为0。否则,设置为4。
4. 从簇数据库中读取数据对象

IMPORT <f1> [TO <g1>] <f2> [TO <g2>] ... 
FROM DATABASE <dbtab>(<ar>) 
[CLIENT <cli>] ID <key>|MAJOR-ID <maid> [MINOR-ID <miid>].

此语句从数据库中的数据簇中读取列表中指定的数据对象。必须用TABLES语句声明。如果不附加TO,则将数据库的数据对象分配给程序中的同名数据对象。如果不附加此选项,则将数据库的数据对象写入字段。
是即将存储数据库的簇的两字符区域ID。标识数据库中的数据,其最大长度取决于中名称字段的长度。可以用MAJOR-ID代替附加ID。然后,就选定名称的第一部分与相符的数据簇。如果指定具有MAJOR-ID的附加MINOR-ID,则选择名称的第二部分(也就是长度之后的位置)大于或等于的数据簇。在处理特定客户簇数据库时,可以使用选项CLIENT关闭自动客户处理,然后自己指定客户。必须在输入数据库名之后立即指定此选项。IMPORT语句也自动从数据库表中读取表工作区的用户字段内容。
不必读取存储在特殊名称之下的所有对象,但可以使用名称作出选择。如果数据库不包含具有指定关键词、和的对象,则将SY-SUBRC设置为4。但是,如果数据库中存在具有这些关键词的数据簇,那么,无论是否存在数据对象,SY-SUBRC之值总是为0。如果簇中没有数据对象,则目标字段保持不变。
运行时,系统检查此语句以查看数据库中对象的结构是否与要写入的结构相符。如果不符合,将出现运行时间错误。类型C字段是此规则的例外,也可显示在结构数据域位结尾。可以加长、缩短、附加或忽略。
5. 从簇数据库中删除数据簇

DELETE FROM DATABASE <dbtab>(<ar>) [CLIENT <cli>] ID <key>.

此语句删除数据库表中区域为和名称为的整个数据簇。必须用TABLES语句对进行声明。

二、 创建ABAP CLUSTER DATABASE
可以通过下面的步骤自己创建abap cluster database;
 在abap dictionary中建立一个transparent table,用来存储cluster database
 建立table structure
 MANDT FIELD可以被ommit
 字段RELID,SRTF2,CLUSTER,CLUSTID和cluster id在EXPORT的时候会被自动填充。
 自定义的字段要在export之前填充,这些字段的值可以被IMPORT获取
 选择cluster ID的field name和你自己的fields,剩余的field是由系统确定的。
 通过structure的总体长度减去前六个字段的长度可以得到数据所占的长度。

INDX是可以存储cluster的一个例子,其在系统中是缺省安装的,它的key field的长度为31byte,除了key field和data cluster还有一些字段用来存储管理系信息。比如change, validate date, create by等。可以在EXPORT之前来填充这些信息。比如:MOVE SY-DATUM TO INDX-AEDAT。
Cluster table和transparent table的区别:cluster table用来存储cluster,很少访问大量数据,存储的是异构数据,灵活的技术,不能用于link access,需要cluster ID和application area才能访问,其返回结果只能是是一个cluster。而对于transparent table可以多次访问,支持link access可以通过logical condition限制访问的数据。
这里写图片描述

三、 使用DATA CLUSTER存储图片/文档
使用前述介绍的EXPORT语法,将图片或文档信息存入表ZLIAP04,代码如下:

REPORT  z_li44_input.

TYPE-POOLS vrm.
TYPES pict_line(256) TYPE x.
DATA  pict_tab TYPE TABLE OF pict_line.

FIELD-SYMBOLS: <a> TYPE ANY .
DATA: l_file TYPE string.

DATA : param     TYPE vrm_id,
       values    TYPE vrm_values,
       value     LIKE LINE OF values.

SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-001.
PARAMETERS:p_file TYPE  rlgrap-filename OBLIGATORY.
SELECTION-SCREEN SKIP 1.
PARAMETERS:p_type TYPE char1 DEFAULT '1' AS LISTBOX VISIBLE LENGTH 8 OBLIGATORY.
PARAMETERS:p_name TYPE char45 OBLIGATORY.
SELECTION-SCREEN END OF BLOCK block1.

INITIALIZATION.
  PERFORM ini.

*-------------------------At Selection-Screen--------------------------*
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_file.

  PERFORM scan_file CHANGING p_file.

START-OF-SELECTION.
  l_file =  p_file.

  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
      filename                = l_file
      filetype                = 'BIN'
    TABLES
      data_tab                = pict_tab
    EXCEPTIONS
      file_open_error         = 1
      file_read_error         = 2
      no_batch                = 3
      gui_refuse_filetransfer = 4
      invalid_type            = 5
      no_authority            = 6
      unknown_error           = 7
      bad_data_format         = 8
      header_not_allowed      = 9
      separator_not_allowed   = 10
      header_too_long         = 11
      unknown_dp_error        = 12
      access_denied           = 13
      dp_out_of_memory        = 14
      disk_full               = 15
      dp_timeout              = 16
      OTHERS                  = 17.
  IF sy-subrc <> 0.
    MESSAGE i001(00) WITH '读取文件错误'.
    STOP.
  ENDIF.

  CASE p_type .
    WHEN '1'.
      EXPORT pict_tab = pict_tab TO DATABASE zliap04(pi) ID p_name. "abtree

    WHEN '2'.
      EXPORT pict_tab = pict_tab TO DATABASE zliap04(dm) ID p_name.
  ENDCASE.

  IF sy-subrc = 0.
    MESSAGE s001(00) WITH 'IMPORT SUCCESS'.
  ELSE.
    MESSAGE e001(00) WITH 'IMPORT FAILED'.
  ENDIF.


*&---------------------------------------------------------------------*
*&      Form  scan_file
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_P_FILE   text
*----------------------------------------------------------------------*
FORM scan_file  CHANGING p_p_file.

  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
    CHANGING
      file_name     = p_p_file
    EXCEPTIONS
      mask_too_long = 1
      OTHERS        = 2.

ENDFORM.                    " scan_file
*&---------------------------------------------------------------------*
*&      Form  ini
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM ini .
  CLEAR param.
  CLEAR value.
  CLEAR values[].

  param = 'P_TYPE'.

  value-key  = '1'.
  value-text = '图片'.
  APPEND value TO values.
  value-key  = '2'.
  value-text = '文档'.
  APPEND value TO values.
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = param
      values = values.
ENDFORM.                    " ini

这里写图片描述

导入后数据保存在表ZLIAP04,如下所示
这里写图片描述

四、 读取DATA CLUSTER中存储的图片/文档
使用前述提到的IMPORT语句读取DATA CLUSTER中的图片/文档数

REPORT  z_li44_output.
CONSTANTS: cntl_true  TYPE i VALUE 1,
           cntl_false TYPE i VALUE 0.

TYPES: BEGIN OF ty_tab,
         col1 TYPE i,
         col2 TYPE i,
       END OF ty_tab.

DATA: gt_tab TYPE STANDARD TABLE OF ty_tab WITH HEADER LINE.

DATA: ok_code TYPE sy-ucomm.

DATA: graphic_url(255),
      graphic_refresh(1),
      g_result LIKE cntl_true.

DATA: h_picture       TYPE REF TO cl_gui_picture.

DATA: container1 TYPE REF TO cl_gui_custom_container,
      picture   TYPE REF TO cl_gui_picture.


START-OF-SELECTION.

  CALL SCREEN 100.

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.


  SET PF-STATUS 'T01'.
  SET TITLEBAR 'T01'.
  CREATE OBJECT: container1 EXPORTING container_name = 'C1',
                 h_picture EXPORTING parent = container1.

  TYPES pict_line(256) TYPE x.
  DATA  pict_tab TYPE TABLE OF pict_line.
  DATA  url(255) TYPE c.

  IMPORT pict_tab = pict_tab FROM DATABASE zliap04(pi) ID 'CCC'.
  CALL FUNCTION 'DP_CREATE_URL'
    EXPORTING
      type    = 'IMAGE'
      subtype = 'GIF'
    TABLES
      data    = pict_tab
    CHANGING
      url     = url.


  CALL METHOD h_picture->load_picture_from_url
    EXPORTING
      url = url.

  CALL METHOD h_picture->set_display_mode
    EXPORTING
      display_mode = h_picture->display_mode_fit_center.

ENDMODULE.                 " STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE ok_code.
    WHEN 'BACK'.
      CLEAR ok_code.
      LEAVE TO SCREEN 0.
    WHEN 'EXIT'.
      LEAVE PROGRAM.

    WHEN OTHERS.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100  

五、INPUT A CLUSTER中存储的文档
实现代码如下:

REPORT  z_li44_output_2 MESSAGE-ID demoofficeintegratio.

* this program is able to run desktop applications like Excel, Word,
* PowerPoint or WordPad either in-place (in R/3 screen) or in their own
* windows. To determine the desktop application you have to enter the
* associated "ProgId" in the entry field "Desktop application"
* for Word97: Word.Application.8
* for Excel:  Excel.Sheet.8
* for PowerPoint: PowerPoint.Slide.8

* this is the very important INCLUDE. It contains the whole ABAP
* class and interface definitions and implementations od
* SAP Desktop Office Integration. These definitions are global from
* 4.6A on, so you won't need this INCLUDE there.
INCLUDE officeintegrationinclude.

CONSTANTS: cntl_true  TYPE i VALUE 1,
           cntl_false TYPE i VALUE 0.

DATA: ok_code TYPE sy-ucomm.

DATA: control TYPE REF TO i_oi_ole_container_control,
      factory TYPE REF TO i_oi_document_factory,
      document TYPE REF TO i_oi_document_proxy,
      container TYPE REF TO cl_gui_custom_container.

* the dynpro entry fields
DATA: application(25) TYPE c VALUE 'Excel.Sheet.8',
      inplace(1) TYPE c.

DATA: stored_application LIKE application,
      initialized(1), retcode TYPE t_oi_ret_string,
      is_released TYPE i, has_changed TYPE i.

TYPES:row(1024) TYPE c.
* ABAP internal table to store documents of desktop applications
DATA: doc_table TYPE STANDARD TABLE OF row,
      doc_size TYPE i, doc_url(256).

TYPES pict_line(256) TYPE x.
DATA  pict_tab  TYPE TABLE OF pict_line.

* in ABAP you have to write an event handler class to catch events.
* This is ABAP OO technology and not SAP DOI just makes use of it to
* catch the event: "user closes desktop application by closing window "
CLASS c_event_handler DEFINITION.
  PUBLIC SECTION.
* catch the event: "user closes desktop application by closing window "
    CLASS-METHODS: close_event_handler
            FOR EVENT on_close_document OF i_oi_document_proxy
            IMPORTING document_proxy has_changed.

* for trigger this event you have to write a VB statement
* like ActiveDocument.Container.SendCustomEvent("param1", ...)
* but for now we don't support this (empty implementation)
    CLASS-METHODS: custom_event_handler
            FOR EVENT on_custom_event OF i_oi_document_proxy
            IMPORTING document_proxy event_name param_count
                      param1 param2 param3.
ENDCLASS.                    "C_EVENT_HANDLER DEFINITION
*----------------------------------------------------------------------*
*       CLASS C_EVENT_HANDLER IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS c_event_handler IMPLEMENTATION.
  METHOD close_event_handler.
    DATA: answer.
    CALL METHOD document->has_changed
      EXPORTING
        no_flush  = ' '
      IMPORTING
        retcode   = retcode
        ret_value = has_changed.

    IF has_changed = 1.
* ask user if document shoul be stored or not
      CALL FUNCTION 'POPUP_TO_CONFIRM'
        EXPORTING
          titlebar              = 'Office Integration Demo'
          text_question         = 'Save Document?'
          display_cancel_button = ' '
        IMPORTING
          answer                = answer
        EXCEPTIONS
          text_not_found        = 1
          OTHERS                = 2.
      IF answer = '1'.
* user said store it !
        PERFORM: store_document.
      ENDIF.
    ENDIF.
    PERFORM close_document.
  ENDMETHOD.                    "CLOSE_EVENT_HANDLER
  METHOD custom_event_handler.
  ENDMETHOD.                    "CUSTOM_EVENT_HANDLER
ENDCLASS.                    "c_event_handler IMPLEMENTATION



START-OF-SELECTION.

  CALL SCREEN 100.

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.


  SET PF-STATUS 'T01'.
  SET TITLEBAR 'T01'.

  IF initialized IS INITIAL.
    CALL FUNCTION 'CONTROL_INIT'
      EXCEPTIONS
        control_init_error = 1
        OTHERS             = 2.
    IF sy-subrc NE 0.
      MESSAGE e007.
    ENDIF.
    initialized = 'X'.

    CALL METHOD cl_gui_cfw=>dispatch.
* start aan application and create a new document
    PERFORM close_document.

* application in own window - factory points to i_oi_document_factory
    IF factory IS INITIAL.
      PERFORM create_application_factory.
    ENDIF.
* in-place activation - control pointing to i_oi_ole_container_control
    IF control IS INITIAL.
      PERFORM create_application_control.
    ENDIF.
* document pointing to i_oi_document:proxy interface
    PERFORM get_document_proxy USING application.
* register the event handler method for closing the document window
    SET HANDLER c_event_handler=>close_event_handler FOR document.

    IMPORT pict_tab = pict_tab FROM DATABASE zliap04(dm) ID 'AAA' IGNORING CONVERSION ERRORS.
    CALL FUNCTION 'DP_CREATE_URL'
      EXPORTING
        type    = 'application'
        subtype = 'x-oleobject'
      TABLES
        data    = pict_tab
      CHANGING
        url     = doc_url.

    IF NOT doc_url IS INITIAL.
* no open the document referenced at the frontend by doc_url
      CALL METHOD document->open_document
        EXPORTING
          document_url = doc_url
          open_inplace = inplace
        IMPORTING
          retcode      = retcode.
      CALL METHOD c_oi_errors=>show_message
        EXPORTING
          type = 'E'.

    ELSE.
      MESSAGE e001(00) WITH '读取文件失败'.
    ENDIF.
  ENDIF.


ENDMODULE.                 " STATUS_0100  OUTPUT


**&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE ok_code.
    WHEN 'BACK'.
      CLEAR ok_code.
      LEAVE TO SCREEN 0.

    WHEN 'EXIT'.
      LEAVE PROGRAM.

*    WHEN 'STORE'.
** close document and save it in ABAP table doc_table
*      PERFORM store_document.
*      stored_application = application.
*      PERFORM close_document.
*
* reopen the document stored in doc_table
    WHEN 'REOPEN'.
*      CHECK doc_size > 0.
*      PERFORM close_document.
*      PERFORM get_document_proxy USING stored_application.
** register the event handler method for closing the document window
*      SET HANDLER c_event_handler=>close_event_handler FOR document.
*      PERFORM open_document_from_table.
      MESSAGE s001(00) WITH '此功能尚未开发'.

    WHEN OTHERS.
  ENDCASE.
ENDMODULE.                 " USER_COMMAND_0100  INPUT

*---------------------------------------------------------------------*
*       FORM CREATE_APPLICATION_FACTORY                               *
*---------------------------------------------------------------------*
FORM create_application_factory.
* create an i_oi_document_factory interface instance
* in case of own application window activation referenced
* FACTORY
  CALL METHOD c_oi_factory_creator=>get_document_factory
    EXPORTING
      factory_type = 'OLE'
    IMPORTING
      factory      = factory
      retcode      = retcode.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.
  CALL METHOD factory->start_factory
    EXPORTING
      r3_application_name     = 'SAP DOI'
      register_on_close_event = 'X'
    IMPORTING
      retcode                 = retcode.
ENDFORM.                    "CREATE_APPLICATION_FACTORY
*---------------------------------------------------------------------*
*       FORM CREATE_APPLICATION_CONTROL                               *
*---------------------------------------------------------------------*
FORM create_application_control.
* create an i_oi_ole_container_control interface instance
* in case of in-place activation, referenced by CONTROL
  CALL METHOD c_oi_ole_control_creator=>get_ole_container_control
    IMPORTING
      control = control
      retcode = retcode.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.
  CREATE OBJECT container
         EXPORTING container_name = 'C1'.


  CALL METHOD control->init_control
    EXPORTING
      r3_application_name      = 'Office Demo'
      inplace_enabled          = 'X'
      inplace_scroll_documents = 'X'
      register_on_close_event  = 'X'
      parent                   = container
    IMPORTING
      retcode                  = retcode.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.

ENDFORM.                    "CREATE_APPLICATION_CONTROL
*---------------------------------------------------------------------*
*       FORM GET_DOCUMENT_PROXY                                       *
*---------------------------------------------------------------------*
*       will create a reference to the interface i_oi_document_proxy  *
*       and assign it to DOCUMENT. The document type is determined    *
*       by the APPLICATION parameter.                                 *
*---------------------------------------------------------------------*
FORM get_document_proxy USING application.
  IF inplace IS INITIAL.
    CALL METHOD factory->get_document_proxy
      EXPORTING
        document_type  = application
      IMPORTING
        document_proxy = document
        retcode        = retcode.
  ELSE.
    CALL METHOD control->get_document_proxy
      EXPORTING
        document_type  = application
      IMPORTING
        document_proxy = document
        retcode        = retcode.
  ENDIF.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.
ENDFORM.                    "GET_DOCUMENT_PROXY
*---------------------------------------------------------------------*
*       FORM CLOSE_DOCUMENT                                           *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM close_document.
  CHECK NOT document IS INITIAL.
  CALL METHOD document->close_document.
  CALL METHOD document->release_document.
  FREE document.
ENDFORM.                    "CLOSE_DOCUMENT
*---------------------------------------------------------------------*
*       FORM STORE_DOCUMENT                                           *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
FORM store_document.
  CHECK NOT document IS INITIAL.
  CALL METHOD document->is_destroyed
    IMPORTING
      ret_value = is_released.
  IF is_released IS INITIAL.
    CALL METHOD document->close_document
      EXPORTING
        do_save     = 'X'
      IMPORTING
        has_changed = has_changed.
    CALL METHOD c_oi_errors=>show_message
      EXPORTING
        type = 'E'.
    IF NOT has_changed IS INITIAL.
* document has changed, so save it into ABAP internal table
      CALL FUNCTION 'SAP_OI_GET_UNIQUE_URL'
        IMPORTING
          unique_url = doc_url
        EXCEPTIONS
          OTHERS     = 0.

      CALL METHOD document->save_document_to_table
        EXPORTING
          no_flush       = ' '
        IMPORTING
          retcode        = retcode
        CHANGING
          document_size  = doc_size
          document_table = pict_tab.
      CALL METHOD c_oi_errors=>show_message
        EXPORTING
          type = 'E'.

      CLEAR doc_url.
      CALL FUNCTION 'DP_CREATE_URL'
        EXPORTING
          type    = 'application'
          subtype = 'x-oleobject'
        TABLES
          data    = pict_tab
        CHANGING
          url     = doc_url.
      IF NOT doc_url IS INITIAL.
        EXPORT pict_tab = pict_tab TO DATABASE zliap04(dm) ID 'AAA'.
        IF sy-subrc = 0.
          MESSAGE s001(00) WITH '数据保存成功'.
        ELSE.
          MESSAGE s001(00) WITH '数据保存失败'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.
ENDFORM.                    "STORE_DOCUMENT

*---------------------------------------------------------------------*
*       FORM OPEN_DOCUMENT_FROM_TABLE                                 *
*---------------------------------------------------------------------*
*       will open a document, which is stored in the ABAP internal    *
*       table DOC_TABLE usinf the data provider (DP_CREATE_URL)       *
*       DOCUMENT points to an i_oi_document_proxy interface.          *
*---------------------------------------------------------------------*
FORM open_document_from_table.
* transport doc_table contents desktop and get back a key in doc_url
* to reference the table contents
  CALL FUNCTION 'DP_CREATE_URL'
    EXPORTING
      type                 = 'application'
      subtype              = 'x-oleobject'
      size                 = doc_size
    TABLES
      data                 = doc_table
    CHANGING
      url                  = doc_url
    EXCEPTIONS
      dp_invalid_parameter = 1
      dp_error_put_table   = 2
      dp_error_general     = 3
      OTHERS               = 4.
  CASE sy-subrc.
    WHEN 0.
    WHEN 1. RAISE dp_invalid_parameter.
    WHEN 2. RAISE dp_error_put_table.
    WHEN 3. RAISE dp_error_general.
    WHEN 4. RAISE dp_error_general.
  ENDCASE.
  IF NOT doc_url IS INITIAL.
* no open the document referenced at the frontend by doc_url
    CALL METHOD document->open_document
      EXPORTING
        document_url = doc_url
        open_inplace = inplace
      IMPORTING
        retcode      = retcode.
    CALL METHOD c_oi_errors=>show_message
      EXPORTING
        type = 'E'.
  ELSE.
    MESSAGE e001(00).
  ENDIF.
ENDFORM.                    "OPEN_DOCUMENT_FROM_TABLE

执行程序,将读取事先保存的EXCEL文档数据,更改后可以保存数据
这里写图片描述

点击EXCEL文档关闭,触发关闭事件,程序提示是否要保存文档,如果选择“是”,文档将会被重新被保存到Z_LIAP04表中,覆盖原有数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值