Skip to Content
Technical Articles

Getting an image from material master data and adding it into an adobe form

This post shows how to get an attachment, in this case an image, linked to a material that was uploaded to the material master data through Generic Object Services (or was archived), and add it on an adobe form.

The business object for Material is BUS1001006.

The GOS must be active for the business object and available on Material Master Maintenance transaction codes.

 

UPLOADING AN IMAGE TO MATERIAL MASTER DATA THROUGH GOS TOOLBAR

It can be done through TCODE MM02 (Change material):

 

Then, you will see the JPG image on the attachment list:

 

After this, execute the report and you will get the image using the method GET_GOS_ATTACHMENT.

If the image is archived, you can retrieve it from ArchiveLink using the method GET_ARCHIVE_ATTACHMENT.

 

The class code and the report sample code to execute the process are on the bottom of the page.

 

CLASS

Available methods on the local class:

METHOD DESCRIPTION
CONSTRUCTOR Create object
GET_ARCHIVE_ATTACHMENT Get ArchiveLink attachments
GET_GOS_ATTACHMENT Get Generic Object Services attachments

 

ADOBE FORM

Create an interface and a form on SFP TCODE.

 

Interface

Create an Interface with the importing parameters:

 

Form Context

Map on the context the importing parameters and adding a GRAPHIC that will be linked to the XSTRING field:

 

Form Layout

Build the layout:

 

Insert an image field and mark the check box “Embed Image Data”:

 

Bind the graphic content to the image field:

 

We will use the SAP logo, on this example.

Result after, the report execution:

 

Further information

Generic Object Services https://help.sap.com/saphelp_nw70ehp3/helpdata/en/4d/078bd464e05dc6e10000000a42189c/frameset.htm

Activating Generic Object Services Toolbar in SAP Objects https://blogs.sap.com/2012/11/21/activating-generic-object-services-toolbar-in-sap-objects/

Printing or Downloading Service For Object Attachments to local desktop https://blogs.sap.com/2013/08/18/printing-or-downloading-service-for-object-attachments-to-local-desktop/

Frequently asked questions about Generic Object Services (GOS) https://wiki.scn.sap.com/wiki/pages/viewpage.action?pageId=84181448

ArchiveLink https://help.sap.com/saphelp_nw70/helpdata/en/5e/566039b85f9443e10000000a114084/frameset.htm

 

TABLES

TOA01, TOA02, TOA03 – Link tables

SRGBTBREL – Relationships in GOS Environment

 

TCODES

MM01, MM02, MM03 – Material Master Maintenance transaction codes

OAC0 – Customizing Content Repositories

OAC2 – SAP ArchiveLink: Global document types

OAC3 – SAP ArchiveLink: Links for Content Repositories

SWO1 – Business Object Builder

 

To execute the SAMPLE REPORT:

Create a INCLUDE Z_LOCAL_CLASS_ATTACHMENTS.

Create a REPORT ZATTACHMENTS

Run the Report.

 

INCLUDE CODE (CLASS)

*&---------------------------------------------------------------------*
*& Include Z_LOCAL_CLASS_ATTACHMENTS
*&---------------------------------------------------------------------*
CLASS zcl_attachments DEFINITION.

  PUBLIC SECTION.

    METHODS constructor .
    METHODS get_archive_attachment
      IMPORTING
        VALUE(im_object_id)     TYPE saeobjid
        VALUE(im_ar_object)     TYPE saeobjart
        VALUE(im_reserve)       TYPE saereserve
      RETURNING
        VALUE(re_xstring_table) TYPE xstring_table .
    METHODS get_gos_attachment
      IMPORTING
        VALUE(im_object_instid) TYPE sibfboriid
        VALUE(im_object_typeid) TYPE saeanwdid
        VALUE(im_object_catid)  TYPE sibfcatid
        VALUE(im_role)          TYPE oblroltype
      RETURNING
        VALUE(re_xstring_table) TYPE xstring_table .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_attachments IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ATTACHMENTS->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD constructor.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ATTACHMENTS->GET_ARCHIVE_ATTACHMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_OBJECT_ID                   TYPE        SAEOBJID
