Showing posts with label SMARTFORM. Show all posts
Showing posts with label SMARTFORM. Show all posts

Tuesday, May 19, 2015

VDA Modulus 43 method of Data Matrix ECC200

From time to time we all have to fulfill some technical norm. Concerning Data Matrix code ECC200 - VDA label norm there is no exception. Once I had to code this norm requirement, simple task to get security sign of all DMC content. So why to discover a wheel again? :) Check my approach below.

VDA requirement says

The check digit is calculated with the Modulus 43 method:
For this purpose the numeric values of all characters transferred (without control characters) are
added and the sum is divided by 43.

The remaining balance is converted into a character again and transferred in the data record as a
check digit. 

Example: the “12345ABCDE” string makes the check digit W. 1+2+3+4+5+10+11+12+13+14 = 75 
--> 75 : 43 = 1 Rest 32 -> 32 equals the W character.



I put some simple subroutine into SF to add one DataMatrix code item.



Later on subroutine for modulus 43.




The actual coding looks like this


*&---------------------------------------------------------------------*
*&      Form  get_check_code
*&---------------------------------------------------------------------*
*       get VDA security check character
*----------------------------------------------------------------------*
*      -->LV_INPUTDATA_STR  text
*      -->LV_CHECK_CHAR     text
*----------------------------------------------------------------------*
FORM get_check_code
      USING
          lv_inputdata_str TYPE string
      CHANGING
          lv_check_char    TYPE /fit/lwert.

  TYPES: BEGIN OF ty_translation,
            input TYPE c1,
            value TYPE i,
         END OF ty_translation.

  DATA: lt_translations TYPE STANDARD TABLE OF ty_translation,
        ls_translation LIKE LINE OF lt_translations.

  CONSTANTS cv_diviser TYPE i VALUE 43.

  ls_translation-input = '0'.
  ls_translation-value = 0.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '1'.
  ls_translation-value = 1.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '2'.
  ls_translation-value = 2.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '3'.
  ls_translation-value = 3.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '4'.
  ls_translation-value = 4.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '5'.
  ls_translation-value = 5.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '6'.
  ls_translation-value = 6.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '7'.
  ls_translation-value = 7.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '8'.
  ls_translation-value = 8.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '9'.
  ls_translation-value = 9.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'A'.
  ls_translation-value = 10.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'B'.
  ls_translation-value = 11.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'C'.
  ls_translation-value = 12.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'D'.
  ls_translation-value = 13.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'E'.
  ls_translation-value = 14.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'F'.
  ls_translation-value = 15.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'G'.
  ls_translation-value = 16.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'H'.
  ls_translation-value = 17.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'I'.
  ls_translation-value = 18.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'J'.
  ls_translation-value = 19.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'K'.
  ls_translation-value = 20.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'L'.
  ls_translation-value = 21.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'M'.
  ls_translation-value = 22.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'N'.
  ls_translation-value = 23.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'O'.
  ls_translation-value = 24.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'P'.
  ls_translation-value = 25.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'Q'.
  ls_translation-value = 26.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'R'.
  ls_translation-value = 27.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'S'.
  ls_translation-value = 28.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'T'.
  ls_translation-value = 29.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'U'.
  ls_translation-value = 30.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'V'.
  ls_translation-value = 31.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'W'.
  ls_translation-value = 32.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'X'.
  ls_translation-value = 33.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'Y'.
  ls_translation-value = 34.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = 'Z'.
  ls_translation-value = 35.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '-'.
  ls_translation-value = 36.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '.'.
  ls_translation-value = 37.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = ' '.
  ls_translation-value = 38.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '$'.
  ls_translation-value = 39.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '/'.
  ls_translation-value = 40.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '+'.
  ls_translation-value = 41.
  APPEND ls_translation TO lt_translations.

  ls_translation-input = '%'.
  ls_translation-value = 42.
  APPEND ls_translation TO lt_translations.
*
  TRANSLATE lv_inputdata_str TO UPPER CASE.

  DATA: lv_char   TYPE c,
        lv_offset TYPE syindex,
        lv_sum    TYPE i,
        lv_rest   TYPE i.

  " get sum of character values
  DO strlen( lv_inputdata_str ) TIMES.
    lv_offset = sy-index - 1.
    lv_char = lv_inputdata_str+lv_offset.

    IF lv_char IS NOT INITIAL.
      CLEAR ls_translation.
      READ TABLE lt_translations WITH KEY input = lv_char INTO ls_translation.
      IF sy-subrc EQ 0.
        lv_sum = lv_sum + ls_translation-value.
      ENDIF.
    ENDIF.
  ENDDO.

  " get proper 43 return code
  IF lv_sum NE 0.
    lv_rest = lv_sum MOD cv_diviser.
    CLEAR ls_translation.
    READ TABLE lt_translations WITH KEY value = lv_rest INTO ls_translation.
    IF sy-subrc EQ 0.
      lv_check_char = ls_translation-input.
    ENDIF.
  ENDIF.
