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: 

Problem with function module MS_WORD_OLE_FORMLETTER for creating form letters

lassebult97
Discoverer

Hi SAP community

we currently have a problem creating form letters using the function module MS_WORD_OLE_FORMLETTER.

After an update to Office version 2301 the merge fields in our template are no longer populated. The correct amount of sites are created. It looks like this in Word:

The following error is shown:

"You cannot control Word document using the OLE automation function
Message No. LS003
Diagnosis
An error occurred in the system control of the OLE software.
Procedure
If your OLE application has already started, close all documents and then try addressing it again."

We use the FM in a Z-program but the problem can also be seen in the standard SAP report RPLMIT00 (PAR2).

We updated to Office version 2303 but the problem still occurs there. Before Version 2301 everything worked fine. We did not made any changes to the program.

Does anybody else have the same issues? We already opened a ticket at SAP but they could not help us as this an problem on Microsofts side as they say.

1 ACCEPTED SOLUTION

lassebult97
Discoverer
0 Kudos

Hi Christian,

yes, I discovered that a colleague created a Z-copy of this function module a few years ago and with that it works. I never really had the time to check what was the problem I was just happy that it worked with that one.

FUNCTION Z_MS_WORD_OLE_FORMLETTER
  IMPORTING
    VALUE(WORD_DOCUMENT) LIKE RLGRAP-FILENAME OPTIONAL
    VALUE(HIDDEN) TYPE I DEFAULT 0
    VALUE(WORD_PASSWORD) TYPE ANY OPTIONAL
    VALUE(PASSWORD_OPTION) TYPE I DEFAULT 1
    VALUE(FILE_NAME) LIKE RLGRAP-FILENAME OPTIONAL
    VALUE(NEW_DOCUMENT) TYPE ANY OPTIONAL
    VALUE(DOWNLOAD_PATH) LIKE RLGRAP-FILENAME
    VALUE(PRINT) TYPE C DEFAULT SPACE
  TABLES
    DATA_TAB TYPE STANDARD TABLE
    FIELDNAMES TYPE STANDARD TABLE
  EXCEPTIONS
    INVALID_FIELDNAMES
    USER_CANCELLED
    DOWNLOAD_PROBLEM
    COMMUNICATION_ERROR.








*** für OUTLOOK
  INCLUDE ole2incl.
  INCLUDE docsincl.


  TYPES:
    abap_bool TYPE c LENGTH 1.




  DATA: wordobj TYPE ole2_object,
        i TYPE i,
        nrows TYPE i,
        found_file LIKE rlgrap-filename,
        filename LIKE rlgrap-filename,
        path_and_file LIKE rlgrap-filename,
        string_end(1),
        user_hint(255),
        passwort(15),
        wordapp TYPE ole2_object,
        worddoc TYPE ole2_object,
        documents TYPE ole2_object,
        word_version TYPE i,
        version_str(80).


  DATA: result TYPE abap_bool,
        user_action TYPE i,
        rc TYPE i,
        file TYPE string,
        file_table TYPE filetable,
        file_table_wa TYPE LINE OF filetable,
        ntotalcols TYPE i,
        cnt TYPE i.


  FIELD-SYMBOLS: <field> TYPE ANY,
                 <data_tab_wa> TYPE ANY.


  DATA: lt_download TYPE STANDARD TABLE OF string,
        lv_download TYPE string,
        lv_hstr(1024) TYPE c.
  CONSTANTS: lc_tab TYPE string VALUE cl_abap_char_utilities=>horizontal_tab.

  DATA: reg_value TYPE string.
*  DATA: filename TYPE string.
  DATA: subrc LIKE sy-subrc.


* build up the data table ----------
* in the first first line the headers are stored
  CLEAR lv_download.
  LOOP AT fieldnames.
    WRITE fieldnames TO lv_hstr LEFT-JUSTIFIED.
    IF sy-tabix > 1.
      CONCATENATE lv_download lc_tab lv_hstr
                  INTO lv_download.
    ELSE.
      CONCATENATE lv_download lv_hstr
                  INTO lv_download.
    ENDIF.
  ENDLOOP.
  APPEND lv_download TO lt_download.