* | [--->] IM_AR_OBJECT                   TYPE        SAEOBJART
* | [--->] IM_RESERVE                     TYPE        SAERESERVE
* | [<-()] RE_XSTRING_TABLE               TYPE        XSTRING_TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_archive_attachment.
    DATA: lt_connect_info    TYPE STANDARD TABLE OF toav0,
          lt_archivobject    TYPE STANDARD TABLE OF docs,
          lt_binarchivobject TYPE STANDARD TABLE OF tbl1024,
          lv_length          TYPE num12,
          lv_xstring         TYPE xstring.

    " Checking wheter the material image is archived on the link tables (TOA01, TOA02, TOA03)
    " Get material object id
    SELECT SINGLE *
      INTO @DATA(ls_arcdocid)
      FROM toa01
     WHERE object_id = @im_object_id
       AND ar_object = @im_ar_object
       AND reserve   = @im_reserve.

    IF sy-subrc NE 0.
      SELECT SINGLE *
        INTO ls_arcdocid
        FROM toa02
       WHERE object_id = im_object_id
         AND ar_object = im_ar_object
         AND reserve   = im_reserve.
    ENDIF.

    IF sy-subrc NE 0.
      SELECT SINGLE *
        INTO ls_arcdocid
        FROM toa03
       WHERE object_id = im_object_id
         AND ar_object = im_ar_object
         AND reserve   = im_reserve.
    ENDIF.

    IF sy-subrc = 0.
      " Recover image from archiveLink
      CALL FUNCTION 'ARCHIV_CONNECTINFO_GET_META'
        EXPORTING
          ar_object             = ls_arcdocid-ar_object
          object_id             = ls_arcdocid-object_id
          sap_object            = ls_arcdocid-sap_object
        TABLES
          connect_info          = lt_connect_info
        EXCEPTIONS
          error_connectiontable = 1
          OTHERS                = 2.

      CHECK sy-subrc = 0.

      " Link table
      LOOP AT lt_connect_info INTO DATA(ls_connect_info).
        " Bynary format Object
        CALL FUNCTION 'ARCHIVOBJECT_GET_BYTES'
          EXPORTING
            archiv_id                = ls_connect_info-archiv_id
            archiv_doc_id            = ls_connect_info-arc_doc_id
            document_type            = CONV saedoktyp( im_reserve )
            length                   = 0
            offset                   = 0
          IMPORTING
            length                   = lv_length
          TABLES
            archivobject             = lt_archivobject
            binarchivobject          = lt_binarchivobject
          EXCEPTIONS
            error_archiv             = 1
            error_communicationtable = 2
            error_kernel             = 3
            OTHERS                   = 4.


        IF sy-subrc = 0.
          " Convert Binary table to Xstring
          CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
            EXPORTING
              input_length = CONV i( lv_length )
            IMPORTING
              buffer       = lv_xstring
            TABLES
              binary_tab   = lt_binarchivobject
            EXCEPTIONS
              failed       = 1
              OTHERS       = 2.

           IF sy-subrc = 0.
              APPEND lv_xstring TO re_xstring_table.
           ENDIF.
        ENDIF. 

      ENDLOOP.
    ENDIF.
  ENDMETHOD.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_ATTACHMENTS->GET_GOS_ATTACHMENT