ENDFORM.                    "get_check_code





Friday, August 29, 2014

HTML Email with tables generated by SmartForm

Intro

There are various possibilities how to work with emails in SAP. Previously I used some function module. When I obtained a task to prepare an email message with some log info content e.g. this job passed the other failed. I decided to create a HTML email message with nice colors, green for passed, red for failed tasks.

At first I decided to use Nguyen Van Thao's pattern. It uses CL_BCS class and SF. I used it by a bit by my own way. So let me introduce a clone with tables inside the smart form + some my experience notes.

Content generator Class

There is class responsible for the filling out needed tables which should be displayed inside the email. I just took a real example from my work.

*----------------------------------------------------------------------*
*       CLASS lcl_manager_email DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_manager_email DEFINITION.
  PUBLIC SECTION.
    METHODS: constructor
              IMPORTING
                io_data_sel  TYPE REF TO lcl_data_sel
                io_data_user TYPE REF TO lcl_data_user,
             send_email_log
              IMPORTING iv_subject TYPE so_obj_des
              RAISING lcx_msg_exception.

  PRIVATE SECTION.
    DATA: o_data_sel  TYPE REF TO lcl_data_sel,
          o_data_user TYPE REF TO lcl_data_user.

    METHODS: get_mail_body
                RETURNING value(rt_soli) TYPE soli_tab
                RAISING lcx_msg_exception. " get mail body from Smart form

ENDCLASS.                    "lcl_manager_email DEFINITION

*----------------------------------------------------------------------*
*       CLASS lcl_manager_email IMPLEMENTATION
*----------------------------------------------------------------------*
* Any email stuff
*----------------------------------------------------------------------*
CLASS lcl_manager_email IMPLEMENTATION.

  METHOD constructor.
    o_data_sel  = io_data_sel.
    o_data_user = io_data_user.
  ENDMETHOD.                    "constructor

  METHOD send_email_log.
    " Send message only in case of real action
    IF ( o_data_sel->v_locka IS NOT INITIAL )    " do admin lock
        OR ( o_data_sel->v_lockl IS NOT INITIAL )  " do local lock
        OR ( o_data_sel->v_vali  IS NOT INITIAL ). " set validation

      DATA: lo_send_request TYPE REF TO cl_bcs,
            lo_document     TYPE REF TO cl_document_bcs,
            lo_recipient    TYPE REF TO if_recipient_bcs,
            lo_sender       TYPE REF TO cl_sapuser_bcs,
            lt_soli         TYPE soli_tab,
            lv_sent_flag    TYPE abap_bool,
            lx_oref         TYPE REF TO lcx_msg_exception,
            lx_bcf          TYPE REF TO cx_bcs,
            lv_msg          TYPE string.

      lt_soli = me->get_mail_body( ).

      " Instantinate CL_BCS and specify options
      TRY .
          " Create persistent
          lo_send_request = cl_bcs=>create_persistent( ).

          " Email FROM
          lo_sender = cl_sapuser_bcs=>create( sy-uname ).
          " Add sender to send request
          CALL METHOD lo_send_request->set_sender
            EXPORTING
              i_sender = lo_sender.

          " Email TO
          lo_recipient = cl_cam_address_bcs=>create_internet_address( o_data_sel->v_email ).
          " Add recipient to send request
          CALL METHOD lo_send_request->add_recipient
            EXPORTING
              i_recipient = lo_recipient
              i_express   = 'X'.

          " Email BODY from SmartForm
          lo_document = cl_document_bcs=>create_document(
              i_type        = 'HTM'
              i_subject     = iv_subject
              i_text        = lt_soli ).
          " Add document to send request
          CALL METHOD lo_send_request->set_document( lo_document ).

          " Send email
          lo_send_request->set_send_immediately( i_send_immediately = abap_true ).

          lv_sent_flag = lo_send_request->send( i_with_error_screen = 'X' ).
          IF lv_sent_flag EQ abap_false.
            RAISE EXCEPTION TYPE lcx_msg_exception
              EXPORTING iv_text =  'Error Sending Email!'.
          ENDIF.

          "Commit to send email
          COMMIT WORK.

        CATCH cx_bcs INTO lx_bcf.
          RAISE EXCEPTION lx_bcf.
      ENDTRY.
    ENDIF.
  ENDMETHOD.                    "send_email_log

  METHOD get_mail_body.