* then the data table data table
  LOOP AT data_tab
       ASSIGNING <data_tab_wa>.
    cnt = 0.
    CLEAR lv_download.
    sy-subrc = 0.
    WHILE sy-subrc = 0.
      cnt = cnt + 1.
      ASSIGN COMPONENT cnt OF STRUCTURE <data_tab_wa> TO <field>.
      CHECK sy-subrc = 0.
      WRITE <field> TO lv_hstr LEFT-JUSTIFIED.
      IF cnt > 1.
        CONCATENATE lv_download lc_tab lv_hstr
                    INTO lv_download.
      ELSE.
        CONCATENATE lv_download lv_hstr
                    INTO lv_download.
      ENDIF.
    ENDWHILE.
    APPEND lv_download TO lt_download.
  ENDLOOP.




* get number of lines in the data table
  DESCRIBE TABLE data_tab LINES nrows.
* get number of headers
  ntotalcols = cnt - 1.                                     "N630301


* check if the given word document exists
  WHILE NOT ( word_document IS INITIAL ).
    i = 0.
*   Does the File exists ?
    file = word_document.
    CALL METHOD cl_gui_frontend_services=>file_exist
      EXPORTING
        file            = file
      RECEIVING
        result          = result
      EXCEPTIONS
        cntl_error      = 1
        error_no_gui    = 2
        wrong_parameter = 3
        OTHERS          = 4.
    IF sy-subrc <> 0.
      i = 1.
    ENDIF.
    CALL METHOD cl_gui_cfw=>flush.
    IF result EQ abap_true.
      i = 1.
    ENDIF.
    IF i = 0.                          "File does´nt exists
*     only show documents with extension .doc
      CALL METHOD cl_gui_frontend_services=>file_open_dialog
        EXPORTING
*          WINDOW_TITLE            = TEXT-011  "'Word-Document'
          default_extension       = '.doc'
*          DEFAULT_FILENAME        =
          file_filter             = '*.doc'
*          INITIAL_DIRECTORY       =
          multiselection          = abap_false
        CHANGING
          file_table              = file_table
          rc                      = rc
          user_action             = user_action
        EXCEPTIONS
          file_open_dialog_failed = 1
          cntl_error              = 2
          error_no_gui            = 3
          OTHERS                  = 4.
      IF sy-subrc <> 0.
        RAISE download_problem.
      ENDIF.
      CALL METHOD cl_gui_cfw=>flush.
      IF user_action EQ cl_gui_frontend_services=>action_cancel.
        RAISE user_cancelled.
      ENDIF.
*     was a file selected?
      IF rc GT 0.
        READ TABLE file_table INTO file_table_wa INDEX 1.
        IF sy-subrc NE 0.
          RAISE download_problem.
        ENDIF.
        word_document = file_table_wa-filename.
      ELSE.
        RAISE user_cancelled.
      ENDIF.
    ELSE.                              "i = 1   File exists
      EXIT.
    ENDIF.
  ENDWHILE.


* =====================================================================
  IF file_name IS INITIAL.
* Kein Filename übergeben: Defaultfilenamen verwenden.
    filename = 'WORDFOLE'.
  ELSE.
* Angegebenen Filenamen verwenden.
    filename = file_name.
  ENDIF.
  i = STRLEN( download_path ).
  i = i - 1.
  string_end = download_path+i(1).
  IF string_end EQ '\' .
    CONCATENATE download_path filename '.DOC' INTO path_and_file.
  ELSE.
    CONCATENATE download_path '\' filename '.DOC' INTO path_and_file.
  ENDIF.


* Bereits vorhandes File WORD.DOC löschen.
  PERFORM delete_data_file USING path_and_file.
  REPLACE '.DOC' WITH '.TXT' INTO path_and_file.


* Datenfile auf PC übertragen.
  file = path_and_file.




* replace with cl_gui_frontend_services=>gui_download
* when the class is finished
  CALL FUNCTION 'GUI_DOWNLOAD'
    EXPORTING
*     BIN_FILESIZE                  =
      filename                      = file
*     FILETYPE                      = 'ASC'
*     APPEND                        = ' '
      write_field_separator         = 'X'
*     HEADER                        = '00'
      trunc_trailing_blanks         = 'X'
*      col_select                    =
*      col_select_mask               =
      codepage                      = '4110'          "note 1036562
      write_bom                     = 'X'             "note 1036562
*   IMPORTING
*     FILELENGTH                    =
    TABLES
      data_tab                      = lt_download
   EXCEPTIONS
     file_write_error              = 1
     no_batch                      = 2
     gui_refuse_filetransfer       = 3
     invalid_type                  = 4
     no_authority                  = 5
     unknown_error                 = 6
     header_not_allowed            = 7
     separator_not_allowed         = 8
     filesize_not_allowed          = 9
     header_too_long               = 10
     dp_error_create               = 11
     dp_error_send                 = 12
     dp_error_write                = 13
     unknown_dp_error              = 14
     access_denied                 = 15
     dp_out_of_memory              = 16
     disk_full                     = 17
     dp_timeout                    = 18
     file_not_found                = 19
     dataprovider_exception        = 20
     control_flush_error           = 21
     OTHERS                        = 22.
  IF sy-subrc <> 0.
    RAISE download_problem.
  ENDIF.