* +-------------------------------------------------------------------------------------------------+
* | [--->] IM_OBJECT_INSTID               TYPE        SIBFBORIID
* | [--->] IM_OBJECT_TYPEID               TYPE        SAEANWDID
* | [--->] IM_OBJECT_CATID                TYPE        SIBFCATID
* | [--->] IM_ROLE                        TYPE        OBLROLTYPE
* | [<-()] RE_XSTRING_TABLE               TYPE        XSTRING_TABLE
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD get_gos_attachment.
    DATA: ls_object        TYPE sibflporb,
          lt_links         TYPE obl_t_link,
          lt_contents_hex  TYPE TABLE OF solix,
          lv_document_id   TYPE so_entryid,
          ls_document_data TYPE sofolenti1,
          lv_xstring       TYPE xstring.

    " get the attachment through the business object using the Generic object services
    ls_object-typeid = im_object_typeid.
    ls_object-catid  = im_object_catid.
    ls_object-instid = im_object_instid.

    CALL METHOD cl_binary_relation=>read_links_of_binrel
      EXPORTING
        is_object   = ls_object
        ip_relation = cl_gos_api=>c_atta
        ip_role     = im_role
      IMPORTING
        et_links    = lt_links.

    LOOP AT lt_links INTO DATA(ls_links).
      lv_document_id = ls_links-instid_b.

      CALL FUNCTION 'SO_DOCUMENT_READ_API1'
        EXPORTING
          document_id                = CONV so_entryid( ls_links-instid_b )
        IMPORTING
          document_data              = ls_document_data
        TABLES
          contents_hex               = lt_contents_hex
        EXCEPTIONS
          document_id_not_exist      = 1
          operation_no_authorization = 2
          x_error                    = 3
          OTHERS                     = 4.

      IF sy-subrc = 0.
         " Convert Binary table to Xstring
         CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
           EXPORTING
             input_length = CONV i( ls_document_data-doc_size )
           IMPORTING
             buffer       = lv_xstring
           TABLES
             binary_tab   = lt_contents_hex
           EXCEPTIONS
             failed       = 1
             OTHERS       = 2.
         IF sy-subrc = 0.
            APPEND lv_xstring TO re_xstring_table.
         ENDIF.
       ENDIF.
  
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Sample Report code

*&---------------------------------------------------------------------*
*& Report ZATTACHMENTS
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zattachments.

INCLUDE z_local_class_attachments.