*---Data declaration
    DATA: lt_lines TYPE TABLE OF tline,
          ls_line  TYPE tline,
          ls_soli  TYPE soli.
    DATA: lv_fname      TYPE rs38l_fnam,
          ls_job_output TYPE ssfcrescl. "Structure to return value at the end of form printing
    DATA: ls_ctrl_form  TYPE ssfctrlop, "Smart Form Control Structure
          ls_output_opt TYPE ssfcompop. "Smart Form Transfer Options

*---Pass data to Smartforms to receive itab of HTML Email

    "Get Smart Form Function Module Name
    CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
      EXPORTING
        formname           = cv_sf_htm_mail
      IMPORTING
        fm_name            = lv_fname
      EXCEPTIONS
        no_form            = 1
        no_function_module = 2
        OTHERS             = 3.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE lcx_msg_exception
        EXPORTING is_syst = sy.
    ENDIF.

    "Spool parameters
    ls_output_opt-tdimmed = 'X'.      "Print Immediately (Print Parameters)
    ls_output_opt-tddelete = 'X'.     "Delete After Printing (Print Parameters)
    ls_output_opt-tdlifetime = 'X'.   "Spool Retention Period (Print Parameters)
    ls_output_opt-tddest = 'LOCL'.    "Spool: Output device
    ls_output_opt-tdprinter = 'SWIN'. "Spool: Device type name
    ls_ctrl_form-no_dialog = 'X'.     "SAP Smart Forms: General Indicator
    ls_ctrl_form-preview = 'X'.       "Print preview
    ls_ctrl_form-getotf = 'X'.        "Return of OTF table. No printing, display, or faxing
    ls_ctrl_form-langu = 'EN'.        "Language key
    ls_ctrl_form-device = 'PRINTER'.  "Output device

    "Call Smart Form Function Module
    CALL FUNCTION lv_fname
      EXPORTING
        control_parameters = ls_ctrl_form
        output_options     = ls_output_opt
      IMPORTING
        job_output_info    = ls_job_output
      TABLES
        it_users1          = o_data_user->t_users1
        it_users2          = o_data_user->t_users2
        it_users3          = o_data_user->t_users3
        it_users4          = o_data_user->t_users4
        it_result_statuses = o_data_user->t_result_statuses
        it_result_errors   = o_data_user->t_result_errors

      EXCEPTIONS
        formatting_error   = 1
        internal_error     = 2
        send_error         = 3
        user_canceled      = 4
        OTHERS             = 5.
    IF ls_job_output-otfdata IS INITIAL.
      RAISE EXCEPTION TYPE lcx_msg_exception
        EXPORTING is_syst = sy.
    ENDIF.

    "Convert OTF to TLINE
    CALL FUNCTION 'CONVERT_OTF'
      EXPORTING
        format                = 'ASCII'
        max_linewidth         = 132
      TABLES
        otf                   = ls_job_output-otfdata
        lines                 = lt_lines
      EXCEPTIONS
        err_max_linewidth     = 1
        err_format            = 2
        err_conv_not_possible = 3
        err_bad_otf           = 4
        OTHERS                = 5.
    IF sy-subrc <> 0.
      RAISE EXCEPTION TYPE lcx_msg_exception
        EXPORTING is_syst = sy.
    ENDIF.

    "Remove empty lines
    DELETE lt_lines WHERE tdline EQ space.
    "Convert itab of HTML Email to itab of sending format in class CL_BCS
    LOOP AT lt_lines INTO ls_line.
      ls_soli = ls_line-tdline.
      APPEND ls_soli TO rt_soli.
      CLEAR ls_soli.
    ENDLOOP.

  ENDMETHOD.                    "get_mail_body

ENDCLASS.                    "lcl_manager_email IMPLEMENTATION



Smart form

By above class we have some prepared data/tables which should be placed into email. Please acknowledge the data types transferred into SmartForm must be data dictionary based. Here I used also some our custom types. 



Tables

I had a bit bad experience with SmartForm's TABLE elements. The text inside the SOLI table was truncated and useless for HTML content. So I decided to use simple LOOP instead of table. Inside the loop you can achieve the same functionality. In connection with IF conditions inside the loop it gives you quite powerful tool for email generation.



