Dear all,

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:

Capture.JPG

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)

Capture.JPG

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

     ‘<html>’

     ‘<body>’

     ‘<img src=”‘

    INTO lv_html.

  CONCATENATE http://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

      ‘” />’

      ‘</body>’

      ‘</html>’

    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’.

   ” Call the generated function module

   CALL FUNCTION fm_name

     EXPORTING

       /1bcdwb/docparams        = fp_docparams

       im_codeurl               = l_display_url1

       im_w                     = im_w

       im_h                     = im_h

*        IMPORTING

*         /1BCDWB/FORMOUTPUT    =

     EXCEPTIONS

       usage_error          = 1

       system_error         = 2

       internal_error       = 3.

   IF sy-subrc <> 0.

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

   ENDIF.

   ” Close the spool job

   CALL FUNCTION ‘FP_JOB_CLOSE’

*        IMPORTING

*         E_RESULT             =

     EXCEPTIONS

       usage_error          = 1

       system_error         = 2

       internal_error       = 3

       OTHERS               = 4.

   IF sy-subrc <> 0.

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

   ENDIF.

ENDFORM.                    “print_adobe

When you execute this report you will get an input screen where you can put the string you want in the barcode and two boxes to define the size of the barcode.

The final result of the report will look like:

Capture.JPG

Hopefully this document gives you an overview of the possibilities this technique offers inside Adobe Forms.

In Part 2 of this document I will show you how you can easily transform this project to use it with normal images and google charts.

The Google Charts API is open source and could be of high importance for your company.


Thanks for reading and keep following for updates.

To report this post you need to login first.

19 Comments

You must be Logged on to comment or reply to a post.

  1. MF Z

    Thank you for this awesome article,

    I got “Http 404 error” when clicking generate button QR Code Generator and DataMatrix Barcode Generator

    Got “Exception condition “HTTP_COMMUNICATION_FAILURE” raised.” when run to    http_client->receive( ).

    So I worried about the stability if using those on-line generate tools include google chart API, Is it possible to use Adobe form(or other not require installation method)

    to generate a picture so this can be used in smart form or script form?Currently I have a request to add DataMatrix into script form but have no idea, Thanks!

    (0) 
    1. Florian Henninger

      Hi MF…

      Yes it is possible, but there is a bit work to face. You have to create the barcode, afterwards you have to get the pdf-Stream and save it as an includetext. this includetext you have to include in your smartforms.

      Sounds easier, than it is 😉

      Regards

      Florian

      (0) 
      1. MF Z

        Thanks for your reply, I will try this later, I’m also trying postscript, this is another choice, but printer must support postscript first.

        (0) 
    2. Frederik Pena Post author

      HI MF,

      For the error you are are facing I think you should check your ICM server settings.

      Make sure that you opened the necessary ports to connect to the internet from your back-end. Using online API is always a risk, but when you use for example the google chart API I think that the chances of server being down are very low.

      Using it inside a smartform should not be that hard to manage as I already provide you with the PDF stream you could store it temporary and use it inside your smartform;

      I will try to write a new Document explaining how to achieve this by using my technique.

      Kind regards,

      Frederik

      (0) 
      1. MF Z

        Hi, Pena,

        I can get the stream from form(Xstring format, field fpformoutput-pdf),could you please tell me how to convert it to Bitmap(BMP)? I tried “SCMS_XSTRING_TO_BINARY” but failed.

        (0) 
        1. Frederik Pena Post author

          Hi MF,

          First of all sorry for my delayed response but I have been quite busy the last two weeks.

          I dont realy understand the purpose of your development. You want to store the generated PDF file as a BMP file ?

          I know of the existence of a function module “CONVER_OTF “that can convert your PDF stream to JPG file. Don’t know if this can be helpfull for you.

          I will dive into your problem this evening and will try to find you a good solution.

          Kind regards,

          Frederik Pena

          (0) 
          1. MF Z

            Thanks Pena, yes, I want to store the generated PDF file as a BMP file, so I can use this in the script form( because script form doesn’t support QR code so I want to generate from adobe form first then convert to BMP and upload it). I think “CONVERT_OTF is just for convert OTF to PDF.

            (0) 
            1. Frederik Pena Post author

              Hi MF,

              After some research I found that converting your PDF-stream to BMP format inside SAP will be very difficult without using external software plugins.

              Normally you should use the generated BMP stream of the barcode in the “convert” form of my tutorial. As you were telling me that you faced an error when running the “SCMS_XSTRING_TO_BINARY” , is it possible to specify the error it is giving you?

              Kind regards,

              Frederik

              (0) 
  2. S M SUDHEER KUMAR CHUNDURU

    Hi Fredrik Pena,

    I have seen your document. It was nice and well explained to how we can work with barcodes.

    But can you help me on the second part (Part2). Our client is looking for the same kind of requirement. Or could you please guide me to how we can include a google map image inside a adobe form.

    Thanks in Advance…..

    Regards,

    Sudheer Kumar Chunduru.

    (0) 

Leave a Reply