Preface

There are always occasionally requirements on semi-structure information processing in SAP ABAP systems. Especially, like purchase order attachments, financial comments, and so on. The questions are always where to store them? and how to access them?. The suggested solutions by marketing guys would be a portal/KM server, a content server, or an OpenText server. But they are all too heavy. I maybe only want to process limited number of XML, PDF, WORD, or HTML, and I only have an ABAP server on hand. What can I do?

In this blog, I will provide you a fast skip view of the facilities that ABAP provides. You may hear or search words like: “KPro”, “DMS”, “CMS”, “ArchiveLink”, and “GOS”. What are they stands for? What the hell should I use to achieve a simple document attachment requirements?  Well, I should say these modules or services may have histories, and it is indeed difficult to figure them out. Don’t even say how to use them correctly. I hope after reading this blog, you can get a general idea of what you want get from them.

The Whole Picture

 

DMS and CMS

  1. CMS is a layer to connect with storages. Storages are: HTTP content server, SAP database, RFC storage system, logical repository, and structure repository.
  2. DMS is based on CMS by adding following functions: attributes, relationships, versioning, context resolution, and content models.

According to the diagram,  DMS and CMS are 2 core KPro services.

DMS Content Model:

The DMS content model is a 3-level content model:

  1. Components administrate content
  2. Physical documents administrate documents
  3. Logical documents administrate collections of documents


CMS

Content Server Architecture

Configuration

1. Create a content repository. The content repository is an object that represents the storage types in ABAP world.

    Path: SPRO –> Cross-Application Components –> DMS –> General data –> Setting for Storage SystemsàMaintain Storage System

  1. Click “CS Admin” to create the content repository connections. The driver should be set to “MaxDB”

  2. On the “Certificates” page, click the button to send certificates from SAP ABAP to Content Server.

  3. On the Overview Tab, make sure the repository is on running status.

  4. Use report “RSCMST” to test all the functions of the newly created repository.

2. Create a repository category. The repository category is a logic view of content repository which is faced to applications.

    Path: SPRO –> Cross-Application Components –> DMS –> General data –> Setting for Storage Systems->Maintain Storage Category

3. Define workstation applications. Workstation application means XLS, DOC, PPT, PDF, and so on.

    The definition here tells use which application to open the document from SAP.

    Path: SPRO –> Cross-Application Components –>DMS –>General data –> Define Workstation Application

4. Define profiles. Profiles connect users/roles with repository category.

    For example: User A is only allowed to upload an EXCEL file to repository category B.

   SPRO –> Cross-Application Components –> DMS –> General data –> Define Profile

Till now the basic CMS configurations are finished. We have defined a content repository: ZSHDMS with category: ZSD_DMS. We also add a workstation application: ZTY which represents general document types. Profile: ZKLEE defines all EXCEL and ZTY documents uploaded by “kai_zhang” will be stored into category: ZSD_DMS.

DMS

SAP DMS is rather complicate. Here we only represent a simple configuration that fulfils the basic requirements like upload attachments to an SAP (or self-developed) objects.

Configuration

1. Configure the key of an object.

    Here we use SAP purchase order as example. The PO number EBELN is in the PO head table EKKO. So we define the key fields in DMS.

   Path: SPRO –> Cross-Application Components –> DMS –> Control data –> Maintain Key fields

2. Define a document type ‘ZMM’.

  A document type is the central object in DMS which combines all the functionalities together.

   Path: SPRO –> Cross-Application Components –> DMS –> Control data –> Define Doc Type

3. Define object link.

    This step tells DMS that ZMM document type will have object EKKO linked and the screen number is fixed 500. The reason is SAP provides EXITS to enhance the DMS. Screen 1500 in function group CV130 is the UI exit.

4. Maintain object link description.

This will give the TAB description in tcode CVxxN.

5. Define a document status description

6. Add status chain to the document type

Maintain screen number for the object, must be 500.

    Path: SPRO –> Cross-Application Components –> DMS –> Control data –> Maintain Screen for Object Link

Till now, all the basic DMS configurations are finished. We can now upload documents into content server.

 
Upload Documents using DMS

Introduction

Tcodes: CV01N, CV02N, CV03N, CV04N

CV01N, CV02N, and CV03N are just the same, they can all be used to create, change, display, and delete documents. CV04N is used to search and list documents.

Upload documents

To upload a document, call CV01N and enter “*” in the “document” field. Put the document type, and leave other fields empty. Click “Enter”.

1. Input some description, and click the button to upload documents from your laptop.

2. Select a file from your laptop