* Statusinformation
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
       EXPORTING
*           PERCENTAGE = 0
            text       = text-002
       EXCEPTIONS
            OTHERS     = 0.




* 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'
      value               = ''
    IMPORTING
      reg_value           = reg_value
    EXCEPTIONS
      get_regvalue_failed = 1
      cntl_error          = 2
      error_no_gui        = 3
      OTHERS              = 4.
  IF sy-subrc <> 0.
    RAISE download_problem.
  ENDIF.
  CALL METHOD cl_gui_cfw=>flush.
  version_str = reg_value.
  SHIFT version_str LEFT BY 11 PLACES.
  MOVE version_str TO word_version.


  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.
  CALL METHOD OF wordobj 'AppShow'.


* Serienbriefdatei öffnen
  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 = 1              "ReadOnly
        #04 = 1              "AddToRecentFile
        #05 = ''             "PasswordDocument
        #06 = ''             "PasswordTemplat
        #07 = 0              "Revert
        #08 = ''             "WritePasswordDocume
        #09 = ''             "WritePasswordTemplate
        #10 = 'wdOpenFormatAuto'.
*                        #11 = 1255.   "Encoding: e.g. hebrew=1255
  ELSE.
    CALL METHOD OF wordobj 'FileOpen'
      EXPORTING
      #01 = path_and_file
      #02 = 0.
  ENDIF.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




  CALL METHOD OF wordobj 'EditSelectAll'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




* Spaltenbegrenzung bei MS Word Tabellen berücksichtigen
* Word97, Word2000, Word XP: max. cols: 63
  IF ntotalcols <= 63.
    CALL METHOD OF wordobj 'TextToTable'
      EXPORTING
      #01 = '1'
      #02 = ntotalcols
      #03 = nrows.
    PERFORM error_handling_ms_word USING path_and_file sy-subrc.
  ENDIF.


  CALL METHOD OF wordobj 'ToolsOptionsSave'
    EXPORTING
    #01 = 0
    #02 = 1
    #03 = 0.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




* Paßwort für die *.DOC Datei generieren
  CASE password_option.
    WHEN 0.                             "use no Password
      CLEAR passwort.
    WHEN 1.                            "use Password
      passwort = word_password.
    WHEN 2.                             "create Password
      PERFORM create_password USING passwort.
    WHEN OTHERS.
  ENDCASE.




  REPLACE '.TXT' WITH '.DOC' INTO path_and_file.
* File mit den Serienbrieffeldern im *.DOC Format speichern
  CALL METHOD OF wordobj 'FileSaveAs'
    EXPORTING
    #01 = path_and_file
    #02 = 0
    #03 = 0
    #04 = passwort.
  IF sy-subrc <> 0.
    CALL METHOD OF wordobj 'DocClose'
      EXPORTING
      #01 = 2.
    RAISE communication_error.
  ENDIF.


  CALL METHOD OF wordobj 'FileClose'.
*  CALL METHOD OF wordobj 'DocClose'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.
  CASE hidden.
    WHEN 0.                            " Standardfiletyp
    WHEN 1.                            " Wordfile auf HIDDEN setzen
      CALL METHOD OF wordobj 'SetAttr'
        EXPORTING
        #01 = path_and_file
        #02 = 2.
    WHEN OTHERS.
  ENDCASE.


* Flush automation queue
  CALL FUNCTION 'FLUSH'
    EXCEPTIONS
      OTHERS = 0.


* Datenfile *.txt auf der Platte löschen
  REPLACE '.DOC' WITH '.TXT' INTO path_and_file.
  PERFORM delete_data_file USING path_and_file.


  REPLACE '.TXT' WITH '.DOC' INTO path_and_file.


* =====================================================================


  IF new_document IS INITIAL.
* Ggf. aktuelles Dokument verwenden oder Wordfile öffnen
    IF word_document IS INITIAL.       "word_document is empty
      CALL METHOD OF wordobj 'FileName' = found_file.
*   No document open in MS word
      IF found_file EQ space.
        CALL METHOD OF wordobj 'FileNew' .
        i = i + 1.
      ENDIF.
    ELSE.
      CALL METHOD OF wordobj 'FileOpen'
        EXPORTING
        #01 = word_document.
    ENDIF.
  ELSE.
    CALL METHOD OF wordobj 'FileNew' .
    i = i + 1.
  ENDIF.


