Skip to Content

How to create WORD template (add SAP OLE Link to document)?

Dec 13, 2017 at 01:39 PM


avatar image

Hello everyone!

After quite deep searching I've reached a wall and cannot move any further :(

I know coding procedure on how to initialize DOI. Then how to add mapping for links in template, load template in RAW data and open the document with changed values. But..

Problem: How to prepare such WORD document template? Document is quite complicated and I have it already localy but without variables (SAP OLE Links, attached screen from MS WORD from SAP Demo template). So the best option would be to input in specific places localy and then upload template and save it as ITAB to RAW in SAP DB table.

SAP demo template: here

If someone would seek for procedure on how to use RAW template, change variables in it and open doc here it is (shorten version):

FORM doi_initialize  
   USING    p_cust_cont_name
   CHANGING po_control   TYPE REF TO i_oi_container_control
            po_document  TYPE REF TO i_oi_document_proxy
            po_link_server   TYPE REF TO i_oi_link_server
           po_gui_cust_container TYPE REF TO cl_gui_custom_container.

DATA: l_retcode TYPE soi_ret_string.

    CREATE OBJECT po_gui_cust_container
        container_name   = p_cust_cont_name.

    CALL METHOD c_oi_container_control_creator=>get_container_control
        control = po_control
        retcode = l_retcode.

    CALL METHOD po_control->init_control
        r3_application_name = 'File export'(010)
        inplace_enabled     = 'X'
        parent              = po_gui_cust_container
        retcode             = l_retcode.

  CALL METHOD po_control->get_document_proxy
      document_type   = soi_doctype_word_document "'Word.Document'
      document_format = soi_docformat_compound "'OLE'
      document_proxy  = po_document
      retcode         = l_retcode.

  CALL METHOD po_control->get_link_server
      link_server = po_link_server
      retcode     = l_retcode.
 CALL METHOD po_link_server->start_link_server [...]

FORM export_values2word 
   USING  p_blart
          po_link_server TYPE REF TO i_oi_link_server
          ps_flds_value TYPE zfm_res_add_data_mswordole_trg.

  DATA: l_retcode TYPE soi_ret_string.
**************variable 1 in WORD

  CALL METHOD po_link_server->add_string_item
    item_name  = 'Z_var1'
    item_value = lv_char "some char values
    retcode    = l_retcode


FORM doi_open_document
   USING  ps_all_data_hdr TYPE zfm_res_add_data_msword2_src
          po_document TYPE REF TO i_oi_document_proxy.

  DATA: l_docsize TYPE i.
  DATA: ls_raw TYPE raw255.
  DATA: ls_doc_tmpl TYPE zfm_add_doc_tmpl.
  DATA: lt_doc_tmpl TYPE STANDARD TABLE OF zfm_add_doc_tmpl.
  DATA: l_template_versi(2) TYPE c.
  DATA: l_retcode TYPE soi_ret_string.

"[....] read RAW of template from DB to lt_raw and l_docsize

  CALL METHOD po_document->open_document_from_table
      document_size    = l_docsize
      document_table   = lt_raw
      no_flush         = ' '
      open_inplace     = 'X'
       retcode          = l_retcode.
beztytułu.png (10.8 kB)
10 |10000 characters needed characters left characters exceeded
* Please Login or Register to Answer, Follow or Comment.

2 Answers

Sandra Rossi Dec 14, 2017 at 06:25 PM

So, you're missing how to use the methods of the I_OI_WORD_PROCESSOR_DOCUMENT interface. If you place "placeholder" texts (PH1, PH2, PH3, or whatever) everywhere needed in your Word Template document, then you may simply use the REPLACE method (documentation in the SAP Library). Here is the code you are missing + REPLACE + retrieve the final document :

DATA interface_available TYPE i.
CALL METHOD po_document->has_WORDPROCESSOR_interface
        is_available = interface_available.
IF NOT interface_available IS INITIAL.
  CALL METHOD po_document->get_WORDPROCESSOR_interface
          wp_interface = po_worddoc.
  po_worddoc->replace( search_string = 'PH1' replace_string = 'what you want' pos = 'global' ).
  po_document->save_document_to_table( CHANGING document_size = docsize document_table = doctable ).
Show 5 Share
10 |10000 characters needed characters left characters exceeded