3. Select the document and click check-in button to finally check-in the document.

    You must check-in your document or the document will not be stored to content server.

    If you do not maintain the profile, you will get the following prompt window to let you choose one repository category. The profile connects SAP USER/ROLE with application type (xml, pdf, doc, and so on) to a specific repository category.

Enhance the DMS to link document with objects

Introducing

We will link document type ZMM to purchase order using BADI implementation. The target is to see PO object links in tcodes: CVXXN.

Enhancement Steps

1. Develop a Z program (ZPO_ATTACHMENT_TST) with type “Module Pool”. Add a screen 9000 into the program.

2. Codes

 *&---------------------------------------------------------------------* *& Module Pool       ZPO_ATTACHMENT_TST *& *&---------------------------------------------------------------------* *& *& *&---------------------------------------------------------------------* program  ZPO_ATTACHMENT_TST. ***BADI EXTENSION****************************************************** ***dynpro number data GF_CALL_DYNP like SY-DYNNR. data GF_PROG_NAME like SY-CPROG. data GF_DOKOB_FILT like DRAD-DOKOB. data GF_AUTH(4) type C. data GF_ACTIVITY type I. ***dynpro example types: begin of EDIT. types:   EBELN like EKKO-EBELN.         include structure DMS_DRAD_BADI_WORK. types: end of EDIT. data GT_EDIT type table of EDIT with header line. data GF_ACTIVITY_1500 type I. controls:  TAB_X1 type tableview using screen 9000. data  GF_VAL(10) value 'EKKO'. data  TAB_MARK. *icon for table control************************************************* data  ICON_F like ICONS-TEXT. data  ICON_F1 like ICONS-TEXT. *&---------------------------------------------------------------------* *&      Module  DYN_9000_PBO_INIT  OUTPUT *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* module DYN_9000_PBO_INIT output.   perform GET_DATA.   perform DISPLAY_COL_CHANGE1 using 'GT_EDIT-VKEY' 1 1.   " hide col   perform DISPLAY_COL_CHANGE1 using 'ICON_F' 1 1.   perform DISPLAY_COL_CHANGE1 using 'ICON_F1' 1 1. endmodule.                 " DYN_9000_PBO_INIT  OUTPUT *&---------------------------------------------------------------------* *&      Module  DYN_9000_PBO_LOOP  OUTPUT *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* module DYN_9000_PBO_LOOP output.   read table GT_EDIT index TAB_X1-CURRENT_LINE.   TAB_MARK = GT_EDIT-TAB_MARK.   if GF_ACTIVITY_1500 < 4. "GF_ACTIVITY_1500 indicates DISPLAY, CHANGE ,CREATE, and LIST     perform CHECK_ICON using GT_EDIT.   endif.   if GF_ACTIVITY_1500 < 3. ***create edit set icon     perform CHECK_ICON1 using GT_EDIT.   elseif GF_ACTIVITY_1500 < 4. ***display     perform DISPLAY_COL_CHANGE1 using 'GT_EDIT-EBELN' 3 0.   endif. endmodule.                 " DYN_9000_PBO_LOOP  OUTPUT *&---------------------------------------------------------------------* *&      Form  get_data *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* form GET_DATA .   data OBJECT type ref to IF_EX_DOCUMENT_OBJ.   data LT_DRAD_WORK type DMS_TBL_DRAD_BADI_WORK.   data LS_DRAD_WORK type DMS_DRAD_BADI_WORK.   data LT_DRAD type table of DRAD.   data LS_EDIT type EDIT.   data LF_ACTIVITY type I.   data LF_ACT.   data LF_TIMES type I value 40. ***get instance   call method CL_EXITHANDLER=>GET_INSTANCE_FOR_SUBSCREENS     changing       INSTANCE = OBJECT.   call method OBJECT->GET_DATA     exporting       FLT_VAL         = GF_VAL     importing       TABLE_DRAD_WORK = LT_DRAD_WORK       TABLE_DRAD_DB   = LT_DRAD       ACTIVITY        = GF_ACTIVITY_1500. ***transport dynpr data   refresh GT_EDIT.   loop at LT_DRAD_WORK into LS_DRAD_WORK. ****move control structure     move-corresponding LS_DRAD_WORK to LS_EDIT. ****move object info     move LS_EDIT-OBJKY to LS_EDIT-EBELN.     append LS_EDIT to GT_EDIT.   endloop. ***fill dynpro   do LF_TIMES times.     clear LS_EDIT.     LS_EDIT-DOKOB = GF_VAL.     append LS_EDIT to GT_EDIT.   enddo. endform.                    " get_data                  " get_data *&---------------------------------------------------------------------* *&      Form  DISPLAY_COL_CHANGE1 *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* *      -->PF_NAME    text *      -->PF_ACTION  text *      -->SET        text *----------------------------------------------------------------------* form DISPLAY_COL_CHANGE1 using PF_NAME like SCREEN-NAME                               PF_ACTION type I                               SET type I.   data LS_WA like line of TAB_X1-COLS.   case PF_ACTION.     when 1.                            "=invisible       loop at TAB_X1-COLS into LS_WA.         if LS_WA-SCREEN-NAME = PF_NAME.           LS_WA-INVISIBLE = SET.         endif.         modify TAB_X1-COLS from LS_WA.       endloop.     when 2.       loop at screen.         if SCREEN-NAME = PF_NAME.           SCREEN-INVISIBLE = SET.         endif.         modify screen.       endloop.     when 3.       loop at screen.         if SCREEN-NAME = PF_NAME.           SCREEN-INPUT = SET.         endif.         modify screen.       endloop.   endcase. endform.                    "DISPLAY_COL_CHANGE1 *&---------------------------------------------------------------------* *&      Form  check_icon *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* *      -->PS_EDIT    text *----------------------------------------------------------------------* form CHECK_ICON  using    PS_EDIT type EDIT.   data LF_TEXT like ICONT-QUICKINFO.   data LF_STRING(15) type C.   data LF_CHECK.   clear ICON_F. ***create short text   if not PS_EDIT-SET_TEXT is initial.     LF_STRING = '长文本'.     concatenate LF_TEXT LF_STRING into LF_TEXT.   endif.   if not PS_EDIT-VKEY is initial.     LF_STRING = '附加信息'.     perform DISPLAY_COL_CHANGE1 using 'GT_EDIT-VKEY' 1 0.   " show col     concatenate LF_TEXT LF_STRING into LF_TEXT     separated by  ' '.   endif.   if not PS_EDIT-SET_CLASS is initial.     LF_STRING = '分类'.     concatenate LF_TEXT LF_STRING into LF_TEXT     separated by  ' '.   endif.   if not LF_TEXT is initial.     LF_STRING = '存在'.     concatenate LF_TEXT LF_STRING into LF_TEXT     separated by  ' '.     perform DISPLAY_COL_CHANGE1 using 'ICON_F' 1 0. ***load icon     call function 'ICON_CREATE'       exporting         NAME                  = ICON_TEXT_ACT         TEXT                  = ICON_F         INFO                  = LF_TEXT       importing         RESULT                = ICON_F       exceptions         ICON_NOT_FOUND        = 1         OUTPUTFIELD_TOO_SHORT = 2         others                = 3.     if SY-SUBRC <> 0.       SY-SUBRC = 0.     endif.   else.     clear ICON_F.   endif. endform.                    " check_icon *----------------------------------------------------------------------* form CHECK_ICON1  using   PS_EDIT type EDIT.   data LF_SET_TYPE type EDIT-SET_TYPE. ***show row   LF_SET_TYPE = PS_EDIT-SET_TYPE.   if LF_SET_TYPE is initial      and ( PS_EDIT+1(1) = 'X' or PS_EDIT+3(1) = 'X' ).     LF_SET_TYPE = 3.   endif.   if not LF_SET_TYPE is initial.     perform DISPLAY_COL_CHANGE1 using 'ICON_F1' 1 0.     perform DISPLAY_COL_CHANGE1 using 'GT_EDIT-EBELN' 3 0.   endif.   case LF_SET_TYPE.     when 1. ***locked       call function 'ICON_CREATE'         exporting           NAME                  = ICON_LOCKED           TEXT                  = ICON_F1           INFO                  = '锁定的数据记录'         importing           RESULT                = ICON_F1         exceptions           ICON_NOT_FOUND        = 1           OUTPUTFIELD_TOO_SHORT = 2           others                = 3.       if SY-SUBRC <> 0.         SY-SUBRC = 0.       endif.     when 2. ***delete indicator       call function 'ICON_CREATE'         exporting           NAME                  = ICON_LOCKED           TEXT                  = ICON_F1           INFO                  = '不允许删除'         importing           RESULT                = ICON_F1         exceptions           ICON_NOT_FOUND        = 1           OUTPUTFIELD_TOO_SHORT = 2           others                = 3.       if SY-SUBRC <> 0.         SY-SUBRC = 0.       endif. ***authority no change or delete     when 3.       call function 'ICON_CREATE'         exporting           NAME                  = ICON_DELETE_ROW           TEXT                  = ICON_F1           INFO                  = '锁定的数据记录'         importing           RESULT                = ICON_F1         exceptions           ICON_NOT_FOUND        = 1           OUTPUTFIELD_TOO_SHORT = 2           others                = 3.       if SY-SUBRC <> 0.         SY-SUBRC = 0.       endif.     when others.       clear ICON_F1.   endcase. endform.                    " check_icon1 *&---------------------------------------------------------------------* *&      Module  DYN_9000_PAI_LOOP  INPUT *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* module DYN_9000_PAI_LOOP input.   GT_EDIT-TAB_MARK = TAB_MARK.   modify GT_EDIT index TAB_X1-CURRENT_LINE. endmodule.                 " DYN_9000_PAI_LOOP  INPUT *&---------------------------------------------------------------------* *&      Module  DYN_9000_PAI_PUT_DATA  INPUT *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* module DYN_9000_PAI_PUT_DATA input.   perform PUT_DATA. endmodule.                 " DYN_9000_PAI_PUT_DATA  INPUT *&---------------------------------------------------------------------* *&      Form  put_data *&---------------------------------------------------------------------* *       text *----------------------------------------------------------------------* form PUT_DATA .   data OBJECT type ref to IF_EX_DOCUMENT_OBJ.   data LT_DRAD_WORK type DMS_TBL_DRAD_BADI_WORK.   data LS_DRAD_WORK type DMS_DRAD_BADI_WORK.   data LT_DRAD type table of DRAD.   data LS_EDIT type EDIT. ***get instance   call method CL_EXITHANDLER=>GET_INSTANCE_FOR_SUBSCREENS     changing       INSTANCE = OBJECT.   loop at GT_EDIT into LS_EDIT. ***move control structure     move-corresponding LS_EDIT to LS_DRAD_W      ACTIVITY        = GF_ACTIVITY_1500. ORK. ***move object info     move LS_EDIT-EBELN to LS_DRAD_WORK-OBJKY.     append LS_DRAD_WORK to LT_DRAD_WORK.   endloop. ***set data   call method OBJECT->PUT_DATA     exporting       FLT_VAL         = GF_VAL       TABLE_DRAD_WORK = LT_DRAD_WORK       TABLE_DRAD_DB   = LT_DRAD endform.                    " put_data 