In text element you can place your HTML code with inside CSS style. Inside text element you may work normally with variables as usual e.g. &GS_RESULT_STATUS-STATUS_LOCKED&.




Together it produces following tables within email. Now email dynamically shows the result of the last taken action according to the conditions within table loops inside the SmartForm.



As you see, it's some mix up of SmartForm's elements and HTML/CSS styles inside texts elements and that's all. So now is your turn...









Thursday, April 24, 2014

SAP Smartforms + KYOCERA printer = DMC, QR codes work

Once I had to solve following task, print DMC square codes on Kyocera printers without any third party software. It is a reasonable step to replace all line bar codes with one square code containing all needed.

Because SAP does not support internally these codes, it is a bit challenge. The task did not allow usage of any software due to CPU time consumption during code rendering on server side.
Kyocera printers comes with interesting "option". You can print QR, DMC and really long list of various codes on their printers IF, If you buy small additional piece of hardware so called flash module. It allows you to trigger printer internal PCL commands producing bar codes as you wish. OK, it seems to be a solution. And you can suspect here, if there is some article concerning the topic, the way is not blind. Yes, it works! :)

So, what's needed?


At first we need plug a flash module into the printer. Kyocera produces various types of compact flash cards, types A, B, C... Here be careful, there is a list of supported cards for every printer. It means, you need to have proper card for your Kyocera printer. Note: flash card can be possibly flashed to upper version.

You need device driver supporting used printer language. You can choose standard PCL or Kyocera proprietary language called PRESCRIBE. This article is focused on usage of Prescribe.

In my case I used KYOAAA1C driver for my Kyocera FS-2020D.

List of suitable drivers:

  •       KYOAAA1C   KYO FS2000/3900/4000 PCL POSS
  •       KYOAAB1C   KYO FS95XX PCL POSS
  •       KYOAAC1C   KYO KMX050 PCL POSS
  •       KYOAAD1C   KYO FSC5400/FSC5300 PCL POSS
  •       KYOAAE1C   KYO FS1028/1128MFP PCL POSS
  •       KYOAAF1C   KYO TASKalfa XXXci PCL POSS  


For full list look at: http://www.stechno.net/sap-notes.html?view=sapnote&id=1135057#sthash.EMTwTPm8.dpuf

Now we can move on


Thing is not too complex. Some base explanation of DMC parameters is given just here. I recommend to download PDF from Kyocera website to understand usage of wanted code in depth. By the same way you can use QRs, DMCs and so on...

In general we need just some text element with proper font style. Style is very important, because SAP text element automatic line breaks destroy Prescribe command. So keep in mind you need to have:

  1. Window with enough space, usually simply MAIN window is a good option.
  2. Whole command must be in preview visible on ONE line. No breaks are possible. That's why we use for text element special very small font size as protection against automatic line breaks. 

Setup style


Style is setup in transaction Smartforms. Use font size 1 pt to save a space.


Setup global variables for DMC code


We can include whole DMC code string into one variable. But SAP limits length of text string used in SF up to 255 characters. That's why is better choice to separate prefix and suffix of the code to gain more space for the content itself.


Preparation of DMC content in initialization part


You can call some custom routines placed directly in SF to make a content of the code. Here we are preparing also Prescribe command itself, I mean prefix and suffix.



Whole code of init can looks like:


* DMC code properties (printed via Prescribe)
DATA: lv_code_type       TYPE string, " type of square code
      lv_dmc_symbol_from TYPE string,
      lv_dmc_symbol_to   TYPE string,
      lv_dmc_position_x  TYPE string,
      lv_dmc_position_y  TYPE string,
      lv_dmc_module_size TYPE string.

* DMC dimensions
lv_code_type        = '100'. " 100 means DMC
lv_dmc_module_size  = '13'.  " size of the small squares with dimension of 13 dots (pixels)
lv_dmc_symbol_from  = '11'.  " min. size
lv_dmc_symbol_to    = '19'.  " max size
lv_dmc_position_x   = '738'. " horizontal in px
lv_dmc_position_y   = '960'. " vertical in px

PERFORM get_dmccode_content
  USING    label_data2
  CHANGING gv_dmc_content.

" Prescribe DMC prefix + suffix definition
CONCATENATE '!R! UNIT D; MAP ' " Note: UNIT D = pixels, MAP = position
            lv_dmc_position_x ','
            lv_dmc_position_y
            '; BARC ' lv_code_type " BARC = print barcode
            ',' lv_dmc_module_size
            ',' lv_dmc_symbol_from
            ',' lv_dmc_symbol_to
            ',0,0,"'