* Serienbrieffelder herstellen
*  IF word_document EQ space AND found_file EQ space.
*    user_hint = text-001.
*    CALL METHOD OF wordobj 'Insert'
*      EXPORTING
*      #01 = user_hint.
*    PERFORM error_handling_ms_word USING path_and_file sy-subrc.
*  ENDIF.


********************
  CALL METHOD OF wordobj 'MailMergeOpenDataSource'
    EXPORTING
    #01 = path_and_file
    #02 = 0
    #03 = 1
    #04 = 0
    #05 = 0
    #06 = passwort.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




  CALL METHOD OF wordobj 'MailMergeEditMainDocument'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.


**  CALL METHOD OF wordobj 'PREVWINDOW'.
  CALL METHOD OF wordobj 'MailMergeToDoc'.


  CALL METHOD OF wordobj 'MAILMERGERESET'.


  CALL METHOD OF wordobj 'EDITGOTO' EXPORTING #1 = 'HERE'.


* Close the Doc and do not ask for saving!!!
  CALL METHOD OF wordobj 'FILECLOSE' EXPORTING #1 = '2'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.
***********************


* after free object word will close
* free object wordobj.
* Flush automation queue
  CALL FUNCTION 'FLUSH'
    EXCEPTIONS
      OTHERS = 0.


ENDFUNCTION.


****************************************************************************************************

FORM create_password USING passwort.


  DATA: faktor TYPE f, produkt TYPE i, password(65).
  DATA: c1.
  DATA: istrlen TYPE i, varctemp(55), varctemp1(55) ,i TYPE i,i2 TYPE i.
  DATA: hex(4) TYPE x.
  DATA: abc LIKE sy-abcde.




  abc = sy-abcde.
  GET RUN TIME FIELD varctemp.
  DO 3 TIMES.
    istrlen = STRLEN( sy-uname ).
    GET TIME.
    MOVE sy-uzeit+5(1) TO i.
    i = i + 1.
    GET RUN TIME FIELD varctemp.
    MOVE varctemp TO faktor.
    IF faktor < 0.
      faktor = ( faktor * ( -1 ) ).
      varctemp = faktor.
      faktor = 0.
    ENDIF.
    i2 = STRLEN( varctemp ).
    i2 = i2 - 1.
    MOVE varctemp+i2(1) TO i2.
    i2 = i2 + 1.
    i2 = i2 + i.
    MOVE abc+i2(1) TO c1.
    SHIFT abc CIRCULAR RIGHT.
    GET RUN TIME FIELD faktor.
    WHILE faktor > 1000.
      faktor = faktor / 10.
    ENDWHILE.
    produkt = istrlen * faktor.
    MOVE produkt TO hex.
    MOVE hex+2(2) TO varctemp1.
    CONCATENATE password c1 varctemp1 INTO password.
  ENDDO.


  passwort = password+0(12).


ENDFORM.                    "create_password




*&---------------------------------------------------------------------*
*&      Form  delete_data_file
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PATH_AND_FILE  text
*----------------------------------------------------------------------*
FORM delete_data_file USING path_and_file.
  DATA: fname TYPE string.
  DATA: filename LIKE rlgrap-filename.
  DATA: rc TYPE i.


  fname = filename.


* delete the file
  CALL METHOD cl_gui_frontend_services=>file_delete
    EXPORTING
      filename = fname
    CHANGING
      rc       = rc
    EXCEPTIONS
      OTHERS   = 0.


* flush to execute the deletion
  CALL METHOD cl_gui_cfw=>flush.


*  DATA: MY_SUBRC LIKE SY-SUBRC.
*
*  CALL FUNCTION 'WS_FILE_DELETE'
*       EXPORTING
*            FILE    = FILENAME
*       IMPORTING
*            RETURN  = MY_SUBRC
*       EXCEPTIONS
*            OTHERS  = 1.
*
*    IF SY-SUBRC <> 0 AND MY_SUBRC <> 0.
*    ENDIF.




ENDFORM.                    "delete_data_file




*&---------------------------------------------------------------------*
*&      Form  error_handling_ms_word
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PATH_AND_FILE  text
*      -->SY-SUBRC       text
*----------------------------------------------------------------------*
FORM error_handling_ms_word USING path_and_file sy-subrc.


  DATA: subrc LIKE syst-subrc.
  DATA: filename LIKE rlgrap-filename.


  CASE subrc.
    WHEN 0.                            "everthing is OK
      EXIT.
    WHEN OTHERS.                       "An error has occured
      PERFORM delete_data_file USING filename.
      RAISE communication_error.
  ENDCASE.


