2017 Dec 13 1:39 PM
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.
2017 Dec 13 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).
2017 Dec 14 12:13 PM
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 😞
2017 Dec 14 6: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
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 ).
2017 Dec 15 9:00 AM
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.
2017 Dec 15 12:42 PM
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).
2017 Dec 18 12:31 PM
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)
2017 Dec 18 4:01 PM
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'.
2017 Dec 19 7:50 AM
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.
2020 Jan 13 3:50 PM
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?
2020 Jan 15 3:00 PM
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.