INTO gv_dmc_prefix RESPECTING BLANKS.
gv_dmc_suffix   = '";EXIT;'.


DMC size on paper


The "module size" is the size of the small squares from which the bar code is built. If you use the command "UNIT D;" the unit is set to dots (pixels), e.g. the value 15 here means 52 x 52 rows. Final size of the DMC code depends on the length of content. If you set up min - max range for symbol attribute of DMC, system  tries to use the smallest possible one according to content length.

Display DMC code


Display gained global variables in text element via proper style. Prescribe command should be the very first thing sent to the printer, see hierarchy below.


Remember the used style above is too small to understand the idea. If I would enlarged version of picture above and view it by bigger font style, it would look something like below. In real we are inserting three different lines in order prefix, next row of content and finally suffix row.



How to overcome the limits


With system bar code (SE73) you can encode max. 255 characters in Smart Forms and max. 70 characters in SAPScript. With bar code formatted as text, the case of here described solution,  you can encode as much as you can place in one line. Maximum length of a field in Smart Forms is 255 characters.
Therefore you have to split the barcode data into several fields, if you want to encode more than 255 characters. 

Text element content

&DMC_PREFIX&
&DMC_DATA_FIELD_1&&DMC_DATA_FIELD_2&&DMC_DATA_FIELD_3&
&DMC_SUFFIX& 

Addition
See the SAP note Sap note 497380 - Maximum bar code length

Troubleshooting part 


You can test the setting of printer including the message  "codes not loaded" by following Prescribe command: "!R! CALL BSTP; EXIT;" Simply place the command into new text element and try to print out. By this command you would able to see any printer start up error. It would be nice to see if module is working properly.

The proper print driver could be tested by following commands. If print out would be successful, you know, driver works. But it is not telling you anything about bar code module yet.

Example 1

!R! UNIT C; MRP 3, 3;
SFNT "Univers-MdCd", 12;
MRP 3, 3;
CIR .35;

Example 2

!R! RES; PSRC 1;
SFNT "Helvetica", 10;
MZP 3, 3;
RTTX 15, " ----- Text1...";
RTTX 45, " ----- Text2...";
RTTX 75, " ----- Text3...";
PAGE; EXIT;

Finally many thanks to Mr. Norbert Volk-Klee for his precious Prescribe support.

Wish you happy printing cool codes!

Tuesday, April 1, 2014

SAP Smartforms - Error Message no. VN073

This is really short article describing how to find root cause of quite common error message VN073 occuring within Smart forms.

When you click to see the content of the error message in e.g. transaction VL74, there is nothing what can help you. So what to do? You just know, there is something wrong with the Smart form.



There is too many thing what can be wrong. And it is even bigger nightmare in case of really complex Smart forms. The worst thing is, the Smart form could be successfully compiled even if it contains errors!

The solution is to use just "Test" button inside the "Smarforms" transaction.



As you can see below, it gives you a clue where the error could be found. In this case some line of template has been deleted, but smart form contains reference to that line in text field. So this button is the salvation ;)


Tuesday, July 9, 2013

SAP Smartforms + Zebra printer = QR codes work

Personally I did some research for myself concerning possibilities to print QR codes within SAP Smartforms. The result was not so happy. There is no direct support from SAP for QRs in Smartforms these days, I mean year 2013.

Possible ways are as follows:

  • The solution from third parties 

  Zebra Designer – NiceLabel software
  http://www.nicelabel.com/products#designer

  • OR ??? ...read below...

QR code printing on Zebra printers

I did many various tests and spend enough time with Zebra support as well. My aim was to avoid any third party tools. Solution is finally no so difficult. The answer is Smartforms "Command node" and ZPL language of Zebra printers. 

Wee need following commands:

  • Position of QR on label
Any ZPL II command inserted into smart form via “command node” is not positioned in the end by smartform's window, but by another ZPL command FO e.g. ‘^FO100,100’.
  • Data - QR content
QR code data must be inserted as command node attribute just by one variable (here e.g. GV_QR_ZPL_CODE). I found this SAP info below and it started to work.
  • Avoid
Although many examples on internet uses starting and ending ZPL commands, but in smart forms you have to avoid of usage such a ZPL sequence ^XA… ^XZ, because it starts new label. It means, QR code is then going to be printed on separate label!


Now put everything together

1. Prepare data for QR in Smartform designer



2. Insert command node, that’s all

It could be placed under MAIN window. I used another window just for imagination of position within designer.




The only limitations is lengh for one Command node content. It is up to 200 characters including ZPL. But for many cases it is sufficient.