Dear all,

Create Dynamic resizable Datamatrix barcode: Using the default barcode option inside ADOBE forms comes with lots of limitations.

One major issue is the lack of scaling the barcodes to a large format.

The default usage of Adobe Forms inside SAP is also very complicated.

With this tutorial I want to provide you a way of having the freedom to use any kind of image/ barcode inside your ADOBE Forms / Smartforms.

In this Tutorial I will focus on the usage of barcodes inside your Adobe forms.

Part 2 will show you an example of using Dynamic Charts based on the Google Maps API and using Web images inside your Forms.

One of the major advantages about this technique is the flexibility you achieve by using it.

Lots of other options can be implemented by using this.

Procedure

In the next Chapters I will give you a clear explanation about how to use and implement this technique.

 

Transactions used:

  • Development   : se80
  • Adobe Forms  : SFP

 

1.Create Adobe Form Interface

Transaction: SFP

Define 3 import parameters inside your interface:

Create Dynamic resizable Datamatrix barcode / images / Charts in Adobe Forms (Part 1 )

2. Create Adobe Form

Use the previously define interface.

Create a Graphic inside the context tab

Create the two variables (by drag&drop from the context node)

Create Dynamic resizable Datamatrix barcode / images / Charts in Adobe Forms (Part 1 )

Set the URL of this Graphic component equal to the import parameter

(Can be done by drag and drop from import list right to the Graphic URL field)

Now one thing left to do is drag and drop the Graphic in the layout view to the Adobe Form and set the parameter “Embed Image Data” to checked.

This is important because otherwise the image won’t be embedded when save the PDF to local PC.

 

To make sure the image has the width and height you entered on the main screen we will need to use some Formcalc inside our Adobe Form.

 

 ----- data.#subform[0].GRAPHIC[0]::initialize: - (JavaScript, client) ------------------------------ data.#subform[0].GRAPHIC.w = $record.IM_W data.#subform[0].GRAPHIC.h = $record.IM_H; 

Now I will go through the code to create a dynamic chart and start using it inside an Adobe Form.

3. Code

To make the code easy to read I divided the process in 5 steps:

  • create_chart         : Creating the barcode dynamical should be done down here
  • download_chart   : Download the barcode to the requested type
  • convert_chart      : Convert the barcode to a xstring to store
  • upload_chart        : Upload the image to the icm cache
  • print_adobe          : Call the requested adobe form

These actions are coded inside different forms that will be called form the Main screen of the program and are stored in a separate include file.

Main Program

In this program we will define the top include and form include.

At the start of-selection we will start the process from creating a dynamic barcode to display the Adobe Form.

REPORT  ZTRAINING_FPT_BAR.

INCLUDE ZTRAINING_FPT_BAR_TOP.    ” global Data

INCLUDE ZTRAINING_FPT_BAR_FORM.   “Forms

SELECTION-SCREEN BEGIN OF BLOCK program WITH FRAME TITLE title1.

   SELECTION-SCREEN BEGIN OF BLOCK code1 WITH FRAME TITLE title2.

     PARAMETERS:pc_value         TYPE string DEFAULT ‘123456789’.

   SELECTION-SCREEN END OF BLOCK code1.

   SELECTION-SCREEN BEGIN OF BLOCK code2 WITH FRAME TITLE title3.

     PARAMETERS:pc_h             TYPE string DEFAULT ‘4,5’,

                             pc_w             TYPE string DEFAULT ‘4,5’ .

   SELECT IO-SCREEN END OF BLOCK code2.

SELECTION-SCREEN END OF BLOCK program.

INITIALIZATION.

title1 = ‘Dynamic Barcode resizer’.

title2 = ‘Please enter a value for the barcode’.

title3 = ‘Please enter a height and width for the barcode (in inch)’.

START-OF-SELECTION .

“Create code 1

     PERFORM create_code  USING

                                 pc_value

                          CHANGING

                                 url1. “Creating the chart dynamical should be done down here

     PERFORM download_code using

                                 url1. “Download the chart to the requested type

     PERFORM convert_code.  “Convert the chart to a xstring to store

     PERFORM upload_code  CHANGING

                                 l_display_url1

                                 l_guid1.   “Upload the image to the icm cache

     PERFORM print_adobe USING   l_display_url1

                                 pc_w

                                 pc_h.

Top Include

 

In this file all the needed variables to create the Adobe form can be found.

I have tried to structure them in the right way so you can figure out quite fast where they are used.

“Class references

DATA : http_client        TYPE REF TO if_http_client.

DATA:  g_html_control     TYPE REF TO cl_gui_html_viewer .

