Build with BUILD (and Docker on Windows)

Some time ago a really nice open source and collaborative design tool was presented to the world of UI/UX designers: BUILD. It can be used for Web and Mobile Apps prototyping and User Research. It eases the collection of feedback from users or customers and jumpstarts the development. OK.. so far so good. This is something that you can check on the project web site.

If you check the GitHub repository you can find an explanation how you can install it on your own machine. It is quite simple really: just install Git, npm, nodejs and mongodb and after couple of command lines you are good to go!

Well.. why am I writing this post when I am sure you have already clicked on the first link, quickly installed everything and already have your first prototype up and running? I was curious about what Docker is and how it works so I decided to install Build with Docker on my Windows machine and it didn’t work that simple so I had to invest some time looking for a solution.

The steps in the README.md are the following:

1.Install Docker Engine – worked like charm if you just follow the link and install it.

2. Create file docker-compose.yml – weeeell this is where things got a bit complicated when I realized that I need to somehow install mongodb on Docker which is not described in the README file. So I spent some time trying to find a way how to install mongo (watch out it should be version 2.6.11). So how I did this?

2.1 First I created a folder (just to have it separated) docker-mongo

folder

2.2 Created the following Dockerfile there:

# Dockerizing MongoDB: Dockerfile for building MongoDB images
# Based on ubuntu:latest, installs MongoDB following the instructions from:
# http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/

FROM ubuntu:latest
MAINTAINER Docker

# Installation:
# Import MongoDB public GPG key AND create a MongoDB list file
RUN apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv 7F0CEB10
RUN echo ‘deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen’ | sudo tee /etc/apt/sources.list.d/mongodb.list

# Update apt-get sources AND install MongoDB
RUN apt-get update
RUN apt-get install -y mongodb-org=2.6.11 mongodb-org-server=2.6.11 mongodb-org-shell=2.6.11 mongodb-org-mongos=2.6.11 mongodb-org-tools=2.6.11

# Create the MongoDB data directory
RUN mkdir -p /data/db

# Expose port #27017 from the container to the host
EXPOSE 27017

# Set /usr/bin/mongod as the dockerized entry-point application
ENTRYPOINT [“/usr/bin/mongod”]

2.3 Ran the command docker build -t XXX/mongo (where XXX can be anything you like)

2.4 Then adjusted the docker-compose.yml file so that it uses the mongodb (again change XXX here)

web:
image: sapbuild/build:0.3.3
ports:
– “9000:9000”
links:
– mongo

mongo:
image: XXX/mongo

3. Pull and start containers here (same step as in the README.md) – just run docker-compose up wait a bit here it might take a while and when you see something like: server cluster started and then you might go to step 4

compose

4. Opened  192.168.99.100:9000 and voila

voila

proto

Maybe there is an easier way and maybe I have done something wrong, but as my first experience with Docker it seemed a bit weird and I was happy to see it running.. It seems to work now and I hope it will help someone who might have trouble setting everything up.

Since I am interested in how it jumstarts development and now have to find out how I can later import the projects in SAP Web IDE. But that is a next open issue that I have to solve…

Cheers and happy prototyping!

 

What does SAP have against gay marriage?

I noticed today that if one tries to add a marriage relationship between business partners with same sex in SAP a pop-up comes up informing the user that the partners have the same sex!

I am aware that this messages can be  deactivated, but leaving it activated by default means something.. or am I wrong? 🙂

Here as a proof:

Unbenannt

Something about Dynamic ABAP

It has been a while that I haven’t written anything new but it was due to making some ‘life-changing’ decisions recently and their impact on my ‘free-time’ activities.
First of all I decided to move to the lovely city of Dresden and start working in a company here, then I decided to get married and since my partner moved with me we had to find a new place to stay and equip it (it really takes some time to do that). OK, ok.. I admit I have been also searching for a wedding dress, invitation design, good wedding photographer and so it really takes some time.. 😉 I will now get to the point of the post in order not to annoy the male readers.
As the title says this time I will explain couple of concepts that are offered in ABAP that offer Real Time Type Services with a real-world problem.