3. Flow logic

 process before output.   module DYN_9000_PBO_INIT.   loop at GT_EDIT with control TAB_X1 cursor TAB_X1-CURRENT_LINE.     module DYN_9000_PBO_LOOP.   endloop. process after input.   loop at GT_EDIT.     chain.       field GT_EDIT-EBELN.       module DYN_9000_PAI_LOOP.     endchain.   endloop.   module DYN_9000_PAI_PUT_DATA. 

4. Screen painting

5. Create BADI implementation “ZPO_ATTACHMENT_TST” using SE19.

Add a filter value ‘EKKO’ make the BADI only effect on EKKO objects.

6. Input the program name and screen number into the “Subscreens” TAB

7. Implement following 3 methods

 method IF_EX_DOCUMENT_OBJ~GET_DATA.*” Export Gloabal data TABLE_DRAD_WORK[] = IF_EX_DOCUMENT_OBJ~TABLE_DRAD_WORK[]. DRAW = IF_EX_DOCUMENT_OBJ~DRAW. ACTIVITY = IF_EX_DOCUMENT_OBJ~ACTIVITY. TABLE_DRAD_DB[] = IF_EX_DOCUMENT_OBJ~TABLE_DRAD_DB. NO_ENQ_CHK = 'X'.endmethod. ************************************************************** method IF_EX_DOCUMENT_OBJ~PUT_DATA.*” Save Gloabal IF_EX_DOCUMENT_OBJ~TABLE_DRAD_WORK[] = TABLE_DRAD_WORK[]. IF_EX_DOCUMENT_OBJ~DRAW = DRAW. IF_EX_DOCUMENT_OBJ~ACTIVITY = ACTIVITY. IF_EX_DOCUMENT_OBJ~TABLE_DRAD_DB = TABLE_DRAD_DB[].*me->G_DOKOB_FILT = FLT_VAL.endmethod. ************************************************************** method IF_EX_DOCUMENT_OBJ~JUMP_TO_SCREEN.CALL TRANSACTION 'ME23N' AND SKIP FIRST SCREEN. RUN_NO_ACTION = 'X'.endmethod. 

8. Active the BADI implementation.

    Till now all the enhancement steps are down. Run CVXXN to test. Example CV04N can search documents with PO number:

How to invoke the DMS in applications

If you want PO applications to invoke DMS functionalities, you must enhance the application to add DMS codes. For example ME23n, User exits should be found to adding code like “ZPO_ATTACHMENT_TST“. You can define whether use a popup window or subscreen.

 

Fast Skip on SAP Document Management Service 02

New NetWeaver Information at SAP.com

Very Helpfull

 

 

User Rating: Be the first one !