ENDFORM.                    "error_handling_ms_word



3 REPLIES 3

0 Kudos

Hi Lasse,

I think we have the same Problem. Do you have a solution?

Regards,

Christian

lassebult97
Discoverer
0 Kudos

Hi Christian,

yes, I discovered that a colleague created a Z-copy of this function module a few years ago and with that it works. I never really had the time to check what was the problem I was just happy that it worked with that one.

FUNCTION Z_MS_WORD_OLE_FORMLETTER
  IMPORTING
    VALUE(WORD_DOCUMENT) LIKE RLGRAP-FILENAME OPTIONAL
    VALUE(HIDDEN) TYPE I DEFAULT 0
    VALUE(WORD_PASSWORD) TYPE ANY OPTIONAL
    VALUE(PASSWORD_OPTION) TYPE I DEFAULT 1
    VALUE(FILE_NAME) LIKE RLGRAP-FILENAME OPTIONAL
    VALUE(NEW_DOCUMENT) TYPE ANY OPTIONAL
    VALUE(DOWNLOAD_PATH) LIKE RLGRAP-FILENAME
    VALUE(PRINT) TYPE C DEFAULT SPACE
  TABLES
    DATA_TAB TYPE STANDARD TABLE
    FIELDNAMES TYPE STANDARD TABLE
  EXCEPTIONS
    INVALID_FIELDNAMES
    USER_CANCELLED
    DOWNLOAD_PROBLEM
    COMMUNICATION_ERROR.








*** für OUTLOOK
  INCLUDE ole2incl.
  INCLUDE docsincl.


  TYPES:
    abap_bool TYPE c LENGTH 1.




  DATA: wordobj TYPE ole2_object,
        i TYPE i,
        nrows TYPE i,
        found_file LIKE rlgrap-filename,
        filename LIKE rlgrap-filename,
        path_and_file LIKE rlgrap-filename,
        string_end(1),
        user_hint(255),
        passwort(15),
        wordapp TYPE ole2_object,
        worddoc TYPE ole2_object,
        documents TYPE ole2_object,
        word_version TYPE i,
        version_str(80).


  DATA: result TYPE abap_bool,
        user_action TYPE i,
        rc TYPE i,
        file TYPE string,
        file_table TYPE filetable,
        file_table_wa TYPE LINE OF filetable,
        ntotalcols TYPE i,
        cnt TYPE i.


  FIELD-SYMBOLS: <field> TYPE ANY,
                 <data_tab_wa> TYPE ANY.


  DATA: lt_download TYPE STANDARD TABLE OF string,
        lv_download TYPE string,
        lv_hstr(1024) TYPE c.
  CONSTANTS: lc_tab TYPE string VALUE cl_abap_char_utilities=>horizontal_tab.

  DATA: reg_value TYPE string.
*  DATA: filename TYPE string.
  DATA: subrc LIKE sy-subrc.


* build up the data table ----------
* in the first first line the headers are stored
  CLEAR lv_download.
  LOOP AT fieldnames.
    WRITE fieldnames TO lv_hstr LEFT-JUSTIFIED.
    IF sy-tabix > 1.
      CONCATENATE lv_download lc_tab lv_hstr
                  INTO lv_download.
    ELSE.
      CONCATENATE lv_download lv_hstr
                  INTO lv_download.
    ENDIF.
  ENDLOOP.
  APPEND lv_download TO lt_download.


* then the data table data table
  LOOP AT data_tab
       ASSIGNING <data_tab_wa>.
    cnt = 0.
    CLEAR lv_download.
    sy-subrc = 0.
    WHILE sy-subrc = 0.
      cnt = cnt + 1.
      ASSIGN COMPONENT cnt OF STRUCTURE <data_tab_wa> TO <field>.
      CHECK sy-subrc = 0.
      WRITE <field> TO lv_hstr LEFT-JUSTIFIED.
      IF cnt > 1.
        CONCATENATE lv_download lc_tab lv_hstr
                    INTO lv_download.
      ELSE.
        CONCATENATE lv_download lv_hstr
                    INTO lv_download.
      ENDIF.
    ENDWHILE.
    APPEND lv_download TO lt_download.
  ENDLOOP.




* get number of lines in the data table
  DESCRIBE TABLE data_tab LINES nrows.
* get number of headers
  ntotalcols = cnt - 1.                                     "N630301


