Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

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

Former Member

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
      EXPORTING
        container_name   = p_cust_cont_name.

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

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

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

  CALL METHOD po_control->get_link_server
    IMPORTING
      link_server = po_link_server
      retcode     = l_retcode.
 
 CALL METHOD po_link_server->start_link_server [...]
ENDFORM.       " DOI_INITIALIZE


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
  EXPORTING
    item_name  = 'Z_var1'
    item_value = lv_char "some char values
  IMPORTING
    retcode    = l_retcode

ENDFORM.           " WRITE_TEXT_TO_DB

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: lt_raw TYPE STANDARD TABLE OF 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
    EXPORTING
      document_size    = l_docsize
      document_table   = lt_raw
      no_flush         = ' '
      open_inplace     = 'X'
    IMPORTING
       retcode          = l_retcode.
ENDFORM. 
10 REPLIES 10

Sandra_Rossi
Active Contributor
0 Kudos

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).

0 Kudos

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 😞

Sandra_Rossi
Active Contributor

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
      IMPORTING
        is_available = interface_available.
IF NOT interface_available IS INITIAL.
  DATA po_worddoc TYPE REF TO I_OI_WORD_PROCESSOR_DOCUMENT.
  CALL METHOD po_document->get_WORDPROCESSOR_interface
        IMPORTING
          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 ).

0 Kudos

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)

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 😮

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
DATA: ls_lngtxt LIKE LINE OF 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.
  ENDLOOP.

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

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


  CALL METHOD po_link_server->COPY_LINK_ITEM_TO_CLIPBOARD
    EXPORTING
      ITEM_NAME = 'Z_VAR1'
    IMPORTING
      retcode    = l_retcode.

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


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

"Paste to doc = Add SAP link
CALL METHOD PO_DOCUMENT->PASTE_SPECIAL
  IMPORTING
    retcode    = l_retcode.

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

0 Kudos

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.

former_member653837
Discoverer
0 Kudos

Hi Michal,

'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.'

Did you find any answer to this?

0 Kudos

Hi

It was quite long time ago, not sure I remember. But I found some piece of my code. Basicaly you need to create template without any SAP OLE Links and prepare mapping in internal table. Then open it with the program. While in debugger you need to point the place and proceed with pasting the links. Probably there is some better ay, but that is how I procceded.

Sample code for pasting links attached.

All my notes (code) regarding this subject is here 🙂

LOOP AT GT_MAP_OLE INTO LS_MAP_OLE.
 CALL METHOD   po_link_server->COPY_LINK_ITEM_TO_CLIPBOARD
  EXPORTING
    ITEM_NAME = LS_MAP_OLE-VAR
  IMPORTING
    retcode    = l_retcode.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.
CALL METHOD PO_DOCUMENT->PASTE_SPECIAL
  IMPORTING
    retcode    = l_retcode.
  CALL METHOD c_oi_errors=>show_message
    EXPORTING
      type = 'E'.
ENDLOOP.