Another good point and I tried it too (sorry I didn't mention :( ) . It won't work because the screen flashes with every usage of REPLACE or with NO_FLUSH it flushes in the end but the same amount of time (around 20s). The shown, opened document should be already filled with changed data.


Could you explain again what is the question then, I don't understand what you're looking for. For the blinking, you may "hide" the control or use a macro to tell Word not blinking (script collection interface) to deactivate the automatic refresh (Application.ScreenUpdating = False). For the 20s duration, sorry OLE is slow (DOI should be much faster as the OLE commands should be done once at the end when you flush). I think that using the link server is only useful for performance when one big object (image, etc.) is used several times in the document, you use methods ADD_* to send the object to the frontend + method COPY_LINK_ITEM_TO_CLIPBOARD + method PASTE_CLIPBOARD (from I_OI_DOCUMENT_PROXY).


Alright - one again to be clear :)

I have a WORD template (normal text) in doc in which I want to put variables (SAP links) to be updated with data from SAP. The best would be if you download the attachment and see those fields yourself.

Question: how to put such variables (SAP fields) in WORD template?

For now I tried to just replace custom string (e.g. I wrote <var1> and replaced it) and it has worked but it was long and flashed (it would be ok if that preparation phase would be in background and the final doc apears in the very end).

However this solution even with the flashing putted aside won't be fine, because for example I have text editors in a program from which I have to take all text and replace in template in a single variable with all ENTERs including. Example in text editor in program:
"Some text:
1. text1
2. text2"

With normal replacing it won't work, and everything will be in single line with '##' characters indicating on Enter, but won't take in account - just strings. With Link server on the other hand it just update SAP links in template including all enters -> so that it is!

Of course I am open for other solutions, but I don't see any than mentioned Link Server (XML would be also fine, but there is no such class in client's system)


As I said, the "flash" can be avoided. I think that the Link Server is optional in your case: if you want to store a value in the clipboard, you may use cl_gui_frontend_services=>clipboard_export (and paste_clipboard of the document proxy interface). I'm very surprised by the issue with the linefeed, I hope I can do some tests if I have time.

For other solutions: you may use DOCX with only CL_ABAP_ZIP. A DOCX is only a ZIP with a special structure of files. One of them contains the text and you may replace placeholders with your own text. Or you may use the old format XML2003.


hmm.... I reread your last answer and that is exactly what I needed. Just can't believe that it is such not user friendly with copying and pasting with two different classes :O

Please see some code corresponding to code in a question to prepare template which can be uploaded for example to OAOR:

"Prepare your text, e.g. READ_TEXT to GT_TLINE

CLEAR: gv_replace.
  LOOP AT GT_TLINE INTO ls_lngtxt.
    CONCATENATE gv_replace  cl_abap_char_utilities=>cr_lf ls_lngtxt-tdline INTO gv_replace.

"Add link to SAP Link Server
 CALL METHOD po_link_server->add_string_item
     item_name  = 'Z_VAR1'
     item_value = GV_REPLACE "string
      retcode    = l_retcode.

  CALL METHOD c_oi_errors=>show_message
      type = 'E'.

      ITEM_NAME = 'Z_VAR1'
      retcode    = l_retcode.

  CALL METHOD c_oi_errors=>show_message
      type = 'E'.

" here you should open your document with PO_DOCUMENT and then paste

"Paste to doc = Add SAP link
    retcode    = l_retcode.

  CALL METHOD c_oi_errors=>show_message
      type = 'E'.

Sandra Rossi Dec 13, 2017 at 10:11 PM

With transaction OAOR, you may load an Office document (or any file) in BDS. You may programmatically read a BDS file by using the class CL_BDS_DOCUMENT_SET, and then you know how to load it in DOI.

Instead of using DOI, don't you want to implement a document in DOCX format with custom XML parts. It has already been discussed in SCN (class CL_DOCX_DOCUMENT), and on the Web (custom XML parts in Microsoft Office). It may be a little bit longer as you already did some work on DOI, but it's a more recent technology (and it's faster to generate, and it works in background).

Show 1 Share
10 |10000 characters needed characters left characters exceeded

Many thanks for your reply!

I am aware of uploading template using OAOR. The problem is that I don't know how to prepare doc before uploading, so how to add variables connected to SAP OLE Link as shown on attached screenshot.

The idea of using XML might be of course the best option, I've found this conception during research however on client's server there is no such class nor the whole OpenXML class :(