DATA:  l_igs_imgconv      TYPE REF TO cl_igs_image_converter,

        l_igs_ce           TYPE REF TO cl_igs_chart_engine,

        l_cached_response  TYPE REF TO if_http_response.

“Added Vars to store the chart in the system.

DATA:  i_html             TYPE w3htmltabtype,

        g_url              TYPE w3url,

        l_imagemap_length  TYPE w3param-cont_len,

        l_image_mime       TYPE w3mimetabtype,

        l_image_size       TYPE w3param-cont_len,

        l_image_type       TYPE w3param-cont_type,

        l_img_blob         TYPE w3mimetabtype,

        l_img_size         TYPE w3param-cont_len,

        l_bmp_xstream      TYPE xstring,

        l_app_type         TYPE string,

        l_guid1            TYPE guid_32,

        lv_host            TYPE string,

        lv_port            TYPE string,

        lv_protocol        TYPE string,

        l_display_url1     TYPE string.

“Vars needed to convert to mimetabtype

DATA : url1               TYPE String.

DATA : url2               TYPE String.

DATA : l_str_length       TYPE i.

DATA : content            TYPE xstring.

DATA : mime               TYPE  w3mimetabtype.

DATA : l_content_length   TYPE  i.

“Vars needed to open the adobe form

DATA: fm_name             TYPE rs38l_fnam,      ” CHAR 30 0 Name of Function Module

       fp_docparams        TYPE sfpdocparams,    ” Structure  SFPDOCPARAMS Short Description  Form Parameters for Form Processing

       fp_outputparams     TYPE sfpoutputparams.

Form Include

 

Create_code

 

In this step we will create the Barcode based on the input at the selection screen.

For this we will be using the following API that can be found at  :QR Code Generator and DataMatrix Barcode Generator ( Appreciate the work they put into it so donations are welcome )

FORM create_code

                                USING

                                        im_value  TYPE string

                                CHANGING

                                        url             TYPE string.

  “Local data

   DATA: lv_html         TYPE string.

   CONCATENATE

     ‘’

     ‘’

     Create Dynamic resizable Datamatrix barcode / images / Charts in Adobe Forms (Part 1 )

    INTO lv_html.

  CONCATENATE ‘https://it.visualead.com:8080/invx.com/code/datamatrix/?code=‘

               im_value

               ‘&fg=%23000000&bg=%23ffffff&width=352&height=352’

        INTO url.

   CONCATENATE

      lv_html

      url

      ‘” />’

      ‘’

      ‘’

    INTO lv_html .

   “Store the link  in table

   CALL FUNCTION ‘HR_EFI_CONVERT_STRING_TO_TABLE’

     EXPORTING

       i_string        = lv_html

       i_tabline_length = 255

     TABLES

       et_table        = i_html.

ENDFORM.                    “Create_code

 

Download Chart

 

To be able to use the Graphic in the system we first need to download the picture as a mimetabtype.

For I created a http_client instance  to fetch the object. By calling the SAP FM “RSFO_XSTIRNG_TO_MIME” we can save the chart as a mimetabtype.

FORM download_code USING url.

   CLEAR:http_client.

   CLEAR: content.

   CLEAR: l_str_length.

   CLEAR: mime.

   CALL METHOD cl_http_client=>create_by_url

     EXPORTING

       url               = url

     IMPORTING

       client            = http_client

     EXCEPTIONS

       argument_not_found = 1

       plugin_not_active = 2

       internal_error    = 3

       OTHERS            = 4.

   IF sy-subrc = 0.

     http_client->send( ).

     http_client->receive( ).

     content = http_client->response->get_data( ).

     http_client->close( ).

     l_str_length = XSTRLEN( content ).

     CALL FUNCTION ‘RSFO_XSTRING_TO_MIME’

       EXPORTING

         c_xstring = content

         i_length = l_str_length

       TABLES

         c_t_mime = mime.

   ENDIF.

ENDFORM.                    “DOWNLOAD_CODE

 

Convert_code

 

In SAP we cannot reference the mimetabtype directly to a graphic object.

For this we need to convert the mimetabtype to an Xstring.
SAP already provided a FM to do this “SCMS_BINARY_XSTIRNG”

 

