Adjuntar/Anexar documentos en transacciones

Procedo a dar mi primer aporte a este nuestro foro.

La cuestión es que hace unos días salió la necesidad de adjuntar una imagen de un escaneo a un cliente y que fuese visible desde la transacción XD03 o XD02, en la vista de anexos. Viendo la variedad de código desfuncional colgado en la red, me adentré a investigar por mi cuenta he hice la siguiente plantilla, donde he despersonalizado los errores:

  DATA: lt_list                TYPE TABLE OF epsfili,
        ls_list                TYPE epsfili,
        lv_read                TYPE string,
        lv_file                TYPE string,
        lv_path                TYPE epsf-epsdirnam,
        ls_xstring             TYPE xstring,
        lv_doc_name            TYPE string,
        lv_extension           TYPE string,
        lt_file                TYPE STANDARD TABLE OF soli,
        lv_length              TYPE i,
        lv_full_path           TYPE string,
        ls_object              TYPE borident,
        lt_content             TYPE STANDARD TABLE OF soli,
        ls_obj_id              TYPE soodk,
        ls_obj_data            TYPE sood1,
        lv_desc                TYPE so_obj_des,
        lt_objhead             TYPE STANDARD TABLE OF soli,
        lv_offset              TYPE i,
        ls_fol_id              TYPE soodk,
        ls_folmem_k            TYPE sofmk,
        ls_note                TYPE borident,
        lv_ep_note             TYPE borident-objkey,
        lv_name                TYPE epsfilnam,
        lo_exc                 TYPE REF TO zcx_error_rf.

  FIELD-SYMBOLS: <fs_file> TYPE soli.

	"Directorio donde se encuentra el fichero
  lv_path = '/rfdir/ourput'.
  lv_file = '/rfdir/ourput/'.

  CALL FUNCTION 'EPS_GET_DIRECTORY_LISTING'
    EXPORTING
      dir_name               = lv_path
    TABLES
      dir_list               = lt_list
    EXCEPTIONS
      invalid_eps_subdir     = 1
      sapgparam_failed       = 2
      build_directory_failed = 3
      no_authorization       = 4
      read_directory_failed  = 5
      too_many_read_errors   = 6
      empty_directory_list   = 7
      OTHERS                 = 8.
  IF sy-subrc <> 0.
"Error
  ENDIF.
	
	"Extensión del archivo a adjuntar. Se puede poner casi cualquiera
  lv_extension = '.jpg'.
  
  CONCATENATE reservation '_' kunnr lv_extension INTO lv_name.

  READ TABLE lt_list INTO ls_list WITH KEY name = lv_name.
  IF sy-subrc = 0.

    CONCATENATE  lv_file ls_list-name INTO lv_read.

    OPEN DATASET lv_read FOR INPUT IN BINARY MODE.

    TRY.
        READ DATASET lv_read INTO ls_xstring.

        lv_doc_name = ls_list-name.

        TRANSLATE lv_doc_name TO UPPER CASE.

*   Convertimos el xstring con los datos binario en una tabla con los datos binarios.
        CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
          EXPORTING
            buffer        = ls_xstring
          IMPORTING
            output_length = lv_length
          TABLES
            binary_tab    = lt_file.

        MOVE lv_doc_name TO lv_full_path.

		"Nombre del archivo a adjuntar . Ejemplo: "archivo.jpg"
		CONCATENATE lv_file reservation '_' kunnr lv_extension INTO lv_file.

        MOVE lv_full_path TO lv_desc.
		
		"Campos clave del cliente. Aquí iria concatenado si tiene mas de un campo clave la tabla de maestro
        ls_object-objkey = kunnr.
		"Tabla de maestro del cliente
        ls_object-objtype =  'KNA1'.

        CALL FUNCTION 'SO_CONVERT_CONTENTS_BIN'
          EXPORTING
            it_contents_bin = lt_file[]
          IMPORTING
            et_contents_bin = lt_content[].

        CALL FUNCTION 'SO_FOLDER_ROOT_ID_GET'
          EXPORTING
            region    = 'B'
          IMPORTING
            folder_id = ls_fol_id
          EXCEPTIONS
            OTHERS    = 1.

        ls_obj_data-objsns = 'O'.
        ls_obj_data-objla = sy-langu.
        ls_obj_data-objdes = lv_desc.

		"Extensión del archivo
        ls_obj_data-file_ext = 'jpg'.

        ls_obj_data-objlen = lines( lt_content ) * 255.

        CALL FUNCTION 'SO_OBJECT_INSERT'
          EXPORTING
            folder_id             = ls_fol_id
            object_type           = 'EXT'
            object_hd_change      = ls_obj_data
          IMPORTING
            object_id             = ls_obj_id
          TABLES
            objhead               = lt_objhead
            objcont               = lt_content
          EXCEPTIONS
            active_user_not_exist = 35
            folder_not_exist      = 6
            object_type_not_exist = 17
            owner_not_exist       = 22
            parameter_error       = 23
            OTHERS                = 1000.

        IF sy-subrc = 0 AND ls_object-objkey IS NOT INITIAL.
          ls_folmem_k-foltp = ls_fol_id-objtp.
          ls_folmem_k-folyr = ls_fol_id-objyr.
          ls_folmem_k-folno = ls_fol_id-objno.
          ls_folmem_k-doctp = ls_obj_id-objtp.
          ls_folmem_k-docyr = ls_obj_id-objyr.
          ls_folmem_k-docno = ls_obj_id-objno.
          CONCATENATE ls_fol_id ls_obj_id INTO lv_ep_note.
          ls_note-objtype = 'MESSAGE'.
          ls_note-objkey = lv_ep_note.

          CALL FUNCTION 'BINARY_RELATION_CREATE' 
            EXPORTING
              obj_rolea    = ls_object
              obj_roleb    = ls_note
              relationtype = 'ATTA'
            EXCEPTIONS
              OTHERS       = 1.

          CALL FUNCTION 'BINARY_RELATION_CREATE_COMMIT'
            EXPORTING
              obj_rolea    = ls_object
              obj_roleb    = ls_note
              relationtype = 'ATTA'
            EXCEPTIONS
              OTHERS       = 1.


          IF sy-subrc IS INITIAL.
*            DELETE DATASET wl_read."Si se quiere eliminar el archivo después
          ELSE.
            "Error
          ENDIF.
        ELSE.
          "Error
        ENDIF.

      CATCH cx_sy_file_open.
        "Error
    ENDTRY.
    CLOSE DATASET lv_read.
  ELSE.
    "Error
  ENDIF.


Espero que les sirva de ayuda

7 Me gusta