* check if the given word document exists
  WHILE NOT ( word_document IS INITIAL ).
    i = 0.
*   Does the File exists ?
    file = word_document.
    CALL METHOD cl_gui_frontend_services=>file_exist
      EXPORTING
        file            = file
      RECEIVING
        result          = result
      EXCEPTIONS
        cntl_error      = 1
        error_no_gui    = 2
        wrong_parameter = 3
        OTHERS          = 4.
    IF sy-subrc <> 0.
      i = 1.
    ENDIF.
    CALL METHOD cl_gui_cfw=>flush.
    IF result EQ abap_true.
      i = 1.
    ENDIF.
    IF i = 0.                          "File does´nt exists
*     only show documents with extension .doc
      CALL METHOD cl_gui_frontend_services=>file_open_dialog
        EXPORTING
*          WINDOW_TITLE            = TEXT-011  "'Word-Document'
          default_extension       = '.doc'
*          DEFAULT_FILENAME        =
          file_filter             = '*.doc'
*          INITIAL_DIRECTORY       =
          multiselection          = abap_false
        CHANGING
          file_table              = file_table
          rc                      = rc
          user_action             = user_action
        EXCEPTIONS
          file_open_dialog_failed = 1
          cntl_error              = 2
          error_no_gui            = 3
          OTHERS                  = 4.
      IF sy-subrc <> 0.
        RAISE download_problem.
      ENDIF.
      CALL METHOD cl_gui_cfw=>flush.
      IF user_action EQ cl_gui_frontend_services=>action_cancel.
        RAISE user_cancelled.
      ENDIF.
*     was a file selected?
      IF rc GT 0.
        READ TABLE file_table INTO file_table_wa INDEX 1.
        IF sy-subrc NE 0.
          RAISE download_problem.
        ENDIF.
        word_document = file_table_wa-filename.
      ELSE.
        RAISE user_cancelled.
      ENDIF.
    ELSE.                              "i = 1   File exists
      EXIT.
    ENDIF.
  ENDWHILE.


* =====================================================================
  IF file_name IS INITIAL.
* Kein Filename übergeben: Defaultfilenamen verwenden.
    filename = 'WORDFOLE'.
  ELSE.
* Angegebenen Filenamen verwenden.
    filename = file_name.
  ENDIF.
  i = STRLEN( download_path ).
  i = i - 1.
  string_end = download_path+i(1).
  IF string_end EQ '\' .
    CONCATENATE download_path filename '.DOC' INTO path_and_file.
  ELSE.
    CONCATENATE download_path '\' filename '.DOC' INTO path_and_file.
  ENDIF.


* Bereits vorhandes File WORD.DOC löschen.
  PERFORM delete_data_file USING path_and_file.
  REPLACE '.DOC' WITH '.TXT' INTO path_and_file.


* Datenfile auf PC übertragen.
  file = path_and_file.




* replace with cl_gui_frontend_services=>gui_download
* when the class is finished
  CALL FUNCTION 'GUI_DOWNLOAD'
    EXPORTING
*     BIN_FILESIZE                  =
      filename                      = file
*     FILETYPE                      = 'ASC'
*     APPEND                        = ' '
      write_field_separator         = 'X'
*     HEADER                        = '00'
      trunc_trailing_blanks         = 'X'
*      col_select                    =
*      col_select_mask               =
      codepage                      = '4110'          "note 1036562
      write_bom                     = 'X'             "note 1036562
*   IMPORTING
*     FILELENGTH                    =
    TABLES
      data_tab                      = lt_download
   EXCEPTIONS
     file_write_error              = 1
     no_batch                      = 2
     gui_refuse_filetransfer       = 3
     invalid_type                  = 4
     no_authority                  = 5
     unknown_error                 = 6
     header_not_allowed            = 7
     separator_not_allowed         = 8
     filesize_not_allowed          = 9
     header_too_long               = 10
     dp_error_create               = 11
     dp_error_send                 = 12
     dp_error_write                = 13
     unknown_dp_error              = 14
     access_denied                 = 15
     dp_out_of_memory              = 16
     disk_full                     = 17
     dp_timeout                    = 18
     file_not_found                = 19
     dataprovider_exception        = 20
     control_flush_error           = 21
     OTHERS                        = 22.
  IF sy-subrc <> 0.
    RAISE download_problem.
  ENDIF.


* Statusinformation
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
       EXPORTING
*           PERCENTAGE = 0
            text       = text-002
       EXCEPTIONS
            OTHERS     = 0.




