前言
最近遇到这样一个需求,需要对BW服务器上的文件进行下载的同时写入每个用户相对应的数据。之前的服务器模版是一个死模版,对于这样的要求,我就想到了OLE技术,那么什么是OLE技术呢?
一、什么是OLE技术?
我在Kimi上问了这样一个问题,它的回答看起来还挺专业的,如下:
简单的说,基于 OLE 的 ABAP 代码操作 Excel 依赖于Excel 应用程序。通过调用 COM 对象,ABAP 能够控制 Excel,实现对 Excel 文件的读写操作。这就要求客户端计算机上安装有Excel。
当ABAP使用这种代码操作Excel时:
此时查看操作系统的进程列表,会发现后台悄悄起了一个 Excel.exe 进程,参数为 /automation -Embedding. 这个参数表明 Excel 正在以一种特殊模式运行,用于支持 OLE 自动化和嵌入功能。这种模式允许其他应用程序通过编程方式控制 Excel,比如本文以 ABAP为例,而不需要用户直接与 Excel 的图形用户界面交互。
/automation
参数指示 Excel 以自动化模式启动。这意味着 Excel 将不显示其图形用户界面,而是在后台运行,等待来自 ABAP 应用程序的命令。这对于需要从其他应用程序自动读取或写入 Excel 文件的场景特别有用。
-Embedding
参数则与 OLE技术的嵌入功能有关。当 Excel 程序以此参数运行时,它作为一个服务器,可以处理来自客户端应用程序的嵌入请求。这些嵌入的对象请求将保留 Excel 的功能,如公式计算和数据分析。
通过编程方式控制以 /automation -Embedding
模式运行的 Excel,应用程序可以使用第三方编程语言,创建、填充并格式化 Excel 工作簿,无需用户手动操作。
二、服务器文件上传
SAP或者BW的服务器文件一般是通过T-code-SMW0去实现上载的,如图:
选择二进制数据,然后选择对应的开发包:
可以选择新建文件,将自己本地的模版文件上传即可,也可对现有的模版的进行更换,选择文件右键导入即可
三、ABAP程序下载与读写
前置条件准备好后,这个时候就可以通过程序进行下载模版文件了,代码如下:
CONCATENATE sy-datum "按照当前日期格式进行文件名生成
'_'
sy-uzeit
'_'
lv_filename
INTO lv_filename.
CALL METHOD cl_gui_frontend_services=>file_save_dialog
EXPORTING
default_extension = lv_extension
default_file_name = lv_filename
initial_directory = lv_path
CHANGING
filename = lv_filename
path = lv_path
fullpath = lv_fullpath
user_action = lv_user_action
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
OTHERS = 4.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ELSE.
CLEAR: lv_destination.
lv_destination = lv_fullpath. "用户选择本地存放的文件路径
ENDIF.
CHECK lv_user_action <> 9.
SELECT SINGLE relid objid
FROM wwwdata
INTO CORRESPONDING FIELDS OF ls_objdata
WHERE srtf2 = 0
AND objid = lv_objid
AND relid = 'MI'.
CLEAR: lv_rc.
CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
EXPORTING
key = ls_objdata
destination = lv_destination "下载的文件路径
IMPORTING
rc = lv_rc.
这个时候通过代码将文件下载到用户的本地文件目录上去,接下来是重头戏,下面代码需要通过OLE技术操作Excel数据,将ABAP内表数据自定义的写到文件中:
第一步:定义对应的对象:
DATA: lv_filename TYPE string,
lv_path TYPE string,
lv_fullpath TYPE string,
lv_user_action TYPE i,
lv_destination LIKE rlgrap-filename,
ls_objdata LIKE wwwdatatab,
lv_objid TYPE wwwdatatab-objid,
lv_rc TYPE sy-subrc,
lv_extension TYPE string,
excel_obj TYPE ole2_object,
book_obj TYPE ole2_object,
sheet TYPE ole2_object。
第二步:创建对应的对象:
" 创建EXCEL对象
CREATE OBJECT excel_obj 'EXCEL.APPLICATION'.
IF sy-subrc NE 0.
MESSAGE 'EXCEL创建错误' TYPE 'S' DISPLAY LIKE 'E'.
STOP.
ENDIF.
"设置EXCEL是否后台打开
SET PROPERTY OF excel_obj 'VISIBLE' = 0.
SET PROPERTY OF excel_obj 'DISPLAYALERTS' = 0.
CALL METHOD OF excel_obj 'WORKBOOKS' = book_obj.
"打开刚刚生成的文件
CALL METHOD OF book_obj 'Open'
EXPORTING
#1 = lv_destination
第三步:打开对应的Sheet页签:
GET PROPERTY OF excel_obj 'ACTIVECELL' = sheet.
"页签名字
CALL METHOD OF excel_obj 'Worksheets' = sheet
EXPORTING
#1 = 'Project'.
CALL METHOD OF sheet 'select'.
CALL METHOD OF sheet 'ACTIVATE'.
第四步:取出需要填充的数据:
LOOP AT lt_mk01 INTO DATA(ls_mk01).
ls_line-project = ls_mk01-id && '-' && ls_mk01-desc.
ls_line-xmattr = ls_mk01-xmattr.
ls_line-xmfzr = ls_mk01-xmfzr.
ls_line-xmyear = ls_mk01-xmyear.
APPEND ls_line TO lt_line.
ENDLOOP
第五步:将数据写到Excel:
IF lt_line IS NOT INITIAL.
LOOP AT lt_line INTO ls_line.
lv_num = sy-tabix + 1.
PERFORM fill_cell USING lv_num 1 0 ls_line-project excel_obj.
PERFORM fill_cell USING lv_num 2 0 ls_line-xmattr excel_obj.
PERFORM fill_cell USING lv_num 3 0 ls_line-xmfzr excel_obj.
PERFORM fill_cell USING lv_num 4 0 ls_line-xmyear excel_obj.
ENDLOOP.
ELSE.
MESSAGE TEXT-m15 TYPE 'S' DISPLAY LIKE 'E'.
RETURN.
ENDIF.
*&---------------------------------------------------------------------*
*& Form FILL_CELL
*&---------------------------------------------------------------------*
* row: 行号,
* col: 列号,
* bold: 字体是否加粗,0,否,1是.
* val: 填充值
*----------------------------------------------------------------------*
FORM fill_cell USING row col bold val excel_obj.
DATA: cell_obj TYPE ole2_object.
CALL METHOD OF excel_obj 'CELLS' = cell_obj
EXPORTING #1 = row
#2 = col.
SET PROPERTY OF cell_obj 'VALUE' = val.
ENDFORM.
总结
到这里所有的写入操作都已经结束了,如果还需要加粗,改变字体颜色什么的,这些格式操作也比较简单,大家可以在网上进行查询。
总结一下,这种OLE的方式实际上还得依赖本地Excel的完成,且一旦数据量多了之后,效率会变得很慢,但对于小需求,数据不大这种场景,OLE其实也是比较推荐的,由于代码量也不多,实现起来也较快。
下一篇咱们会讲相比OLE技术而言,速度更快,且兼容性更强的abap2xlsx技术