Objective:
Hi Everyone, I believe after looking the SAP VE viewer on your desktop, you would be interested to know whether we can see the same VE Viewer inside the SAP GUI. The objective of this blog is to help you understand how to open SAP Visual Enterprise viewer inside SAP GUI. In this blog, we will create a class and also a test program which takes a file as an input and displays the same inside the VE Viewer.
Pre-requisites:
Programming logic:
To start with, SAP VE Viewer also has an Active X control for integration into SAP Gui. "DeepViewForGAC 1.0 Type Library" is the name of the Active X control. If you would like to know more about how Active X control works inside SAP GUI, please refer to Thomas Jung blog. Many thanks to him, he help us understand fundamentals related to numerous SAP technical things.
New Class ZCL_GUI_SVE_CONTROL Creation:
Lets start creating a new class for VE Viewer.
Login to SAP ERP system, navigate to ABAP Class creation (SE24), create a new class ZCL_GUI_SVE_CONTROL with following properties.
Now, we need to create some attributes/properties which we will be accessing inside the methods.
Save all the objects and activate the class. Then, Click on Create Constructor. It will give you a popup asking for a confirmation "Do you want to copy across the signature of the super class constructor?". Select "Yes" option and continue to write the following code in the Constructor.
DATA: lv_prog_id(80), lv_style TYPE i.
IF parent IS INITIAL.
* RAISE error_cntl_create.
RAISE cntl_error.
ENDIF.
CLASS cl_gui_cfw DEFINITION LOAD.
* assign prog_id to get the frontend specific control
IF NOT activex IS INITIAL.
lv_prog_id = gc_ve_cls_id.
ELSEIF NOT javabean IS INITIAL.
* RAISE gui_type_not_supported.
RAISE cntl_system_error.
ENDIF.
IF lv_prog_id IS INITIAL.
RAISE cntl_system_error.
ENDIF.
* Set the window styles of the control when style parameter was not
* set with constructor call.
* For more information on the styles see WIN32 SDK
IF lv_style IS INITIAL.
* otherwise the control would be invisible and the mistake would be
* hard to find
lv_style = cl_gui_control=>ws_visible + cl_gui_control=>ws_child + cl_gui_control=>ws_clipsiblings.
ENDIF.
* Create the control
CALL METHOD super->constructor
EXPORTING
clsid = lv_prog_id
shellstyle = lv_style
parent = parent
lifetime = lifetime
name = name
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
* RAISE error_cntl_create.
RAISE cntl_error.
ENDIF.
* register instance at framework
CALL METHOD cl_gui_cfw=>subscribe
EXPORTING
shellid = h_control-shellid
ref = me
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
* RAISE error_cntl_create.
RAISE cntl_error.
ENDIF.
* create and initialize dataprovider => m_dp_handle
CALL FUNCTION 'DP_CREATE'
CHANGING
h_dp = gv_dp_handle
EXCEPTIONS
dp_create_error = 1
dp_install_error = 2
dp_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
* RAISE error_cntl_create.
RAISE cntl_system_error.
ENDIF.
Next, create a new method SAP_LOAD_VIEWER_SINGLE for loading the file name with the signature shown in the snapshot below:
Add the following code inside the method.
CALL METHOD call_method
EXPORTING
method = 'SAP_LOAD_VIEWER_SINGLE'
p_count = 4
p1 = single_view
p2 = layer
p3 = action
p4 = exclaction
queue_only = ' '
* importing
* result = result
EXCEPTIONS
OTHERS = 1.
IF sy-subrc NE 0.
RAISE error_cntl_call_method.
ENDIF.
New program Z_SVE_TEST_PROGRAM Creation:
Now, create a new program "Z_SVE_TEST_PROGRAM" to accept a file as a selection screen parameter and then use the class created above for displaying the file in VE Viewer inside SAP GUI.
Program code:
*&---------------------------------------------------------------------*
*& Report Z_SVE_TEST_PROGRAM
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_sve_test_program.
TYPE-POOLS: cntl.
CONSTANTS:
gc_container TYPE char128 VALUE 'CUSTOM_CONTROL_0100'.
DATA:
obj_container TYPE REF TO cl_gui_custom_container,
obj_ve TYPE REF TO zcl_gui_sve_control,
g_syucomm TYPE syucomm.
DATA:
g_loadsingleresult TYPE string,
g_single_view TYPE string.
PARAMETERS:
p_fname TYPE dxfields-longpath DEFAULT 'C:\Temp\rh.rh' OBLIGATORY.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.
PERFORM f4_filename CHANGING p_fname.
START-OF-SELECTION.
CALL SCREEN 100.
*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS 'STATUS_0100'.
SET TITLEBAR 'TITLE_0100'.
IF obj_container IS INITIAL.
CREATE OBJECT obj_container
EXPORTING
* PARENT =
container_name = gc_container
* STYLE =
* LIFETIME = lifetime_default
* REPID =
* DYNNR =
* NO_AUTODEF_PROGID_DYNNR =
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6 .
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CREATE OBJECT obj_ve
EXPORTING
* clsid = clsid
* lifetime = lifetime_default
* shellstyle = shellstyle
parent = obj_container
* autoalign = 'x'
* licensekey = licensekey
* name = name
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
parent_is_splitter = 5
OTHERS = 6.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
CLEAR g_single_view.
IF p_fname IS NOT INITIAL.
CONCATENATE '<SINGLE_VIEW FILEPATH="'
p_fname
'" LANGUAGE="en" />'
INTO g_single_view.
ENDIF.
CALL METHOD obj_ve->sap_load_viewer_single
EXPORTING
single_view = g_single_view
* action = 'CREATE_LAYER'
IMPORTING
result = g_loadsingleresult
EXCEPTIONS
error_cntl_call_method = 1.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ELSE.
ENDIF.
ENDIF.
ENDMODULE. " STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
IF g_syucomm EQ 'BACK' OR
g_syucomm EQ 'CANCEL'.
IF obj_ve IS INITIAL.
ELSE.
CALL METHOD obj_ve->free.
CLEAR obj_ve.
ENDIF.
IF obj_container IS NOT INITIAL.
CALL METHOD obj_container->free.
CLEAR obj_container.
ENDIF.
LEAVE TO SCREEN 0.
ELSEIF g_syucomm EQ 'EXIT'.
LEAVE PROGRAM.
ENDIF.
ENDMODULE. "user_command_0100 INPUT
*&---------------------------------------------------------------------*
*& Form F4_FILENAME
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* <--P_P_FNAME text
*----------------------------------------------------------------------*
FORM f4_filename CHANGING pr_fname.
DATA i_path TYPE dxfields-longpath.
DATA filemask TYPE dxfields-filemask.
DATA o_path TYPE dxfields-longpath.
DATA abend_flag TYPE dxfields-abendflag.
MOVE 'C:\' TO i_path.
DATA: lwa_file_table TYPE file_table,
lt_file_table TYPE filetable.
DATA multiselection TYPE abap_bool.
DATA rc TYPE i.
cl_gui_frontend_services=>file_open_dialog(
EXPORTING
window_title = 'File Selection'
* default_extension = default_extension
default_filename = 'C:\TEMP\RH.RH' " default_filename
* file_filter = file_filter
* with_encoding = with_encoding
* initial_directory = initial_directory
multiselection = abap_false
CHANGING
file_table = lt_file_table
rc = rc
* user_action = user_action
* file_encoding = file_encoding
EXCEPTIONS
file_open_dialog_failed = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5
).
IF sy-subrc <> 0.
* Implement suitable error handling here
ELSE.
READ TABLE lt_file_table INTO lwa_file_table INDEX 1.
MOVE lwa_file_table-filename TO pr_fname.
ENDIF.
ENDFORM. " F4_FILENAME
Please note:
Snapshots of Program output:
References:
I would like to Thank once again Thomas Jung , Mark Doberenz and my friend Prudvin . Blogs written by Thomas Jung helped me understand the Active X part, Inputs from Mark helped me to write this blog and share this to everyone.