Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
vincezk
Advisor
Advisor

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