Following is taken from help.sap.com:

The RTTS are implemented through a hierarchy of type classes that contain the methods for RTTC (Run Time Type Creation) and RTTI (Run Time Type Identification). With the help of these system classes it is possible to determine type information of existing instances and type names of the ABAP type system at runtime and to define new data types at runtime.
The properties of the types are represented by the attributes of type objects. For each type there is exactly one type object. The attributes of the type object contain information on the properties of the type. For each kind of type (elementary type, table, class, and so on), there is a type class with special attributes for special type properties. The class hierarchy of the type classes corresponds to the hierarchy of the type kinds in the ABAP type system.
In addition, type classes for complex types, references, classes, and interfaces have special methods for specifying references to partial types. With these methods, you can navigate to all partial types via a composite type.
Type objects can only be created through the methods of type classes. To get a reference to a type object of a type, you can use the static methods of the class CL_ABAP_TYPEDESCR or call methods of the special type classes.
Most important classes that every ABAPer has to know are:
CL_ABAP_TYPEDESCR
|
|–CL_ABAP_DATADESCR
|        |
|        |–CL_ABAP_ELEMDESCR
|        |–CL_ABAP_REFDESCR
|        |–CL_ABAP_COMPLEXDESCR
|          |
|          |–CL_ABAP_STRUCTDESCR
|          |–CL_ABAP_TABLEDESCR
|
|–CL_ABAP_OBJECTDESCR
|
|–CL_ABAP_CLASSDESCR
|–CL_ABAP_INTFDESCR

One can not understand the meaning of Dynamic programming without an example so let’s see one possible scenario.
Let’s suppose you need to upload some data in a table, but you have to make the code flexible and useful for uploading data in any table, not just a pre-defined one. Usually we create an internal table, use GUI_UPLOAD and we are done. But the bad thing about this approach is that sometimes we need to reuse the code for another table but before we have to change the type of the internal table, save, activate, test the code, transfer it to productive system and these all steps take a lot of time. When you don’t really have it, it is better to find some smart fast solution 🙂
So let’s explain the code step by step:

1. Creating the variables that we will need:


REPORT  zsax_upload_zmig_tables.

TYPE-POOLS: abap, sydes.

FIELD-SYMBOLS:  TYPE table.
FIELD-SYMBOLS: .
FIELD-SYMBOLS:  TYPE ANY.

DATA: lv_tab TYPE c VALUE cl_abap_char_utilities=>horizontal_tab.

DATA: lt_ftab TYPE lvc_t_fcat,
      wa_ftab TYPE LINE OF lvc_t_fcat,
      lt_ftab1 TYPE lvc_t_fcat WITH HEADER LINE,
      vals TYPE string,
      word TYPE string.

DATA: it_file TYPE REF TO data,
      is_file TYPE REF TO data,
      dref    TYPE REF TO data.

DATA: serv_dir TYPE string VALUE '/usr/sap/SAX/SYS/global',
      filepath TYPE authb-filename,
      data_tab TYPE TABLE OF string,
      wa_line TYPE string,
      wa_tab TYPE string,
      itab TYPE TABLE OF string,
      comp TYPE string.

DATA: gv_table_name   TYPE string,
      gr_type_desc    TYPE REF TO cl_abap_typedescr,
      gr_struct_desc  TYPE REF TO cl_abap_structdescr,
      gr_table_desc   TYPE REF TO cl_abap_tabledescr,
      gv_t            TYPE c,
      gv_comp         TYPE i,
      gr_table_ref    TYPE REF TO data,
      gr_struc_ref   TYPE REF TO data,
      descr_ref TYPE REF TO cl_abap_typedescr.

DATA: gt_itab   TYPE TABLE OF string,
      gt_split  TYPE TABLE OF string,
      gv_str    TYPE string,
      gv_stro    TYPE string.

DATA: td       TYPE sydes_desc.

FIELD-SYMBOLS: <table>    TYPE ANY TABLE,
               <struct>   TYPE ANY,
               <comp>     TYPE ANY.