FORM convert_code .

   CLEAR: l_bmp_xstream.

   CLEAR: l_igs_imgconv.

   CLEAR: l_img_blob.

   CREATE OBJECT l_igs_imgconv.

   l_igs_imgconv->input = ‘image/png’.

   l_igs_imgconv->output = ‘image/bmp’.

   CALL METHOD l_igs_imgconv->set_image

     EXPORTING

       blob     = mime

       blob_size = l_content_length.

   CALL METHOD l_igs_imgconv->execute

     EXCEPTIONS

       communication_error = 1

       internal_error     = 2

       external_error     = 3

       OTHERS             = 4.

   IF sy-subrc IS INITIAL.

     CALL METHOD l_igs_imgconv->get_image

       IMPORTING

         blob     = l_img_blob

         blob_size = l_img_size.

     CALL FUNCTION ‘SCMS_BINARY_TO_XSTRING’

       EXPORTING

         input_length      = l_img_size

      IMPORTING

         buffer            = l_bmp_xstream

       TABLES

         binary_tab        = l_img_blob

      EXCEPTIONS

        FAILED            = 1

        OTHERS            = 2.

     IF sy-subrc <> 0.

       MESSAGE ‘Problem with the conversion ‘ TYPE ‘E’.

     ENDIF.

   ENDIF.

ENDFORM.                    ” CONVERT_CODE

 

After running the previous routine we can use the Xstring in SAP screens.
Unfortunately to embed the images/charts inside an ADOBE FORM we need to upload the object to the ICM server.

For this reason the fourth form method “upload_chart” is created.

Upload_code

This method will upload the image to the ICM cache server for a specified time.
This gives us the possibility to use the images inside ADOBE FORMS.
The objects will be automatically released from the cache server after the timeout expires. (The timeout time is a personal decision)

FORM upload_code CHANGING l_display_url

                            l_guid.

   CLEAR: l_cached_response.

   CREATE OBJECT l_cached_response

     TYPE

       cl_http_response

     EXPORTING

       add_c_msg       = 1.

   l_cached_response->set_data( l_bmp_xstream ).

   l_app_type = ‘image/jpeg’.

   l_cached_response->set_header_field(

         name = if_http_header_fields=>content_type

         value = l_app_type ).

   “Setting the Response Status.

   l_cached_response->set_status( code  = 200

                                  reason = ‘OK’).

   “Set the cached timeout

   l_cached_response->server_cache_expire_rel( expires_rel = 3600 ).

   ” Create a unique URL for the object

   CALL FUNCTION ‘GUID_CREATE’

     IMPORTING

       ev_guid_32 = l_guid.

   ” Getting the host , port and Protocol of the server

   CALL METHOD cl_http_server=>get_location

     EXPORTING

       server      = cl_wdr_task=>server

     IMPORTING

       host        = lv_host

       port        = lv_port

       out_protocol = lv_protocol.

   “Create the store url

     CONCATENATE

      lv_protocol ‘://’ lv_host ‘:’ lv_port ‘/sap/bc/fp/’

      l_guid ‘.JPG’

      INTO l_display_url.

   ” Upload the generated URL in the cache

   cl_http_server=>server_cache_upload( url     = l_display_url

                                        response = l_cached_response ).

ENDFORM.                    “UPLOAD_CODE

After this routine, the image/ chart will be available on the ICM Cache server and can be embedded inside the Adobe Form. In my Demo Program I created another Form to call the Adobe Form and ask you for a print preview.

This can also be automated by using job profiles ( * will create another post about job profiles in future)

Print_Adobe

This form will call the previously created Adobe Form and pass the requested import parameters to it.

FORM print_adobe USING l_display_url1

                        im_w

                        im_h.

  “Concatenate the inch to the value

     CONCATENATE im_w ‘in’ INTO im_w.

     CONCATENATE im_h ‘in’ INTO im_h.

  “Passed as a string so needed to remove the empty spaces and replace the , with .

     REPLACE all OCCURRENCES OF ‘,’ in im_w WITH ‘.’ .

     REPLACE all OCCURRENCES OF ‘,’ in im_h WITH ‘.’ .

     CONDENSE im_w NO-GAPS .

     CONDENSE im_h NO-GAPS.

   “Sets the output parameters and opens the spool job

   CALL FUNCTION ‘FP_JOB_OPEN’                   “& Form Processing: Call Form

     CHANGING

       ie_outputparams = fp_outputparams

     EXCEPTIONS

       cancel         = 1

       usage_error    = 2

       system_error   = 3

       internal_error = 4

       OTHERS         = 5.

   IF sy-subrc <> 0.

     MESSAGE  ‘Proble with Adobe PDF’ TYPE ‘A’.

   ENDIF.

   ” Get the name of the generated function module

   CALL FUNCTION ‘FP_FUNCTION_MODULE_NAME’           “& Form Processing Generation

     EXPORTING

       i_name    = ‘ZTRAINING_FPT_BEK_BAR_FORM’

     IMPORTING

       e_funcname = fm_name.

   IF sy-subrc <> 0.

     MESSAGE  ‘Proble with Adobe PDF’ TYPE ‘A’.

   ENDIF.

   ” Language and country setting (here US as an example)

   fp_docparams-langu  = ‘E’.

   fp_docparams-country = ‘US’<span