Copyright 2022 - BV TallVision IT

Would you like to Start Word with template and data ? SAP can be linked to Office products using OLE, Object Link Enabling, which can be useful in a business situation. This article introduces a read-to-use and all standard SAP function module which allows you to start Word, pass data and open a Word template (.dotx) for the data. Use it to talk to Office Word in a preset way, or use it as a reference on how to interact with Office for other applications (Excel ?).

The function module that is highlighted in this article is used by standard SAP when a "download to Wordprocessing" is selected as a download method. So e.g. transaction SE16n will run through these steps....

Start Word with a template

To demonstrate how OLE functionality works, follow these preperation steps:

  1. Find (or create) a template in Word, e.g. SAPmatters.dotx - refer to Word documentation on how this is done. Make sure you add a few fields that can be filled in (supplied) from SAP side
  2. Create an Abap report that has an internally defined structure definition (no need to use an actual DDIC structure) with the fields you want to pass on to Word. Note that the number of fields on the structure needs to be the number of fields that are supplied to the function module (this becomes an issue in Office 2013, not relevant in Office 2010).
  3. Now add the function module call to MS_WORD_OLE_FORMLETTER (which is the same as WORD_OLE_FORMLETTER) and follow the example setup below.
        CALL FUNCTION 'WORD_OLE_FORMLETTER'
          EXPORTING
            word_document = lv_word_template_document
            download_path = lv_word_data_directory
            file_name     = lv_word_data_filename
          TABLES
            data_tab      = lt_data 
            fieldnames    = lt_fieldnames
          EXCEPTIONS
            OTHERS        = 4.
    

    These are OLE specific too:
    GET PROPERTY OF
    SET PROPERTY OF
    ....

  4. The setup needs a data file (lv_word_data_directory) to be placed on the frontend (PC) somewhere, for which the function module will take a default path (lv_word_data_directory). Note that files with data are created and remain on the path .
  5. If all is correct, Word will open, a screen is shown with the data fields showing as columns (running from top to bottom, Chinese-style) and the .dotx template content (lv_word_template_document) is shown. With a preview function, the template will be filled with data.
  6. The definition of the lt_data and the lt_fieldnames are up to you. The lt_data table holds the fields you want to supply to the template as columns on the table (most common use is address data, so the template is called with a list of addresses). The lt_fieldnames table lists the columns from lt_data as simple descriptions. The number of columns on the data table and the lines on fieldnames should match. lt_fieldnames can be defined as lt_fieldnames TYPE STANDARD TABLE OF char40.

Have a look "under the hood"

If you are using this example to learn more about OLE, this is your article. Function module MS_WORD_OLE_FORMLETTER performs quite a few steps and the steps demonstrate how to "talk OLE".

This is what the module does:

  1. Compose a file (.txt) with the data. The first line of the file contains field names, separated by a TAB. The other lines of the file contain actual data, also separated by a TAB.
    * when the class is finished
      CALL FUNCTION 'GUI_DOWNLOAD'
        EXPORTING
    
  2. The Word version is determined, which is what starts OLE automation
    * Start with OLE automation
      CALL METHOD cl_gui_frontend_services=>registry_get_value
        EXPORTING
          root                = cl_gui_frontend_services=>hkey_classes_root
          key                 = 'Word.Basic\CurVer'
    
  3. The Word object is instantiated {objects WORDDOC, WORDAPP and WORDOBJ}
      IF word_version < 8.
        CREATE OBJECT wordobj 'Word.Basic'.
      ELSE.
        CREATE OBJECT worddoc 'Word.Document'.
        GET PROPERTY OF worddoc 'Application' = wordapp.
        SET PROPERTY OF wordapp 'Visible' = 1.
        GET PROPERTY OF wordapp 'WordBasic' = wordobj.
        CALL METHOD OF wordobj 'FileClose'.
      ENDIF.
    
    At this point, it may be worth while checking WORDDOC-HANDLE and checking the contents of the WORDAPP and WORDOBJ fields. If these are not filled in, the system is in trouble.
  4. Word is started wiht an instruction to show itself.
     
      CALL METHOD OF wordobj 'AppShow'.
    
  5. The .txt file containing template data is opened
     
      if word_version > 8.
        get property of wordapp 'Documents' = documents.
    
        call method of documents 'Open'
          exporting
            #01 = path_and_file  "file name
            #02 = 0              "confirm conversion
            #03 = 0              "ReadOnly               
            #04 = 1              "AddToRecentFile
            #05 = ''             "PasswordDocument
            #06 = ''             "PasswordTemplat
            #07 = 0              "Revert
            #08 = ''             "WritePasswordDocume
            #09 = ''             "WritePasswordTemplate
            #10 = 'wdOpenFormatAuto'.
      else.
        call method of wordobj 'FileOpen'
          exporting
            #01 = path_and_file
            #02 = 0.
      endif.
    
  6. The content is displayed and all text is selected
    call method of wordobj 'EditSelectAll'.
    
  7. Word function "Text to table" (TextToTable) is called, transforming the selected data into the format required for templates
        call method of wordobj 'TextToTable'
          exporting
            #01 = '1'
            #02 = ntotalcols
            #03 = nrows.
    
  8. The result is saved as a .doc file
      call method of wordobj 'FileSaveAs'
        exporting
          #01 = path_and_file
          #02 = 0
          #03 = 0
          #04 = passwort.
    
  9. Document and file are closed
      if sy-subrc <> 0.
        call method of wordobj 'DocClose'
          exporting
            #01 = 2.
        raise communication_error.
      endif.
    
      call method of wordobj 'FileClose'.
    
  10. Regular Abap logic now removes the .txt file, which has been converted to a .doc data file by Word

With these preparation steps in place, the actual Word template document can be started. Actions like MailMergeOpenDataSource and MailMergeEditMainDocument complete the tast of this module.

Special statements for OLE

Have you noticed this: CREATE OBJECT for a variabele of type OLE2_OBJECT (which is in fact a structure) ? Or CALL METHOD OF ? Looks a bit strange ? These are dedicated statements that SAP has made available for OLE processing. Parameters are passed as numbers, rather than names.

    call method of documents 'Open'
      exporting
        #01 = path_and_file  "file name
        #02 = 0              "confirm conversion
        #03 = 0              "ReadOnly               
        #04 = 1              "AddToRecentFile
        #05 = ''             "PasswordDocument
        #06 = ''             "PasswordTemplat
        #07 = 0              "Revert
        #08 = ''             "WritePasswordDocume
        #09 = ''             "WritePasswordTemplate
        #10 = 'wdOpenFormatAuto'.

The Word example - know issues

For HR implementations, there are quite a few implementations of the function module MS_WORD_OLE_FORMLETTER which needed to be revisited after Word upgrades.

  • Flexible data structure - the module was used for an implementation where the actual data that is passed to the module originated from a Query. Hence the actual number of fields was not set and the number of fields on the lt_data table was set to a maximum of 50 fields (thus the lt_data structure had 50 fields). From Office 2013 onwards, the number of columns on the data structure and the number of columns defined in the field list (lt_fieldnames) needed to be an exact match.
  • After an upgrade the Word screen showed the data that was selected in SAP, with column names and all of it was selected. The process made it to the point where selected information was to be transformed through "TextToTable". This didn't work however, because the document was opened in read-only mode. This was resolved by applying a change to the standard SAP module, where it opened the document: CALL METHOD OF documents 'Open'. The #3 parameter was set to "0", which resolved the issue.
  • OSS notes on this topic: 1036562(2007), 0630301(2008), 1888226(2016)