PARAMETERS: l_file TYPE string DEFAULT 'D:\Zentraltabelle.txt'.
PARAMETERS: table LIKE dd02l-tabname DEFAULT 'ZENTRAL'.

2. Upload data in a text table


CALL FUNCTION 'C13Z_UPLOAD'
 EXPORTING
   codepage                      = '1100'
   filename                      = l_file
  TABLES
    data_tab                      = data_tab
          .

IF sy-subrc  0.
write: 'Error!'.
ENDIF.

3. Call to dynamically create the table


CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
  EXPORTING
    i_structure_name = table
  CHANGING
    ct_fieldcat      = lt_ftab
  EXCEPTIONS
    OTHERS           = 1.

IF sy-subrc NE 0.
  WRITE: / 'Fehler bei Field catalog '.
  STOP.
ENDIF.

CALL METHOD cl_alv_table_create=&gt;create_dynamic_table
  EXPORTING
    it_fieldcatalog = lt_ftab
  IMPORTING
    ep_table        = it_file.

CREATE DATA dref TYPE (table).
ASSIGN dref-&gt;* TO .

ASSIGN it_file-&gt;* TO .

cl_abap_tabledescr=&gt;describe_by_name(
      EXPORTING p_name = table
      RECEIVING p_descr_ref = gr_type_desc
      EXCEPTIONS type_not_found = 4 ).

gr_struct_desc ?= gr_type_desc.
gr_table_desc = cl_abap_tabledescr=&gt;create( gr_struct_desc ).
CREATE DATA gr_table_ref TYPE HANDLE gr_table_desc.
CREATE DATA gr_struc_ref TYPE HANDLE gr_struct_desc.
ASSIGN gr_table_ref-&gt;* TO <table>.
ASSIGN gr_struc_ref-&gt;* TO .
DESCRIBE FIELD  TYPE gv_t COMPONENTS gv_comp.

3. Perform some parameter checks (if you happen to be dealing with Dates and crazy decimals)


LOOP AT data_tab INTO gv_str.
  CLEAR: gt_split.

  SPLIT gv_str AT lv_tab INTO TABLE gt_split.

  DO gv_comp TIMES.
    READ TABLE gt_split INTO gv_str INDEX sy-index.
    ASSIGN COMPONENT sy-index OF STRUCTURE  TO .

    DESCRIBE FIELD   INTO  td.
    descr_ref = cl_abap_typedescr=&gt;describe_by_data(  ).

    CASE descr_ref-&gt;type_kind.
        " DATUM TYPE
      WHEN 'D'.

        CALL FUNCTION 'CONVERSION_EXIT_DATEX_INPUT'
          EXPORTING
            input  = gv_str
          IMPORTING
            output = gv_stro.
         = gv_stro.

      WHEN 'P'.
        " DECIMAL TYPE
        CALL FUNCTION 'HRCM_STRING_TO_AMOUNT_CONVERT'
              EXPORTING
                string                    = gv_str
               decimal_separator         = ','
               thousands_separator       = '.'
*       WAERS                     = ' '
             IMPORTING
               betrg                     =
*     EXCEPTIONS
*       CONVERT_ERROR             = 1
*       OTHERS                    = 2
                      .

      WHEN 'F'.
        " DECIMAL TYPE
        CALL FUNCTION 'HRCM_STRING_TO_AMOUNT_CONVERT'
              EXPORTING
                string                    = gv_str
               decimal_separator         = ','
               thousands_separator       = '.'
*       WAERS                     = ' '
             IMPORTING
               betrg                     =
*     EXCEPTIONS
*       CONVERT_ERROR             = 1
*       OTHERS                    = 2
                      .

      WHEN 'T'.
        " TIME TYPE
        CALL FUNCTION 'CONVERSION_EXIT_TIMLO_INPUT'
          EXPORTING
            input  = gv_str
          IMPORTING
            output = gv_stro.
         = gv_stro.

      WHEN OTHERS.
        " CHAR, NUMC... TYPE
         = gv_str.
    ENDCASE.

    CLEAR gv_str.
  ENDDO.

  INSERT INTO (table) VALUES .
