2023 Mar 30 8:39 AM
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.
2023 Jul 07 6:10 AM
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
2023 Jul 07 5:55 AM
Hi Lasse,
I think we have the same Problem. Do you have a solution?
Regards,
Christian
2023 Jul 07 6:10 AM
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
2023 Jul 07 8:39 AM
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!