* 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'
      value               = ''
    IMPORTING
      reg_value           = reg_value
    EXCEPTIONS
      get_regvalue_failed = 1
      cntl_error          = 2
      error_no_gui        = 3
      OTHERS              = 4.
  IF sy-subrc <> 0.
    RAISE download_problem.
  ENDIF.
  CALL METHOD cl_gui_cfw=>flush.
  version_str = reg_value.
  SHIFT version_str LEFT BY 11 PLACES.
  MOVE version_str TO word_version.


  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.
  CALL METHOD OF wordobj 'AppShow'.


* Serienbriefdatei öffnen
  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 = 1              "ReadOnly
        #04 = 1              "AddToRecentFile
        #05 = ''             "PasswordDocument
        #06 = ''             "PasswordTemplat
        #07 = 0              "Revert
        #08 = ''             "WritePasswordDocume
        #09 = ''             "WritePasswordTemplate
        #10 = 'wdOpenFormatAuto'.
*                        #11 = 1255.   "Encoding: e.g. hebrew=1255
  ELSE.
    CALL METHOD OF wordobj 'FileOpen'
      EXPORTING
      #01 = path_and_file
      #02 = 0.
  ENDIF.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




  CALL METHOD OF wordobj 'EditSelectAll'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




* Spaltenbegrenzung bei MS Word Tabellen berücksichtigen
* Word97, Word2000, Word XP: max. cols: 63
  IF ntotalcols <= 63.
    CALL METHOD OF wordobj 'TextToTable'
      EXPORTING
      #01 = '1'
      #02 = ntotalcols
      #03 = nrows.
    PERFORM error_handling_ms_word USING path_and_file sy-subrc.
  ENDIF.


  CALL METHOD OF wordobj 'ToolsOptionsSave'
    EXPORTING
    #01 = 0
    #02 = 1
    #03 = 0.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




* Paßwort für die *.DOC Datei generieren
  CASE password_option.
    WHEN 0.                             "use no Password
      CLEAR passwort.
    WHEN 1.                            "use Password
      passwort = word_password.
    WHEN 2.                             "create Password
      PERFORM create_password USING passwort.
    WHEN OTHERS.
  ENDCASE.




  REPLACE '.TXT' WITH '.DOC' INTO path_and_file.
* File mit den Serienbrieffeldern im *.DOC Format speichern
  CALL METHOD OF wordobj 'FileSaveAs'
    EXPORTING
    #01 = path_and_file
    #02 = 0
    #03 = 0
    #04 = passwort.
  IF sy-subrc <> 0.
    CALL METHOD OF wordobj 'DocClose'
      EXPORTING
      #01 = 2.
    RAISE communication_error.
  ENDIF.


  CALL METHOD OF wordobj 'FileClose'.
*  CALL METHOD OF wordobj 'DocClose'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.
  CASE hidden.
    WHEN 0.                            " Standardfiletyp
    WHEN 1.                            " Wordfile auf HIDDEN setzen
      CALL METHOD OF wordobj 'SetAttr'
        EXPORTING
        #01 = path_and_file
        #02 = 2.
    WHEN OTHERS.
  ENDCASE.


* Flush automation queue
  CALL FUNCTION 'FLUSH'
    EXCEPTIONS
      OTHERS = 0.


* Datenfile *.txt auf der Platte löschen
  REPLACE '.DOC' WITH '.TXT' INTO path_and_file.
  PERFORM delete_data_file USING path_and_file.


  REPLACE '.TXT' WITH '.DOC' INTO path_and_file.


* =====================================================================


  IF new_document IS INITIAL.
* Ggf. aktuelles Dokument verwenden oder Wordfile öffnen
    IF word_document IS INITIAL.       "word_document is empty
      CALL METHOD OF wordobj 'FileName' = found_file.
*   No document open in MS word
      IF found_file EQ space.
        CALL METHOD OF wordobj 'FileNew' .
        i = i + 1.
      ENDIF.
    ELSE.
      CALL METHOD OF wordobj 'FileOpen'
        EXPORTING
        #01 = word_document.
    ENDIF.
  ELSE.
    CALL METHOD OF wordobj 'FileNew' .
    i = i + 1.
  ENDIF.


* Serienbrieffelder herstellen
*  IF word_document EQ space AND found_file EQ space.
*    user_hint = text-001.
*    CALL METHOD OF wordobj 'Insert'
*      EXPORTING
*      #01 = user_hint.
*    PERFORM error_handling_ms_word USING path_and_file sy-subrc.
*  ENDIF.