ENDLOOP.

4. Keep on ABAPing… 🙂
Next time I will write about dynamic creation of objects and dynamic calls of methods from objects.

Outlook messages from SAP system

This is a sample code that can be used to create draft messages in your Outlook through SAP. Of course it is important to understand what it does so I tried to comment as much I can.

The VB code that can be used to create draft message is given here:

Sub create_draftmsg()
  Dim oApp As Outlook.Application
    Dim oEmail As Outlook.MailItem
    Set oApp = New Outlook.Application
    Set oEmail = oApp.CreateItem(olMailItem)
With oEmail
        .To = "to@mail.com"
        .CC = ""
        .Subject = "SUBJECT"
        .Body = "BODY TEXT"
        .Attachments.Add "C:\Cat.bmp", olByValue
        .Save
    End With
    Set oEmail = Nothing
End Sub

The ABAP code is given below.

INCLUDE OLE2INCL.
* they are all OLE2_OBJECTS so it is important to know the real classes
DATA: OUTLOOK TYPE OLE2_OBJECT,
MAILITEM TYPE OLE2_OBJECT,
ATTACHMENTS TYPE OLE2_OBJECT,
APPT TYPE OLE2_OBJECT,
DESTI TYPE OLE2_OBJECT,
BODYMAIL(600) TYPE C.
CREATE OBJECT OUTLOOK 'OUTLOOK.APPLICATION'.
* Get the outlook namespace
CALL METHOD OF OUTLOOK 'GetNamespace' = NAMESPACE
EXPORTING
#1 = 'MAPI'.
* Get outlook folders and create a reference to sent mail folder
* (myfolder)
* If this is not used than a draft message is not created when Outlook is not running
CALL METHOD OF NAMESPACE 'GetDefaultFolder' = MYFOLDER  EXPORTING     #1 = 16.    "olFolderDraftMail (value from a short debugging in VB)
CALL METHOD OF OUTLOOK 'CreateItem' = OUTMAIL EXPORTING #1 = 0. " 0 - MailItem
SET PROPERTY OF OUTMAIL 'SUBJECT' = 'SUBJECT'.
SET PROPERTY OF OUTMAIL 'BODY' = BODYMAIL.
CALL METHOD OF OUTMAIL 'RECIPIENTS' = DESTI.
CALL METHOD OF DESTI 'ADD' EXPORTING #1 = 'recipient@mail.com'.
CALL METHOD OF OUTMAIL 'ATTACHMENTS' = ATTS.
CALL METHOD OF ATTS 'ADD' EXPORTING #1 = 'filepath:\file.type'.
CALL METHOD OF OUTMAIL 'SAVE'.
FREE OBJECT DESTI.
FREE OBJECT ATTS.
FREE OBJECT OUTMAIL.
FREE OBJECT OUTLOOK.

Today’s wisdom: Use Macro recorder to discover the classes needed in order to use Microsoft goodies in ABAP! 🙂

Testing my thesis apps in a local primary school

After the first version of the apps is done it was time to test them with kids and see if they like them. I visited a primary school here in Skopje and had a chance to test them in 3 different classes. Total 75 kids tested the apps. The interesting fact was that 34 out of 75 kids (or their parents) had smartphones but only 7 of them had game consoles at home.

It is obvious that the second application is not motivating too much physical activity but this was due to the limited space we had in the classroom since now they have PC for every child in primary schools and tables couldn’t be moved around. But we were invited by the gym teacher to join them on a gym lesson next time.

SAP Technical sites/blogs I often consult…

The best technical  ones

http://www.saptechnical.com

http://abap4.tripod.com

http://abaplovers.blogspot.com

http://sap.ittoolbox.com

http://www.erpdb.info

http://www.freesaptutorial.com/

http://www.erpgenie.com

I’ll update this list every time I find a site/blog that will help me.

More info…

coming soon…