Embed VE Viewer inside SAP GUI
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:
- Install SAP VE Viewer on your laptop/desktop. Here is the link from where you can download (http://www.sdn.sap.com/irj/scn/downloads?rid=/webcontent/uuid/00811fac-caea-2f10-b8a0-b4152739d1eb)
- Some ABAP development experience and a SAP system to write up the ABAP code.
- Install a COM Object browser/Active X inspector. (Please note: This is an optional one. Its only required if you want to know more about what methods/events are available for us)
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:
- Screen 0100 is created inside this program with Custom Control “CUSTOM_CONTROL_0100 ” and OK CODE is handled by using variable “G_SYUCOMM”.
- PF STATUS “STATUS_0100” is created with commonly used user command BACK, EXIT, CANCEL.
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.
Really nice article...
Thanks a lot for the sample code as well...
Regards,
Raj
Hello Aditya,
Great Blog, please help me by answering few questions.
1. Is it possible to send multiple RH files & get them viewed assembled ?
2. My requirement is, sending all rh files of the components in a BOM, the viewer should assemble & display
Dear All,
Please help in building an Custom Abap program to embed Viewer in it.
The scope is from the selected BOM, I have to load all the available (Multiple) assembly's drawing in the viewer. Not much information on how to use the class CL_GUI_VIEWER_MODEL, how the methods should be called & parameters to be passed. Please throw some light.
Thanks,
Sridhar
Hi Sridhar, You can use the load_assembly method to pass an assembly to be loaded in the viewer. It is important to specify the TMX (Transformation matrix) data in this case , so that Viewer understands how to position the parts. You can load an entire assembly at once by simply passing the parts in one go to the load_assembly method or use it in conjunction with Add_item method to add further parts based on user selection of parts. Here is some sample code that you may refer: CONSTANTS: * Populate initial values of DMUTMX for the root of the assembly BEGIN OF lc_root_dmutmx, locox TYPE /plmu/s_vwr_trafo_id-locox VALUE '0.0000000000000000E+00', locoy TYPE /plmu/s_vwr_trafo_id-locoy VALUE '0.0000000000000000E+00', locoz TYPE /plmu/s_vwr_trafo_id-locoz VALUE '0.0000000000000000E+00', axis1x TYPE /plmu/s_vwr_trafo_id-axis1x VALUE '1.0000000000000000E+00', axis1y TYPE /plmu/s_vwr_trafo_id-axis1y VALUE '0.0000000000000000E+00', axis1z TYPE /plmu/s_vwr_trafo_id-axis1z VALUE '0.0000000000000000E+00', axis2x TYPE /plmu/s_vwr_trafo_id-axis2x VALUE '0.0000000000000000E+00', axis2y TYPE /plmu/s_vwr_trafo_id-axis2y VALUE '1.0000000000000000E+00', axis2z TYPE /plmu/s_vwr_trafo_id-axis2z VALUE '0.0000000000000000E+00', axis3x TYPE /plmu/s_vwr_trafo_id-axis3x VALUE '0.0000000000000000E+00', axis3y TYPE /plmu/s_vwr_trafo_id-axis3y VALUE '0.0000000000000000E+00', axis3z TYPE /plmu/s_vwr_trafo_id-axis3z VALUE '1.0000000000000000E+00', scale TYPE /plmu/s_vwr_trafo_id-scale VALUE '1.0000000000000000E+00', END OF lc_root_dmutmx. MOVE view_objects TO lt_viewobjects. SORT lt_viewobjects BY guid. DELETE ADJACENT DUPLICATES FROM lt_viewobjects COMPARING guid. READ TABLE lt_viewobjects INTO curviewobj INDEX 1. READ TABLE dmu_objects INTO curobj WITH KEY guid = curviewobj-guid. SELECT dokar doknr dokvr doktl dktxt FROM drat INTO CORRESPONDING FIELDS OF TABLE lt_dmu_doc_desc FOR ALL ENTRIES IN dmu_objects WHERE dokar = dmu_objects-data-dokar AND doknr = dmu_objects-data-doknr AND dokvr = dmu_objects-data-dokvr AND doktl = dmu_objects-data-doktl AND langu = sy-langu. CLEAR: ls_application, lt_application, ls_dir_id, ls_root. ls_application-objecttype = lc_doc_object_type. ls_application-appl = lc_doc_appl_type. APPEND ls_application TO lt_application. lv_dmu_count = lines( dmu_objects ). IF me->gv_vwr_loaded EQ abap_false. * Viewer not loaded yet => call LOAD_ASSEMBLY LOOP AT dmu_objects INTO curobj. CLEAR: ls_posids_stage, ls_visual_tree. IF curobj-guid_pred IS INITIAL. curobj-guid_pred = lc_root_ext_guid. ENDIF. IF curobj-guid = lc_root_ext_guid. * This is definitely the root guid * If the current ext. guid has is 32 bit guid-mapping already created * reuse it. Else create a new 32 bit guid READ TABLE gt_posids_stage INTO ls_posids_stage WITH KEY ext_guid = curobj-guid. IF sy-subrc <> 0. TRY. * Create guid CALL METHOD cl_system_uuid=>if_system_uuid_static~create_uuid_c32 RECEIVING uuid = ls_posids_stage-guid. CATCH cx_uuid_error . ls_message-msgid = sy-msgid. ls_message-msgno = sy-msgno. ls_message-msgty = sy-msgty. APPEND ls_message TO lt_guid_message. IF ls_message-msgty CA 'EAX'. MESSAGE ID ls_message-msgid TYPE ls_message-msgty NUMBER ls_message-msgno WITH ls_message-msgv1 ls_message-msgv2 ls_message-msgv3 ls_message-msgv4. EXIT. ENDIF. RETURN. ENDTRY. * Created a new Ext. GUID - GUID Mapping. Log it to the stage ls_posids_stage-ext_guid = curobj-guid. APPEND ls_posids_stage TO gt_posids_stage. ENDIF. ls_root-posid = ls_posids_stage-guid. * Setting values to be passed Viewer API parameters (Again mostly trivial values) ls_root-highlight = abap_false. ls_root-absoluteposition = abap_false. * Root is defnitely a sub-assmebly => DO NOT pass any URI ls_root-uri = space. * Fetch the document description formulated above. CLEAR: ls_dmu_doc_desc. READ TABLE lt_dmu_doc_desc INTO ls_dmu_doc_desc WITH KEY dokar = curobj-data-dokar doknr = curobj-data-doknr dokvr = curobj-data-dokvr doktl = curobj-data-doktl. * Stage the root relevant data into gs_root MOVE-CORRESPONDING ls_root TO gs_root. * Update the local scene tree with whatever is being passed * to the VIEWER. This is later used to infer hierarchy between selected parts ls_visual_tree-guid = ls_posids_stage-guid. ls_visual_tree-guid_pred = curobj-guid_pred. " This will always be 000000 for root -> No parent of root APPEND ls_visual_tree TO gt_visual_tree. ELSE. * This is not the root. * IF lv_is_subasm EQ abap_false. CLEAR: ls_subpart. * By the time we are here, gs_root should be filled, if this is not DMU Viewing (All). IF gs_root IS INITIAL. CLEAR: ls_posids_stage. TRY. * Create guid CALL METHOD cl_system_uuid=>if_system_uuid_static~create_uuid_c32 RECEIVING uuid = ls_posids_stage-guid. CATCH cx_uuid_error . ls_message-msgid = sy-msgid. ls_message-msgno = sy-msgno. ls_message-msgty = sy-msgty. APPEND ls_message TO lt_guid_message. IF ls_message-msgty CA 'EAX'. MESSAGE ID ls_message-msgid TYPE ls_message-msgty NUMBER ls_message-msgno WITH ls_message-msgv1 ls_message-msgv2 ls_message-msgv3 ls_message-msgv4. ENDIF. RETURN. ENDTRY. ls_posids_stage-ext_guid = lc_root_ext_guid. APPEND ls_posids_stage TO gt_posids_stage. ls_root-posid = ls_posids_stage-guid. * Append a entry for the transformation matrices of the root node (Use GUID generated above as POSID). * These would be trivial values but are needed by Viewer APIs ls_dmutmx-posid = ls_root-posid. APPEND ls_dmutmx TO lt_dmutmx. * Setting values to be passed Viewer API parameters (Again mostly trivial values) ls_root-highlight = abap_false. ls_root-absoluteposition = abap_false. * Root is defnitely a sub-assmebly => DO NOT pass any URI ls_root-uri = space. * Fetch the document description formulated above. CLEAR: ls_dmu_doc_desc. READ TABLE lt_dmu_doc_desc INTO ls_dmu_doc_desc WITH KEY dokar = curobj-data-dokar doknr = curobj-data-doknr dokvr = curobj-data-dokvr doktl = curobj-data-doktl. ls_root-name = ls_dmu_doc_desc-dktxt. * Stage the root relevant data into gs_root MOVE-CORRESPONDING ls_root TO gs_root. * Update the local scene tree with whatever is being passed * to the VIEWER. This is later used to infer hierarchy between selected parts ls_visual_tree-guid = ls_posids_stage-guid. ls_visual_tree-guid_pred = curobj-guid_pred. " This will always be 000000 for root -> No parent of root APPEND ls_visual_tree TO gt_visual_tree. ENDIF. **SUBPARTS: Parts or Sub-assembly. IF curobj-flg_stko IS INITIAL. lv_is_doc_struc = abap_false. ELSE. lv_is_doc_struc = abap_true. ENDIF. * Fetch RH original iff the curobj is a part IF lv_is_doc_struc = abap_false. ls_dir_id-dokar = curobj-data-dokar. ls_dir_id-doknr = curobj-data-doknr. ls_dir_id-doktl = curobj-data-doktl. ls_dir_id-dokvr = curobj-data-dokvr. CALL FUNCTION 'DMS_GET_UNIQUE_FILE' EXPORTING it_application = lt_application is_dir_id = ls_dir_id iv_validity_date = sy-datum IMPORTING et_file = lt_file et_message = lt_dms_msg. IF lt_dms_msg IS NOT INITIAL. LOOP AT lt_dms_msg INTO ls_dms_msg WHERE msgty CA 'EAX'. MESSAGE ID ls_dms_msg-msgid TYPE ls_dms_msg-msgty NUMBER ls_dms_msg-msgno WITH ls_dms_msg-msgv1 ls_dms_msg-msgv2 ls_dms_msg-msgv3 ls_dms_msg-msgv4. EXIT. ENDLOOP. ENDIF. READ TABLE lt_file INTO ls_file INDEX 1. * Populate values to ls_subpart -> To be passed to Viewer ls_subpart-description = ls_file-dktxt. ls_subpart-uri = ls_file-url. ls_subpart-hide = abap_false. IF ls_file-url IS INITIAL. * IF lv_dmu_count = 1. * me->lif_docmng~free( ). * ENDIF. MESSAGE s108(cpbr) DISPLAY LIKE 'W' WITH ls_dir_id-doknr. * EXIT. CONTINUE. ENDIF. ENDIF. ls_subpart-highlight = abap_false. ls_subpart-absoluteposition = abap_false. * Fetch the document description formulated earlier. * This will the same for every instance (Ex: Wheel, Spoke etc.) CLEAR: ls_dmu_doc_desc. READ TABLE lt_dmu_doc_desc INTO ls_dmu_doc_desc WITH KEY dokar = curobj-data-dokar doknr = curobj-data-doknr dokvr = curobj-data-dokvr doktl = curobj-data-doktl. * If there exist multiple instances of the current part, * Send them as separate parts coupled with their appropriate T-Matrices * to the Viewer - Viewer provides instance level control for each such instance. LOOP AT gt_posids_stage INTO ls_posids_stage_p WHERE ext_guid = curobj-guid_pred. LOOP AT curobj-postab-pos INTO ls_pos. ls_subpart-parentposid = ls_posids_stage_p-guid. ls_subpart-name = ls_dmu_doc_desc-dktxt. * Each one of these multiple instances needs to have a unique POSID/GUID. * However, they are mapped to the same EXT.GUID and staged accordingly. CLEAR: ls_posids_stage. TRY. * Create guid CALL METHOD cl_system_uuid=>if_system_uuid_static~create_uuid_c32 RECEIVING uuid = ls_posids_stage-guid. CATCH cx_uuid_error . ls_message-msgid = sy-msgid. ls_message-msgno = sy-msgno. ls_message-msgty = sy-msgty. APPEND ls_message TO lt_message. IF ls_message-msgty CA 'EAX'. MESSAGE ID ls_message-msgid TYPE ls_message-msgty NUMBER ls_message-msgno WITH ls_message-msgv1 ls_message-msgv2 ls_message-msgv3 ls_message-msgv4. EXIT. ENDIF. RETURN. ENDTRY. ls_posids_stage-ext_guid = curobj-guid. APPEND ls_posids_stage TO gt_posids_stage. ls_subpart-posid = ls_posids_stage-guid. * Maintain local scene data stage. ls_visual_tree-guid = ls_subpart-posid. ls_visual_tree-guid_pred = ls_subpart-parentposid. APPEND ls_visual_tree TO gt_visual_tree. APPEND ls_subpart TO lt_subparts. * DMU_OBJECTS essentially will contain the T-matrices for each instance. * Map them accordingly. READ TABLE curobj-matrices-matrix WITH KEY tmxguid = ls_pos-tmxguid INTO ls_matrix. IF sy-subrc <> 0. * IF lv_dmu_count = 1. * me->lif_docmng~free( ). * ENDIF. MESSAGE s103(cpbr) DISPLAY LIKE 'W'. CONTINUE. ENDIF. CLEAR ls_dmutmx. MOVE-CORRESPONDING ls_matrix TO ls_dmutmx. ls_dmutmx-posid = ls_posids_stage-guid. APPEND ls_dmutmx TO lt_dmutmx. ENDLOOP. ENDLOOP. ENDIF. ENDLOOP. * Append a entry for the transformation matrices of the root node (Use GUID generated above as POSID). * These would be trivial values but are needed by Viewer APIs CLEAR: ls_dmutmx. MOVE-CORRESPONDING lc_root_dmutmx TO ls_dmutmx. ls_dmutmx-posid = gs_root-posid. APPEND ls_dmutmx TO lt_dmutmx. IF NOT me->ve_vwr_docked IS INITIAL. IF NOT lt_subparts IS INITIAL. IF NOT lt_dmutmx IS INITIAL. CALL METHOD me->ve_vwr_docked->load_assembly EXPORTING io_parent = ve_vwr_parent is_root = ls_root it_exclaction = lt_exclude_action it_subparts = lt_subparts it_trafo = lt_dmutmx iv_id_field = '' IMPORTING et_message = lt_message. me->gv_vwr_loaded = abap_true. IF lt_message IS NOT INITIAL. LOOP AT lt_message INTO ls_message WHERE msgty CA 'EAX'. MESSAGE ID ls_message-msgid TYPE ls_message-msgty NUMBER ls_message-msgno WITH ls_message-msgv1 ls_message-msgv2 ls_message-msgv3 ls_message-msgv4. EXIT. ENDLOOP. ENDIF. ENDIF. ENDIF. ENDIF. ELSE. * Viewer already loaded => call ADD_ITEMS LOOP AT dmu_objects INTO curobj. IF curobj-guid = lc_root_ext_guid. CONTINUE. ELSEIF curobj-guid_pred IS INITIAL. curobj-guid_pred = lc_root_ext_guid. ENDIF.
Hi Adithya K!
I don't know if you can help me but, no harm to try.
I'm facing a problem with VEV with DMS. I save a conversation/redlining but when I get back the conversation/redlining does not appear. When I debug the standard, I can see that the conversations are uploaded to a internal table of layers but they do not appear on the file.
Can you help me?
Should this work with document URLs as well? I have it working with local files, but can't stream documents from their URLs.
Any light you could shine on this would be appreciated!