********************
  CALL METHOD OF wordobj 'MailMergeOpenDataSource'
    EXPORTING
    #01 = path_and_file
    #02 = 0
    #03 = 1
    #04 = 0
    #05 = 0
    #06 = passwort.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.




  CALL METHOD OF wordobj 'MailMergeEditMainDocument'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.


**  CALL METHOD OF wordobj 'PREVWINDOW'.
  CALL METHOD OF wordobj 'MailMergeToDoc'.


  CALL METHOD OF wordobj 'MAILMERGERESET'.


  CALL METHOD OF wordobj 'EDITGOTO' EXPORTING #1 = 'HERE'.


* Close the Doc and do not ask for saving!!!
  CALL METHOD OF wordobj 'FILECLOSE' EXPORTING #1 = '2'.
  PERFORM error_handling_ms_word USING path_and_file sy-subrc.
***********************


* after free object word will close
* free object wordobj.
* Flush automation queue
  CALL FUNCTION 'FLUSH'
    EXCEPTIONS
      OTHERS = 0.


ENDFUNCTION.


****************************************************************************************************

FORM create_password USING passwort.


  DATA: faktor TYPE f, produkt TYPE i, password(65).
  DATA: c1.
  DATA: istrlen TYPE i, varctemp(55), varctemp1(55) ,i TYPE i,i2 TYPE i.
  DATA: hex(4) TYPE x.
  DATA: abc LIKE sy-abcde.




  abc = sy-abcde.
  GET RUN TIME FIELD varctemp.
  DO 3 TIMES.
    istrlen = STRLEN( sy-uname ).
    GET TIME.
    MOVE sy-uzeit+5(1) TO i.
    i = i + 1.
    GET RUN TIME FIELD varctemp.
    MOVE varctemp TO faktor.
    IF faktor < 0.
      faktor = ( faktor * ( -1 ) ).
      varctemp = faktor.
      faktor = 0.
    ENDIF.
    i2 = STRLEN( varctemp ).
    i2 = i2 - 1.
    MOVE varctemp+i2(1) TO i2.
    i2 = i2 + 1.
    i2 = i2 + i.
    MOVE abc+i2(1) TO c1.
    SHIFT abc CIRCULAR RIGHT.
    GET RUN TIME FIELD faktor.
    WHILE faktor > 1000.
      faktor = faktor / 10.
    ENDWHILE.
    produkt = istrlen * faktor.
    MOVE produkt TO hex.
    MOVE hex+2(2) TO varctemp1.
    CONCATENATE password c1 varctemp1 INTO password.
  ENDDO.


  passwort = password+0(12).


ENDFORM.                    "create_password




*&---------------------------------------------------------------------*
*&      Form  delete_data_file
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PATH_AND_FILE  text
*----------------------------------------------------------------------*
FORM delete_data_file USING path_and_file.
  DATA: fname TYPE string.
  DATA: filename LIKE rlgrap-filename.
  DATA: rc TYPE i.


  fname = filename.


* delete the file
  CALL METHOD cl_gui_frontend_services=>file_delete
    EXPORTING
      filename = fname
    CHANGING
      rc       = rc
    EXCEPTIONS
      OTHERS   = 0.


* flush to execute the deletion
  CALL METHOD cl_gui_cfw=>flush.


*  DATA: MY_SUBRC LIKE SY-SUBRC.
*
*  CALL FUNCTION 'WS_FILE_DELETE'
*       EXPORTING
*            FILE    = FILENAME
*       IMPORTING
*            RETURN  = MY_SUBRC
*       EXCEPTIONS
*            OTHERS  = 1.
*
*    IF SY-SUBRC <> 0 AND MY_SUBRC <> 0.
*    ENDIF.




ENDFORM.                    "delete_data_file




*&---------------------------------------------------------------------*
*&      Form  error_handling_ms_word
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PATH_AND_FILE  text
*      -->SY-SUBRC       text
*----------------------------------------------------------------------*
FORM error_handling_ms_word USING path_and_file sy-subrc.


  DATA: subrc LIKE syst-subrc.
  DATA: filename LIKE rlgrap-filename.


  CASE subrc.
    WHEN 0.                            "everthing is OK
      EXIT.
    WHEN OTHERS.                       "An error has occured
      PERFORM delete_data_file USING filename.
      RAISE communication_error.
  ENDCASE.


ENDFORM.                    "error_handling_ms_word



Sandra_Rossi
Active Contributor
0 Kudos

Hi lassebult97, thanks for the feedback, could you convert your comment into an answer and accept it, so that to make it even more visible to the community? Thank you!