START-OF-SELECTION.
  DATA: lv_matnr TYPE matnr VALUE '000000000000000000'. " INSERT MATERIAL NUMBER HERE

  DATA(lo_attachments) = NEW zcl_attachments( ).

  " Search for the image on the ArchiveLink
  DATA(lt_xstring_table) = lo_attachments->get_archive_attachment(
                                                                   im_object_id = CONV #( lv_matnr ) " Material Number
                                                                   im_ar_object = <AR_OBJECT>        " Document type. Maintained on view TOAVE using SM30
                                                                   im_reserve   = 'JPG'              " Image extension (BMP,JPG)
                                                                  ).

  IF lt_xstring_table IS INITIAL.
    " OtherWise serach for the attachments linked to the Business Object
    lt_xstring_table = lo_attachments->get_gos_attachment(
                                                           im_object_instid = CONV #( lv_matnr ) " Material Number
                                                           im_object_typeid = 'BUS1001006'       " Business object - Standard Material
                                                           im_object_catid  = 'BO'               " Business Object
                                                           im_role          = 'GOSAPPLOBJ'       " Generic object services application object
                                                          ).
  ENDIF.

  CHECK lt_xstring_table IS NOT INITIAL.

  DATA: fm_name         TYPE rs38l_fnam,      " Name of Function Module
        fp_docparams    TYPE sfpdocparams,    " Parameters for Form Processing
        fp_outputparams TYPE sfpoutputparams, " Processing Output Parameter
        fp_formoutput   TYPE fpformoutput,    " PDF file
        fp_result       TYPE sfpjoboutput.

  CONSTANTS: co_formname TYPE fpname               VALUE 'ZTESTE_MATERIAL_IMAGE'.

  fp_outputparams-getpdf    = abap_true.
  fp_outputparams-nopdf     = abap_false.
  fp_outputparams-nopreview = abap_true.
  fp_outputparams-nodialog  = abap_true.

  " Sets the output parameters and opens the spool job
  CALL FUNCTION 'FP_JOB_OPEN'
    CHANGING
      ie_outputparams = fp_outputparams
    EXCEPTIONS
      cancel          = 1
      usage_error     = 2
      system_error    = 3
      internal_error  = 4
      OTHERS          = 5.

  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  " Get the name of the generated function module
  CALL FUNCTION 'FP_FUNCTION_MODULE_NAME'
    EXPORTING
      i_name     = co_formname
    IMPORTING
      e_funcname = fm_name.

  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  CALL FUNCTION fm_name
    EXPORTING
      /1bcdwb/docparams  = fp_docparams
      im_matnr           = lv_matnr
      im_image_x         = lt_xstring_table[ 1 ]
    IMPORTING
      /1bcdwb/formoutput = fp_formoutput
    EXCEPTIONS
      usage_error        = 1
      system_error       = 2
      internal_error     = 3.

  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  " Close the spool job
  CALL FUNCTION 'FP_JOB_CLOSE'
    IMPORTING
      e_result       = fp_result
    EXCEPTIONS
      usage_error    = 1
      system_error   = 2
      internal_error = 3
      OTHERS         = 4.

  IF sy-subrc <> 0.
    RETURN.
  ENDIF.

  " Download the form
  DATA: lv_filename    TYPE string,
        lv_path        TYPE string,
        lv_fullpath    TYPE string,
        lv_user_action TYPE i.

  CALL METHOD cl_gui_frontend_services=>file_save_dialog
    EXPORTING
      file_filter               = '*.pdf'
      default_extension         = 'pdf'
      default_file_name         = 'file_name'
      initial_directory         = 'C:\TEMP\'
    CHANGING
      filename                  = lv_filename
      path                      = lv_path
      fullpath                  = lv_fullpath
      user_action               = lv_user_action
    EXCEPTIONS
      cntl_error                = 1
      error_no_gui              = 2
      invalid_default_file_name = 3
      not_supported_by_gui      = 4
      OTHERS                    = 5.

  DATA(lt_pdf_content) = cl_document_bcs=>xstring_to_solix( ip_xstring = fp_formoutput-pdf ).

  CALL METHOD cl_gui_frontend_services=>gui_download
    EXPORTING
      filename                = lv_filename
      filetype                = 'BIN'
    CHANGING
      data_tab                = lt_pdf_content
    EXCEPTIONS
      file_not_found          = 1
      file_write_error        = 2
      filesize_not_allowed    = 3
      invalid_type            = 4
      no_batch                = 5
      gui_refuse_filetransfer = 8
      OTHERS                  = 10.
4 Comments
You must be Logged on to comment or reply to a post.
  • Thanks for sharing.

    I believe some more detailed explanation could’ve been added to make it more clear what exactly is happening here. I’ve already had some experience with GOS objects and Adobe forms but the readers without specific knowledge (which is probably the target audience for such blog) might have trouble connecting the dots.

    More specifically the blog could use:
    – some general information about GOS, e.g. what it is, how it works, and why do we have to jump through so many hoops;
    – an overview of the steps involved to connect the dots between GOS attachment, program code, and form (GOS attachment is read as binary content, data is placed in XSTRING variable which is then passed to the form as a parameter).

    In the sample code, I’d recommend adding a parameter for material. Also the use of FMs and consequent download could be a bit confusing (it’s not directly related to the main task). For demonstration purposes I’d just go with a simplest form call in print preview mode or something like that.

    Programming style is a bit inconsistent too. There is some 7.4 syntax but then the old full form of CALL METHOD. Prefixes in the variable names are also no longer recommended but if you use them then at least be consistent. Personally, I believe when sharing the code it’s good to make it as presentable as possible.

    There are also header styles available in the blog editor (just like in Word), no need to write the headers in all caps.