Fast Skip on SAP Document Management Service 01
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
- CMS is a layer to connect with storages. Storages are: HTTP content server, SAP database, RFC storage system, logical repository, and structure repository.
- 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:
- Components administrate content
- Physical documents administrate documents
- 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
- Click “CS Admin” to create the content repository connections. The driver should be set to “MaxDB”
- On the “Certificates” page, click the button to send certificates from SAP ABAP to Content Server.
- On the Overview Tab, make sure the repository is on running status.
- 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